// returns two int indices packed into one long. left index is for the real file array half, right // is for the adopted children name array private static long findIndexInBoth( @NotNull VirtualFileSystemEntry[] array, @NotNull String name, @NotNull Comparator comparator) { int high = array.length - 1; if (high == -1) { return pack(-1, -1); } int low = 0; boolean startInAdopted = isAdoptedChild(array[low]); boolean endInAdopted = isAdoptedChild(array[high]); if (startInAdopted == endInAdopted) { int index = findIndexInOneHalf(array, low, high + 1, startInAdopted, name, comparator); int otherIndex = startInAdopted ? -1 : -array.length - 1; return startInAdopted ? pack(otherIndex, index) : pack(index, otherIndex); } boolean adopted = false; int cmp = -1; int mid = -1; int foundIndex = -1; while (low <= high) { mid = low + high >>> 1; VirtualFileSystemEntry file = array[mid]; cmp = comparator.compareFileNameTo(name, file); adopted = isAdoptedChild(file); if (cmp == 0) { foundIndex = mid; break; } if ((adopted || cmp <= 0) && (!adopted || cmp >= 0)) { int indexInAdopted = findIndexInOneHalf(array, mid + 1, high + 1, true, name, comparator); int indexInReal = findIndexInOneHalf(array, low, mid, false, name, comparator); return pack(indexInReal, indexInAdopted); } if (cmp > 0) { low = mid + 1; } else { high = mid - 1; } } // key not found. if (cmp != 0) foundIndex = -low - 1; int newStart = adopted ? low : mid + 1; int newEnd = adopted ? mid + 1 : high + 1; int theOtherHalfIndex = newStart < newEnd ? findIndexInOneHalf(array, newStart, newEnd, !adopted, name, comparator) : -newStart - 1; return adopted ? pack(theOtherHalfIndex, foundIndex) : pack(foundIndex, theOtherHalfIndex); }
private static int binSearch( @NotNull VirtualFileSystemEntry[] array, int start, int end, @NotNull String name, @NotNull Comparator comparator) { int low = start; int high = end - 1; assert low >= 0 && low <= array.length; while (low <= high) { int mid = low + high >>> 1; int cmp = comparator.compareFileNameTo(name, array[mid]); if (cmp > 0) { low = mid + 1; } else if (cmp < 0) { high = mid - 1; } else { return mid; // key found } } return -(low + 1); // key not found. }