/** * Determines which Ledger Ids are safe to delete from BookKeeper. * * @param oldMetadata A pointer to the previous version of the metadata, that contains all Ledgers eligible for * deletion. Only those Ledgers that do not exist in currentMetadata will be selected. * @param currentMetadata A pointer to the current version of the metadata. No Ledger that is referenced here will * be selected. * @return A List that contains Ledger Ids to remove. May be empty. */ @GuardedBy("lock") private List<Long> getLedgerIdsToDelete(LogMetadata oldMetadata, LogMetadata currentMetadata) { if (oldMetadata == null) { return Collections.emptyList(); } val existingIds = currentMetadata.getLedgers().stream() .map(LedgerMetadata::getLedgerId) .collect(Collectors.toSet()); return oldMetadata.getLedgers().stream() .map(LedgerMetadata::getLedgerId) .filter(id -> !existingIds.contains(id)) .collect(Collectors.toList()); }
private void checkLedgerIds(List<Long> expectedLedgerIds, LogMetadata metadata) { val actualLedgerIds = metadata.getLedgers().stream().map(LedgerMetadata::getLedgerId).collect(Collectors.toList()); AssertExtensions.assertListEquals("Unexpected ledger ids.", expectedLedgerIds, actualLedgerIds, Long::equals); } }
private void reportMetrics() { this.metrics.ledgerCount(getLogMetadata().getLedgers().size()); this.metrics.queueStats(this.writes.getStatistics()); }
val ledgerIdsToKeep = newMetadata.getLedgers().stream().map(LedgerMetadata::getLedgerId).collect(Collectors.toSet()); val ledgersToDelete = oldMetadata.getLedgers().stream().filter(lm -> !ledgerIdsToKeep.contains(lm.getLedgerId())).iterator(); while (ledgersToDelete.hasNext()) { val lm = ledgersToDelete.next();
val lastLedger = currentMetadata.getLedgers().get(currentMetadata.getLedgers().size() - 1); allLedgers.add(new AbstractMap.SimpleImmutableEntry<>(lastLedger.getLedgerId(), shouldAppend ? LedgerMetadata.Status.NotEmpty : LedgerMetadata.Status.Empty)); val metadataLedgers = currentMetadata.getLedgers().stream().map(LedgerMetadata::getLedgerId).collect(Collectors.toSet());
val emptyLedgerIds = Ledgers.fenceOut(oldMetadata.getLedgers(), this.bookKeeper, this.config, this.traceObjectId);
for (int i = 1; i < metadata.getLedgers().size(); i++) { Assert.assertEquals("Sequence is not incremented.", metadata.getLedgers().get(i - 1).getSequence() + 1, metadata.getLedgers().get(i).getSequence()); m.getLedgers().stream() .filter(lm -> lm.getStatus() != LedgerMetadata.Status.Empty) .map(LedgerMetadata::getLedgerId) .forEach(expectedLedgerIds::add); for (int i = m.getLedgers().size() - skipCount; i < m.getLedgers().size(); i++) { long ledgerId = m.getLedgers().get(i).getLedgerId(); if (!expectedLedgerIds.contains(ledgerId)) { expectedLedgerIds.add(ledgerId);
val allMetadatas = this.metadata.getLedgers();
val firstLedgerId = m.getLedgers().get(0).getLedgerId(); val firstLedgerSeq = m.getLedgers().get(0).getSequence(); LedgerAddress a = m.getNextAddress(new LedgerAddress(firstLedgerSeq - 1, firstLedgerId - 1, 1234), Long.MAX_VALUE); Assert.assertEquals("Unexpected ledger id when input address less than first ledger.", firstLedgerId, a.getLedgerId()); val secondLedgerId = m.getLedgers().get(1).getLedgerId(); val secondLedgerSeq = m.getLedgers().get(1).getSequence(); LedgerAddress truncationAddress = new LedgerAddress(secondLedgerSeq, secondLedgerId, 1); val m2 = m.truncate(truncationAddress); for (int i = 0; i < m.getLedgers().size(); i++) { val lm = m.getLedgers().get(i); a = m.getNextAddress(new LedgerAddress(lm.getSequence(), lm.getLedgerId(), 3), 3); if (i == m.getLedgers().size() - 1) { Assert.assertNull("Unexpected result when reached the end of the log.", a); } else { val nextLm = m.getLedgers().get(i + 1); Assert.assertEquals("Unexpected ledger id when result should be in the next ledger.", nextLm.getLedgerId(), a.getLedgerId()); Assert.assertEquals("Unexpected entry id when result should be in the next ledger.", 0, a.getEntryId());
/** * Tests serialization/deserialization. */ @Test(timeout = 5000) public void testSerialization() throws Exception { Supplier<Long> nextLedgerId = new AtomicLong()::incrementAndGet; LogMetadata m1 = null; val lacs = new HashMap<Long, Long>(); for (int i = 0; i < LEDGER_COUNT; i++) { long ledgerId = nextLedgerId.get() * 2; if (m1 == null) { m1 = new LogMetadata(ledgerId).withUpdateVersion(i); } else { m1 = m1.addLedger(ledgerId).withUpdateVersion(i); } if (i % 2 == 0) { // Every other Ledger, update the LastAddConfirmed. lacs.put((long) i, (long) i + 1); } } m1 = m1.updateLedgerStatus(lacs); val serialization = LogMetadata.SERIALIZER.serialize(m1); val m2 = LogMetadata.SERIALIZER.deserialize(serialization); Assert.assertEquals("Unexpected epoch.", m1.getEpoch(), m2.getEpoch()); Assert.assertEquals("Unexpected TruncationAddress.", m1.getTruncationAddress().getSequence(), m2.getTruncationAddress().getSequence()); Assert.assertEquals("Unexpected TruncationAddress.", m1.getTruncationAddress().getLedgerId(), m2.getTruncationAddress().getLedgerId()); AssertExtensions.assertListEquals("Unexpected ledgers.", m1.getLedgers(), m2.getLedgers(), (l1, l2) -> l1.getSequence() == l2.getSequence() && l1.getLedgerId() == l2.getLedgerId() && l1.getStatus() == l2.getStatus()); }