OTAlgorithms { public static <K, D> Promise<List<D>> checkout(OTRepository<K, D> repository, OTSystem<D> system) { Ref<List<D>> cachedSnapshotRef = new Ref<>(); return repository.getHeads() .then(heads -> findParent(repository, system, heads, DiffsReducer.toVoid(), commit -> repository.loadSnapshot(commit.getId()) .map(maybeSnapshot -> (cachedSnapshotRef.value = maybeSnapshot.orElse(null)) != null)) .then(findResult -> Promise.of(cachedSnapshotRef.value))) .whenComplete(toLogger(logger, thisMethod())); }  static Promise<R> reduce(OTRepository<K, D> repository, OTSystem<D> system,
			Set<K> heads, GraphReducer<K, D, R> reducer); static Promise<FindResult<K, A>> findParent(OTRepository<K, D> repository, OTSystem<D> system,
			Set<K> startNodes, DiffsReducer<A, D> diffsReducer, AsyncPredicate<OTCommit<K, D>> matchPredicate); static Promise<K> mergeAndPush(OTRepository<K, D> repository, OTSystem<D> system); static Promise<K> mergeAndPush(OTRepository<K, D> repository, OTSystem<D> system, @NotNull Set<K> heads); static Promise<K> mergeAndUpdateHeads(OTRepository<K, D> repository, OTSystem<D> system); static Promise<K> mergeAndUpdateHeads(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads); @NotNull static Promise<OTCommit<K, D>> merge(OTRepository<K, D> repository, OTSystem<D> system, @NotNull Set<K> heads); static Promise<Set<K>> findCut(OTRepository<K, D> repository, OTSystem<D> system, Set<K> startNodes,
			Predicate<Collection<OTCommit<K, D>>> matchPredicate); static Promise<K> findAnyCommonParent(OTRepository<K, D> repository, OTSystem<D> system, Set<K> startCut); static Promise<Set<K>> findAllCommonParents(OTRepository<K, D> repository, OTSystem<D> system, Set<K> startCut); static Promise<List<D>> diff(OTRepository<K, D> repository, OTSystem<D> system, K node1, K node2); static Promise<Set<K>> excludeParents(OTRepository<K, D> repository, OTSystem<D> system, Set<K> startNodes); static Promise<Map<K, A>> reduceEdges(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads, K parentNode,
			DiffsReducer<A, D> diffAccumulator); static Promise<List<D>> checkout(OTRepository<K, D> repository, OTSystem<D> system); static Promise<List<D>> checkout(OTRepository<K, D> repository, OTSystem<D> system, K commitId); static Promise<Void> saveSnapshot(OTRepository<K, D> repository, OTSystem<D> system, K revisionId); static Promise<OTLoadedGraph<K, D>> loadForMerge(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads); static Promise<OTLoadedGraph<K, D>> loadGraph(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads, OTLoadedGraph<K, D> graph); static Promise<OTLoadedGraph<K, D>> loadGraph(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads); static Promise<OTLoadedGraph<K, D>> loadGraph(OTRepository<K, D> repository, OTSystem<D> system, Set<K> heads, Function<K, String> idToString, Function<D, String> diffToString); static Promise<Void> copy(OTRepository<K, D> from, OTRepository<K, D> to); static final StacklessException GRAPH_EXHAUSTED; }
@Test public void testCheckOutNoSnapshot() { REPOSITORY.revisionIdSupplier = () -> RANDOM.nextInt(1000) + 1; Integer id1 = await(REPOSITORY.createCommitId()); await(REPOSITORY.pushAndUpdateHead(OTCommit.ofRoot(id1))); Integer id2 = await(REPOSITORY.createCommitId()); await(REPOSITORY.pushAndUpdateHead(OTCommit.ofCommit(0, id2, id1, emptyList(), id1))); Throwable exception = awaitException(checkout(REPOSITORY, TEST_OP, id2)); assertSame(GRAPH_EXHAUSTED, exception); }