private static void sort(final BytesRefBuilder scratch, final BytesRefBuilder scratch1, final BytesRefArray bytes, final int[] indices) { final int numValues = bytes.size(); assert indices.length >= numValues; if (numValues > 1) { new InPlaceMergeSorter() { final Comparator<BytesRef> comparator = Comparator.naturalOrder(); @Override protected int compare(int i, int j) { return comparator.compare(bytes.get(scratch, indices[i]), bytes.get(scratch1, indices[j])); } @Override protected void swap(int i, int j) { int value_i = indices[i]; indices[i] = indices[j]; indices[j] = value_i; } }.sort(0, numValues); } }
public static int sortAndDedup(final BytesRefArray bytes, final int[] indices) { final BytesRefBuilder scratch = new BytesRefBuilder(); final BytesRefBuilder scratch1 = new BytesRefBuilder(); final int numValues = bytes.size(); assert indices.length >= numValues; if (numValues <= 1) { return numValues; } sort(scratch, scratch1, bytes, indices); int uniqueCount = 1; BytesRefBuilder previous = scratch; BytesRefBuilder current = scratch1; bytes.get(previous, indices[0]); for (int i = 1; i < numValues; ++i) { bytes.get(current, indices[i]); if (!previous.get().equals(current.get())) { indices[uniqueCount++] = indices[i]; } BytesRefBuilder tmp = previous; previous = current; current = tmp; } return uniqueCount; }
public void testSortAndDedupByteRefArray() { SortedSet<BytesRef> set = new TreeSet<>(); final int numValues = scaledRandomIntBetween(0, 10000); List<BytesRef> tmpList = new ArrayList<>(); BytesRefArray array = new BytesRefArray(Counter.newCounter()); for (int i = 0; i < numValues; i++) { String s = randomRealisticUnicodeOfCodepointLengthBetween(1, 100); set.add(new BytesRef(s)); tmpList.add(new BytesRef(s)); array.append(new BytesRef(s)); } if (randomBoolean()) { Collections.shuffle(tmpList, random()); for (BytesRef ref : tmpList) { array.append(ref); } } int[] indices = new int[array.size()]; for (int i = 0; i < indices.length; i++) { indices[i] = i; } int numUnique = CollectionUtils.sortAndDedup(array, indices); assertThat(numUnique, equalTo(set.size())); Iterator<BytesRef> iterator = set.iterator(); BytesRefBuilder spare = new BytesRefBuilder(); for (int i = 0; i < numUnique; i++) { assertThat(iterator.hasNext(), is(true)); assertThat(array.get(spare, indices[i]), equalTo(iterator.next())); } }
public void testSortByteRefArray() { List<BytesRef> values = new ArrayList<>(); final int numValues = scaledRandomIntBetween(0, 10000); BytesRefArray array = new BytesRefArray(Counter.newCounter()); for (int i = 0; i < numValues; i++) { String s = randomRealisticUnicodeOfCodepointLengthBetween(1, 100); values.add(new BytesRef(s)); array.append(new BytesRef(s)); } if (randomBoolean()) { Collections.shuffle(values, random()); } int[] indices = new int[array.size()]; for (int i = 0; i < indices.length; i++) { indices[i] = i; } CollectionUtils.sort(array, indices); Collections.sort(values); Iterator<BytesRef> iterator = values.iterator(); BytesRefBuilder spare = new BytesRefBuilder(); for (int i = 0; i < values.size(); i++) { assertThat(iterator.hasNext(), is(true)); assertThat(array.get(spare, indices[i]), equalTo(iterator.next())); } }
public static void sort(final BytesRefArray bytes, final int[] indices) { sort(new BytesRefBuilder(), new BytesRefBuilder(), bytes, indices); }