Skip to content

Commit

Permalink
Fix a bug in MemoizationList.
Browse files Browse the repository at this point in the history
Properly handle the case when source.get() in force() causes forget().
  • Loading branch information
TomasMikula committed Feb 23, 2015
1 parent 1f0d7a9 commit f5d6fb5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ private void prepareNotifications(QuasiListChange<? extends E> change) {
enqueueNotifications(change);
}

private void prepareNotifications(QuasiListModification<? extends E> mod) {
enqueueNotifications(mod.asListChange());
}

private void publishNotifications() {
notifyObservers();
}
Expand Down Expand Up @@ -112,19 +116,16 @@ public void force(int from, int to) {
}

Lists.checkRange(from, to, size());
int presentBefore = sparseList.getPresentCountBefore(from);
ListChangeAccumulator<E> mods = new ListChangeAccumulator<>();
for(int i = from; i < to; ++i) {
if(!sparseList.isPresent(i)) {
E elem = source.get(i);
if(sparseList.setIfAbsent(i, elem)) {
mods.add(ProperLiveList.elemInsertion(presentBefore + (i - from)));
int presentBefore = sparseList.getPresentCountBefore(i);
memoizedItems.prepareNotifications(ProperLiveList.elemInsertion(presentBefore));
}
}
}
if(!mods.isEmpty()) {
memoizedItems.notifyObservers(mods.fetch());
}
memoizedItems.publishNotifications();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import org.junit.Test;
import org.reactfx.Counter;
import org.reactfx.value.Val;

public class MemoizationListTest {

Expand Down Expand Up @@ -189,4 +190,23 @@ public void testRecursionWithinForce() {

assertEquals(Arrays.asList(1), memo2Mirror);
}

@Test
public void testMemoizedItemsChangeWithinForce() {
LiveList<Integer> src = new LiveArrayList<>(1, 2, 4, 8, 16, 32);
MemoizationList<Integer> memo1 = src.memoize();
MemoizationList<Integer> memo2 = memo1.map(Function.identity()).memoize();
Val<Integer> memo1Sum = memo1.memoizedItems().reduce((a, b) -> a + b).orElseConst(0);
memo1Sum.addListener((obs, oldVal, newVal) -> memo2.forget(0, memo2.size()));

List<Integer> memo2Mirror = new ArrayList<>();
memo2.memoizedItems().observeModifications(mod -> {
memo2Mirror.subList(mod.getFrom(), mod.getFrom() + mod.getRemovedSize()).clear();
memo2Mirror.addAll(mod.getFrom(), mod.getAddedSubList());
// the main part of this test is that it does not throw IndexOutOfBoundsException
});
memo2.force(3, 6);

assertEquals(Arrays.asList(32), memo2Mirror);
}
}

0 comments on commit f5d6fb5

Please sign in to comment.