private static <T> int stolenBinarySearch(ReadonlyList<? extends T> l, T key, Comparator<? super T> c, final int from) { int low = from; int high = (l.getSize() - from) -1; while (low <= high) { int mid = (low + high) >>> 1; T midVal = l.get(mid); int cmp = c.compare(midVal, key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found }
public void execute() { final int[] idxs = new int[myLists.size()]; for (int i = 0; i < myLists.size(); i++) { final ReadonlyList<T> member = myLists.get(i); idxs[i] = member.getSize() == 0 ? -1 : 0; } while (true) { CompoundNumber minIdxs = null; for (int i = 0; i < idxs.length; i++) { if (idxs[i] == -1) continue; // at end final ReadonlyList<T> list = myLists.get(i); if ((minIdxs == null) || (myComparator.compare(Pair.create(new CompoundNumber(i, idxs[i]), list.get(idxs[i])), Pair.create(minIdxs, myLists.get(minIdxs.getMemberNumber()).get(minIdxs.getIdx()))) <= 0)) { minIdxs = new CompoundNumber(i, idxs[i]); } } if (minIdxs == null) return; myConsumer.consume(minIdxs); final int memberIdx = minIdxs.getMemberNumber(); idxs[memberIdx] = (myLists.get(memberIdx).getSize() == (idxs[memberIdx] + 1) ? -1 : idxs[memberIdx] + 1); } }
public static<T> void firstPlusSecond(final StepList<T> first, final ReadonlyList<T> second, final Comparator<T> comparator, @Nullable final Consumer<T> beforeAddListener, final Processor<T> filter) { if (second.getSize() == 0) return; int idx = stolenBinarySearch(first, second.get(0), comparator, 0); if (idx < 0) { idx = - (idx + 1); } // for group headers to not be left alone without its group if (idx > 0 && (! filter.process(first.get(idx - 1)))) { -- idx; if (idx > 0) --idx; } final ReadonlyList<T> remergePart = first.cut(idx); merge(remergePart, second, comparator, new Consumer<T>() { @Override public void consume(T t) { if (beforeAddListener != null) { beforeAddListener.consume(t); } first.add(t); } }, filter); }
@Override public ReadonlyList<T> cut(int idxFromIncluded) { if (idxFromIncluded >= getSize()) return ReadonlyList.EMPTY; final int itemNumber = idxFromIncluded >> mySize2Power; final int insideIdx = idxFromIncluded ^ (itemNumber << mySize2Power); final ArrayList<T> start = myList.get(itemNumber); final NotRegularReadonlyList<T> result = new NotRegularReadonlyList<T>(new ArrayList<ArrayList<T>>(myList.subList(itemNumber + 1, myList.size())), mySize2Power, start.subList(insideIdx, start.size())); myList.set(itemNumber, new ArrayList<T>(start.subList(0, insideIdx))); for (int i = myList.size() - 1; i > itemNumber; -- i) { myList.remove(i); } mySize = myList.isEmpty() ? 0 : (((myList.size() - 1) * myPack + myList.get(myList.size() - 1).size())); return result; }
public void execute() { final int[] idxs = new int[myLists.size()]; for (int i = 0; i < myLists.size(); i++) { final ReadonlyList<T> member = myLists.get(i); idxs[i] = member.getSize() == 0 ? -1 : 0; } while (true) { CompoundNumber minIdxs = null; for (int i = 0; i < idxs.length; i++) { if (idxs[i] == -1) continue; // at end final ReadonlyList<T> list = myLists.get(i); if ((minIdxs == null) || (myComparator.compare(new Pair<CompoundNumber,T>(new CompoundNumber(i, idxs[i]), list.get(idxs[i])), new Pair<CompoundNumber,T>(minIdxs, myLists.get(minIdxs.getMemberNumber()).get(minIdxs.getIdx()))) <= 0)) { minIdxs = new CompoundNumber(i, idxs[i]); } } if (minIdxs == null) return; myConsumer.consume(minIdxs); final int memberIdx = minIdxs.getMemberNumber(); idxs[memberIdx] = (myLists.get(memberIdx).getSize() == (idxs[memberIdx] + 1) ? -1 : idxs[memberIdx] + 1); } }
@Override public Ring<Integer> getUsedWires(int row, ReadonlyList<CommitI> commits, final Convertor<Integer, List<Integer>> future) { final Map.Entry<Integer, RingIndex> entry = myRingIndex.floorEntry(row); if (entry == null) return new Ring.IntegerRing(); final Ring<Integer> ring = entry.getValue().getUsedInRing(); if (entry.getKey() == row) { return ring; } //System.out.println("-----------------> row = " + row); final Iterator<WireEvent> iterator = createWireEventsIterator(entry.getKey()); while (iterator.hasNext()) { final WireEventI event = iterator.next(); if (event.getCommitIdx() >= row) { return ring; } // System.out.println("event: " + event.toString()); // System.out.println("ring before: " + ring.toString()); //if (event.getCommitIdx() == entry.getKey()) continue; performOnRing(ring, event, commits, future.convert(event.getCommitIdx())); } return ring; }
private void testRealResults(TreeNavigationImpl navigation, ReadonlyList.ArrayListWrapper<CommitI> commits) { final int[] expectedWireNumbers = {0,0,1,1,1, 1,3,3,2,0, 0,1,1,1,2, 2,0,0}; for (int i = 0; i < 5; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); Assert.assertEquals(expectedWireNumbers[i], commitI.getWireNumber()); } Ring<Integer> usedWires = navigation.getUsedWires(17, commits, new Convertor<Integer, List<Integer>>() { @Override public List<Integer> convert(Integer o) { return Collections.emptyList(); } }); System.out.println("*"); }
private void recountFragmentZwichem(ReadonlyList<CommitI> commits, Map<Integer, Integer> recalculateMap, int runningCommitNumber, int inclusive) { if (! recalculateMap.isEmpty()) { for (int i = runningCommitNumber; i <= inclusive; i++) { final CommitI commit = commits.get(i); final Integer newWire = recalculateMap.get(commit.getWireNumber()); if (newWire != null) { commit.setWireNumber(newWire); } } } }
private void fillData(List<CommitHashPlusParents> list, TreeNavigationImpl navigation, SkeletonBuilder builder, ReadonlyList.ArrayListWrapper<CommitI> commits) { int wasSize = commits.getSize(); for (CommitHashPlusParents commitHashPlusParents : list) { final WireNumberCommitDecoration commitI = createCommit(commitHashPlusParents); commits.getDelegate().add(commitI); builder.consume(commitI, getParents(commitHashPlusParents), commits, commits.getSize() - 1); } //navigation.recountWires(wasSize == 0 ? 0 : (wasSize - 1), commits); navigation.recalcIndex(commits, builder.getFutureConvertor()); }
public void testOneLine() throws Exception { final List<CommitHashPlusParents> list = read("1 2\n2 3\n3 4\n4 5\n5"); // 4, 4 final TreeNavigationImpl navigation = new TreeNavigationImpl(2, 2); final SkeletonBuilder builder = new SkeletonBuilder(navigation); final ReadonlyList.ArrayListWrapper<CommitI> commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list, navigation, builder, commits); for (int i = 0; i < 5; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); Assert.assertEquals(0, commitI.getWireNumber()); } final Iterator<WireEvent> iterator = navigation.createWireEventsIterator(0); WireEventI we = iterator.next(); Assert.assertEquals(true, we.isStart()); Assert.assertEquals(0, we.getCommitIdx()); we = iterator.next(); Assert.assertEquals(true, we.isEnd()); Assert.assertEquals(4, we.getCommitIdx()); assertWires(navigation.getUsedWires(0, commits, builder.getFutureConvertor()).getUsed()); assertWires(navigation.getUsedWires(1, commits, builder.getFutureConvertor()).getUsed(), 0); assertWires(navigation.getUsedWires(2, commits, builder.getFutureConvertor()).getUsed(), 0); assertWires(navigation.getUsedWires(3, commits, builder.getFutureConvertor()).getUsed(), 0); assertWires(navigation.getUsedWires(4, commits, builder.getFutureConvertor()).getUsed(), 0); final Iterator<WireEvent> iterator1 = navigation.createWireEventsIterator(4); WireEventI we1 = iterator1.next(); Assert.assertEquals(true, we1.isEnd()); Assert.assertEquals(4, we1.getCommitIdx()); }
private void testFirstStepResults(TreeNavigationImpl navigation, ReadonlyList.ArrayListWrapper<CommitI> commits, final SkeletonBuilder builder) { for (int i = 0; i < 7; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); } Assert.assertEquals(0, commits.get(0).getWireNumber()); Assert.assertEquals(0, commits.get(1).getWireNumber()); Assert.assertEquals(1, commits.get(2).getWireNumber()); Assert.assertEquals(0, commits.get(3).getWireNumber()); Assert.assertEquals(1, commits.get(4).getWireNumber()); Assert.assertEquals(0, commits.get(5).getWireNumber()); Assert.assertEquals(0, commits.get(6).getWireNumber()); final Iterator<WireEvent> iterator = navigation.createWireEventsIterator(0); testFirstIteratorPart(iterator); WireEventI we; assertWires(navigation.getUsedWires(0, commits, builder.getFutureConvertor()).getUsed()); assertWires(navigation.getUsedWires(1, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(2, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(3, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(4, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(5, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(6, commits, builder.getFutureConvertor()).getUsed(), 0); final Iterator<WireEvent> iterator1 = navigation.createWireEventsIterator(4); we = iterator1.next(); Assert.assertEquals(4, we.getWireEnds()[0]); Assert.assertEquals(5, we.getCommitIdx()); final int[] commitsEnds1 = we.getCommitsEnds(); Assert.assertEquals(2, commitsEnds1.length); Assert.assertEquals(3, commitsEnds1[0]); Assert.assertEquals(4, commitsEnds1[1]); }
public void testRealMergesAndBranches() throws Exception { List<CommitHashPlusParents> list = read("1 2 3\n2 10\n3 4\n4 5 9\n5 6 7\n6 10\n7 8\n8 10\n9 10\n10 11 12\n11 17\n12 13 15\n" + "13 14\n14 17\n15 16 17\n16 18\n17 18"); TreeNavigationImpl navigation = new TreeNavigationImpl(20, 20); SkeletonBuilder builder = new SkeletonBuilder(navigation); ReadonlyList.ArrayListWrapper<CommitI> commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list, navigation, builder, commits); testRealResults(navigation, commits); List<CommitHashPlusParents> list1 = read("1 2 3\n2 10\n3 4\n4 5 9\n5 6 7\n6 10\n7 8\n8 10\n9 10\n10 11 12\n11 17\n12 13 15\n"); List<CommitHashPlusParents> list2 = read("13 14\n14 17\n15 16 17\n16 18\n17 18"); navigation = new TreeNavigationImpl(20, 20); builder = new SkeletonBuilder(navigation); commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list1, navigation, builder, commits); fillData(list2, navigation, builder, commits); testRealResults(navigation, commits); list1 = read("1 2 3\n2 10\n3 4\n4 5 9\n5 6 7\n6 10\n7 8\n8 10\n9 10\n10 11 12\n11 17\n12 13 15\n13 14\n14 17\n"); list2 = read("15 16 17\n16 18\n17 18"); navigation = new TreeNavigationImpl(20, 20); builder = new SkeletonBuilder(navigation); commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list1, navigation, builder, commits); fillData(list2, navigation, builder, commits); testRealResults(navigation, commits); list1 = read("1 2 3\n2 10\n3 4\n4 5 9\n5 6 7\n6 10\n7 8\n8 10\n9 10\n10 11 12\n11 17\n12 13 15\n13 14\n14 17\n15 16 17\n"); list2 = read("16 18\n17 18"); navigation = new TreeNavigationImpl(20, 20); builder = new SkeletonBuilder(navigation); commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list1, navigation, builder, commits); fillData(list2, navigation, builder, commits); testRealResults(navigation, commits); }
private ReadonlyListsMerger(final List<ReadonlyList<T>> lists, final Consumer<CompoundNumber> consumer, final Comparator<Pair<CompoundNumber, T>> comparator) { myLists = lists; myConsumer = consumer; myComparator = comparator; }
public static<T extends Comparable<T>> void merge(final List<ReadonlyList<T>> lists, final Consumer<CompoundNumber> consumer) { new ReadonlyListsMerger<T>(lists, consumer, new MyComparator<T>()).execute(); }
public static<T> void merge(final List<ReadonlyList<T>> lists, final Consumer<CompoundNumber> consumer, final Comparator<Pair<CompoundNumber, T>> comparator) { new ReadonlyListsMerger<T>(lists, consumer, comparator).execute(); }
public void testTwoSteps() throws Exception { final List<CommitHashPlusParents> list = read("1 2 3\n2 4\n3 5\n4 6\n5 6\n6 7\n7 8 9"); final List<CommitHashPlusParents> step2 = read("8 10\n9 11\n10 12\n11 13\n12 14\n13 14\n14 15"); // 4, 4 final TreeNavigationImpl navigation = new TreeNavigationImpl(2, 2); final SkeletonBuilder builder = new SkeletonBuilder(navigation); final ReadonlyList.ArrayListWrapper<CommitI> commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list, navigation, builder, commits); testFirstStepResults(navigation, commits, builder); // end of first step fillData(step2, navigation, builder, commits); testFirstStepResults(navigation, commits, builder); for (int i = 7; i < 14; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); } Assert.assertEquals(0, commits.get(7).getWireNumber()); Assert.assertEquals(1, commits.get(8).getWireNumber()); Assert.assertEquals(0, commits.get(9).getWireNumber()); Assert.assertEquals(1, commits.get(10).getWireNumber()); Assert.assertEquals(0, commits.get(11).getWireNumber()); Assert.assertEquals(1, commits.get(12).getWireNumber()); Assert.assertEquals(0, commits.get(13).getWireNumber()); final Iterator<WireEvent> iterator = navigation.createWireEventsIterator(0); testFirstIteratorPart(iterator); WireEventI we = iterator.next(); Assert.assertEquals(6, we.getCommitIdx()); final int[] commitsStarts = we.getCommitsStarts(); Assert.assertEquals(2, commitsStarts.length); Assert.assertEquals(7, commitsStarts[0]); Assert.assertEquals(8, commitsStarts[1]); Assert.assertNull(we.getWireEnds()); we = iterator.next(); Assert.assertEquals(12, we.getWireEnds()[0]); Assert.assertEquals(13, we.getCommitIdx()); final int[] commitsEnds = we.getCommitsEnds(); Assert.assertEquals(2, commitsEnds.length); Assert.assertEquals(11, commitsEnds[0]); Assert.assertEquals(12, commitsEnds[1]); assertWires(navigation.getUsedWires(7, commits, builder.getFutureConvertor()).getUsed(),0,1); assertWires(navigation.getUsedWires(8, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(9, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(10, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(11, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(12, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(13, commits, builder.getFutureConvertor()).getUsed(), 0,1); }
public void testTwoStepsMinusLastElement() throws Exception { final List<CommitHashPlusParents> list = read("1 2 3\n2 4\n3 5\n4 6\n5 6\n6 7\n7 8 9"); final List<CommitHashPlusParents> step2 = read("8 10\n9 11\n10 12\n11 13\n12 14\n13 14"); // 4, 4 final TreeNavigationImpl navigation = new TreeNavigationImpl(2, 2); final SkeletonBuilder builder = new SkeletonBuilder(navigation); final ReadonlyList.ArrayListWrapper<CommitI> commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list, navigation, builder, commits); testFirstStepResults(navigation, commits, builder); // end of first step fillData(step2, navigation, builder, commits); testFirstStepResults(navigation, commits, builder); for (int i = 7; i < 13; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); } Assert.assertEquals(0, commits.get(7).getWireNumber()); Assert.assertEquals(1, commits.get(8).getWireNumber()); Assert.assertEquals(0, commits.get(9).getWireNumber()); Assert.assertEquals(1, commits.get(10).getWireNumber()); Assert.assertEquals(0, commits.get(11).getWireNumber()); Assert.assertEquals(1, commits.get(12).getWireNumber()); final Iterator<WireEvent> iterator = navigation.createWireEventsIterator(0); testFirstIteratorPart(iterator); WireEventI we = iterator.next(); Assert.assertEquals(6, we.getCommitIdx()); final int[] commitsStarts = we.getCommitsStarts(); Assert.assertEquals(2, commitsStarts.length); Assert.assertEquals(7, commitsStarts[0]); Assert.assertEquals(8, commitsStarts[1]); Assert.assertNull(we.getWireEnds()); assertWires(navigation.getUsedWires(7, commits, builder.getFutureConvertor()).getUsed(),0,1); assertWires(navigation.getUsedWires(8, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(9, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(10, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(11, commits, builder.getFutureConvertor()).getUsed(), 0,1); assertWires(navigation.getUsedWires(12, commits, builder.getFutureConvertor()).getUsed(), 0,1); }
public void testBranchAndMerge() throws Exception { final List<CommitHashPlusParents> list = read("1 2\n2 3 4\n3 5\n4 6\n5 7\n6 8\n7 8\n8 9\n9"); // 4, 4 final TreeNavigationImpl navigation = new TreeNavigationImpl(2, 2); final SkeletonBuilder builder = new SkeletonBuilder(navigation); final ReadonlyList.ArrayListWrapper<CommitI> commits = new ReadonlyList.ArrayListWrapper<CommitI>(); fillData(list, navigation, builder, commits); final int[] expectedWireNumbers = {0, 0, 0, 1, 0, 1, 0, 1, 1}; for (int i = 0; i < 5; i++) { final CommitI commitI = (CommitI)commits.get(i); // just because of the test data order Assert.assertEquals("" + (i + 1), commitI.getHash().getString()); Assert.assertEquals(expectedWireNumbers[i], commitI.getWireNumber()); } final Iterator<WireEvent> iterator = navigation.createWireEventsIterator(0); WireEventI we = iterator.next(); Assert.assertEquals(true, we.isStart()); Assert.assertEquals(0, we.getCommitIdx()); we = iterator.next(); final int[] commitsStarts = we.getCommitsStarts(); Assert.assertEquals(2, commitsStarts.length); Assert.assertEquals(2, commitsStarts[0]); Assert.assertEquals(3, commitsStarts[1]); Assert.assertNull(we.getWireEnds()); Assert.assertEquals(1, we.getCommitIdx()); we = iterator.next(); Assert.assertEquals(6, we.getWireEnds()[0]); Assert.assertEquals(7, we.getCommitIdx()); final int[] commitsEnds = we.getCommitsEnds(); Assert.assertEquals(2, commitsEnds.length); Arrays.sort(commitsEnds); Assert.assertEquals(5, commitsEnds[0]); Assert.assertEquals(6, commitsEnds[1]); we = iterator.next(); Assert.assertEquals(true, we.isEnd()); Assert.assertEquals(8, we.getCommitIdx()); assertWires(navigation.getUsedWires(0, commits, builder.getFutureConvertor()).getUsed()); assertWires(navigation.getUsedWires(1, commits, builder.getFutureConvertor()).getUsed(), 0); assertWires(navigation.getUsedWires(2, commits, builder.getFutureConvertor()).getUsed(), 0, 1); assertWires(navigation.getUsedWires(3, commits, builder.getFutureConvertor()).getUsed(), 0, 1); assertWires(navigation.getUsedWires(4, commits, builder.getFutureConvertor()).getUsed(), 0, 1); assertWires(navigation.getUsedWires(5, commits, builder.getFutureConvertor()).getUsed(), 0, 1); assertWires(navigation.getUsedWires(6, commits, builder.getFutureConvertor()).getUsed(), 0, 1); assertWires(navigation.getUsedWires(7, commits, builder.getFutureConvertor()).getUsed(), 0, 1); // before wires! assertWires(navigation.getUsedWires(8, commits, builder.getFutureConvertor()).getUsed(), 1); final Iterator<WireEvent> iterator1 = navigation.createWireEventsIterator(5); WireEventI we1 = iterator1.next(); Assert.assertEquals(6, we1.getWireEnds()[0]); Assert.assertEquals(7, we1.getCommitIdx()); final int[] commitsEnds1 = we1.getCommitsEnds(); Assert.assertEquals(2, commitsEnds1.length); Arrays.sort(commitsEnds); Assert.assertEquals(5, commitsEnds1[0]); Assert.assertEquals(6, commitsEnds1[1]); we1 = iterator1.next(); Assert.assertEquals(true, we1.isEnd()); Assert.assertEquals(8, we1.getCommitIdx()); }
/** * * * @param row - commit idx * @param commits * @return pair: idx of closest commit with ring recorded; ring - ring for that commit */ @Nullable Ring<Integer> getUsedWires(int row, ReadonlyList<CommitI> commits, final Convertor<Integer, List<Integer>> future);