@Override public TimestampStoreInvalidator createTimestampStoreInvalidator(KeyValueService rawKvs) { return CassandraTimestampStoreInvalidator.create(rawKvs); } }
@Test public void throwsIfCreatingWithNonCassandraKvs() { assertThatThrownBy(() -> CassandraTimestampStoreInvalidator.create(new InMemoryKeyValueService(false))) .isInstanceOf(IllegalArgumentException.class); }
@Test public void multipleInvalidatorsForSameKeyValueServiceAllReturnSameResults() { long limit = getBoundAfterTakingOutOneMillionTimestamps(); CassandraTestTools.executeInParallelOnExecutorService(() -> assertThat(CassandraTimestampStoreInvalidator.create(kv).backupAndInvalidate()).isEqualTo(limit)); }
/** * Consistent results here mean that: * (1) all calls to backupAndInvalidate() return the same value V, and * (2) this value V is the maximum of all successfully stored timestamp bounds. */ @Test public void invalidationDuringTimestampIssuanceYieldsConsistentResults() { Set<Long> backedUpValues = Sets.newConcurrentHashSet(); AtomicLong maxSuccessfulBound = new AtomicLong(CassandraTimestampUtils.INITIAL_VALUE); CassandraTestTools.executeInParallelOnExecutorService(() -> { CassandraTimestampStoreInvalidator storeInvalidator = CassandraTimestampStoreInvalidator.create(kv); try { if (ThreadLocalRandom.current().nextBoolean()) { backedUpValues.add(storeInvalidator.backupAndInvalidate()); } else { maxSuccessfulBound.accumulateAndGet(getBoundAfterTakingOutOneMillionTimestamps(), Math::max); } } catch (IllegalArgumentException | IllegalStateException | MultipleRunningTimestampServiceError error) { // Can arise if trying to manipulate the timestamp bound during/after an invalidation. This is fine. } }); if (!backedUpValues.isEmpty()) { invalidator.revalidateFromBackup(); assertThat(Iterables.getOnlyElement(backedUpValues)).isEqualTo(maxSuccessfulBound.get()); assertWeCanReadTimestamp(maxSuccessfulBound.get()); } // 2^-32 chance that nothing got backed up; accept in this case. }
@Override public TimestampStoreInvalidator createTimestampStoreInvalidator(KeyValueService rawKvs) { return CassandraTimestampStoreInvalidator.create(rawKvs); } }