TarRevisions implements Revisions, Closeable { @Override public boolean setHead( @NotNull RecordId expected, @NotNull RecordId head, @NotNull Option... options) { checkBound(); Lock lock = isExpedited(options) ? rwLock.writeLock() : rwLock.readLock(); lock.lock(); try { RecordId id = this.head.get(); return id.equals(expected) && this.head.compareAndSet(id, head); } finally { lock.unlock(); } } TarRevisions(SegmentNodeStorePersistence persistence); static Option timeout(long time, TimeUnit unit); @NotNull @Override RecordId getHead(); @NotNull @Override RecordId getPersistedHead(); @Override boolean setHead(
            @NotNull RecordId expected,
            @NotNull RecordId head,
            @NotNull Option... options); @Override RecordId setHead(
            @NotNull Function<RecordId, RecordId> newHead,
            @NotNull Option... options); @Override void close(); static final Option EXPEDITE_OPTION; static final Option INFINITY; }
@Test public void setHead() throws IOException { RecordId headId = revisions.getHead(); SegmentNodeState newRoot = addChild(reader.readNode(headId), "a"); assertTrue(revisions.setHead(headId, newRoot.getRecordId())); store.flush(); try (JournalReader reader = createJournalReader()) { assertTrue(reader.hasNext()); assertEquals(newRoot.getRecordId().toString10(), reader.next().getRevision()); } }
@Test public void setFromFunctionBlocks() throws ExecutionException, InterruptedException, TimeoutException { ListeningExecutorService executor = listeningDecorator(newFixedThreadPool(2)); try { final CountDownLatch latch = new CountDownLatch(1); ListenableFuture<Boolean> t1 = executor.submit(new Callable<Boolean>() { @Override public Boolean call() throws Exception { latch.await(); return null != revisions.setHead(Functions.<RecordId>identity()); } }); try { t1.get(500, MILLISECONDS); fail("SetHead from function should block"); } catch (TimeoutException expected) {} ListenableFuture<Boolean> t2 = executor.submit(new Callable<Boolean>() { @Override public Boolean call() throws Exception { latch.countDown(); return null != revisions.setHead(Functions.<RecordId>identity()); } }); assertTrue(t2.get(500, MILLISECONDS)); assertTrue(t1.get(500, MILLISECONDS)); } finally { executor.shutdown(); } }