@Override public void disable() throws DurableDataLogException { ensurePreconditions(); synchronized (this.entries) { this.entries.disable(this.clientId); } close(); }
@Override protected DurableDataLog createDurableDataLog(Object sharedContext) { Preconditions.checkArgument(sharedContext instanceof InMemoryDurableDataLog.EntryCollection); return new InMemoryDurableDataLog((InMemoryDurableDataLog.EntryCollection) sharedContext, executorService()); }
@Override public long getEpoch() { ensurePreconditions(); synchronized (this.entries) { return this.epoch; } }
@Override public DurableDataLog createDurableDataLog(int containerId) { Exceptions.checkNotClosed(this.closed, this); InMemoryDurableDataLog.EntryCollection entries; synchronized (this.persistedData) { entries = this.persistedData.getOrDefault(containerId, null); if (entries == null) { entries = this.maxAppendSize < 0 ? new InMemoryDurableDataLog.EntryCollection() : new InMemoryDurableDataLog.EntryCollection(this.maxAppendSize); this.persistedData.put(containerId, entries); } } return new InMemoryDurableDataLog(entries, this.appendDelayProvider, this.executorService); }
@Override public CloseableIterator<ReadItem, DurableDataLogException> getReader() throws DurableDataLogException { ensurePreconditions(); return new ReadResultIterator(this.entries.iterator()); }
/** * Tests the constructor of InMemoryDurableDataLog. The constructor takes in an EntryCollection and this verifies * that information from a previous instance of an InMemoryDurableDataLog is still accessible. */ @Test(timeout = 5000) public void testConstructor() throws Exception { InMemoryDurableDataLog.EntryCollection entries = new InMemoryDurableDataLog.EntryCollection(); TreeMap<LogAddress, byte[]> writeData; // Create first log and write some data to it. try (DurableDataLog log = new InMemoryDurableDataLog(entries, executorService())) { log.initialize(TIMEOUT); writeData = populate(log, WRITE_COUNT); } // Close the first log, and open a second one, with the same EntryCollection in the constructor. try (DurableDataLog log = new InMemoryDurableDataLog(entries, executorService())) { log.initialize(TIMEOUT); // Verify it contains the same entries. verifyReads(log, writeData); } } }
@Override public CompletableFuture<Void> truncate(LogAddress upToAddress, Duration timeout) { ensurePreconditions(); return CompletableFuture.runAsync(() -> { try { synchronized (this.entries) { this.entries.truncate(upToAddress.getSequence(), this.clientId); } } catch (DataLogWriterNotPrimaryException ex) { throw new CompletionException(ex); } }, this.executorService); }
@Override public CompletableFuture<LogAddress> append(ArrayView data, Duration timeout) { ensurePreconditions(); CompletableFuture<LogAddress> result; try { Entry entry = new Entry(data); synchronized (this.entries) { entry.sequenceNumber = this.offset; this.entries.add(entry, clientId); // Only update internals after a successful add. this.offset += entry.data.length; } result = CompletableFuture.completedFuture(new InMemoryLogAddress(entry.sequenceNumber)); } catch (Throwable ex) { return Futures.failedFuture(ex); } Duration delay = this.appendDelayProvider.get(); if (delay.compareTo(Duration.ZERO) <= 0) { // No delay, execute right away. return result; } else { // Schedule the append after the given delay. return result.thenComposeAsync( logAddress -> Futures.delayedFuture(delay, this.executorService) .thenApply(ignored -> logAddress), this.executorService); } }