CheckAndSetRequest createNewCellRequest(ShardAndStrategy shardAndStrategy, byte[] colValNew) { return CheckAndSetRequest.newCell(TABLE_REF, cellForShard(shardAndStrategy), colValNew); }
private void updateWatermarkForTable(long newWatermark, TableReference table) { while (true) { Cell cell = cell(table); Optional<Value> currentValue = Optional.ofNullable( kvs.get(CLEARS, ImmutableMap.of(cell, Long.MAX_VALUE)).get(cell)); Optional<Long> currentWatermark = currentValue.map(value -> RowResult.of(cell, value.getContents())) .map(TableClearsRowResult::of) .map(TableClearsRowResult::getLastClearedTimestamp); if (currentWatermark.isPresent() && currentWatermark.get() > newWatermark) { return; } CheckAndSetRequest request = currentWatermark .map(watermark -> CheckAndSetRequest.singleCell( CLEARS, cell, EncodingUtils.encodeVarLong(watermark), EncodingUtils.encodeVarLong(newWatermark))) .orElseGet(() -> CheckAndSetRequest.newCell( CLEARS, cell, EncodingUtils.encodeVarLong(newWatermark))); try { kvs.checkAndSet(request); return; } catch (CheckAndSetException e) { // do nothing, we spin } } }
void populate() { CheckAndSetRequest request = CheckAndSetRequest.newCell( AtlasDbConstants.PERSISTED_LOCKS_TABLE, LOCK_OPEN.cell(), LOCK_OPEN.value()); try { kvs.checkAndSet(request); } catch (CheckAndSetException e) { // This can happen if multiple LockStores are started at once. We don't actually mind. // All we care about is that we're in the state machine of "LOCK_OPEN"/"LOCK_TAKEN". // It still might be interesting, so we'll log it. List<String> values = getActualValues(e); log.debug("Encountered a CheckAndSetException when creating the LockStore. This means that two " + "LockStore objects were created near-simultaneously, and is probably not a problem. " + "For the record, we observed these values: {}", values); } }
Optional<KeyAlreadyExistsException> failure = clientPool.runWithRetry(client -> { for (Entry<Cell, byte[]> e : values.entrySet()) { CheckAndSetRequest request = CheckAndSetRequest.newCell(tableRef, e.getKey(), e.getValue()); CheckAndSetResult casResult = checkAndSetRunner.executeCheckAndSet(client, request); if (!casResult.successful()) {
private CheckAndSetRequest casProgressRequest(Cell cell, Map<Cell, Value> storedProgress, SweepProgress newProgress) throws JsonProcessingException { if (storedProgress.isEmpty()) { // Progress for this thread has never been stored return CheckAndSetRequest.newCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, progressToBytes(newProgress)); } Value storedValue = Iterables.getOnlyElement(storedProgress.values()); if (isFinishedTablePlaceholder(storedValue)) { // Last iteration, this thread finished a table return CheckAndSetRequest.singleCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, FINISHED_TABLE, progressToBytes(newProgress)); } else { return CheckAndSetRequest.singleCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, progressToBytes(hydrateProgress(storedProgress).get()), progressToBytes(newProgress)); } }
@Test public void testReadFromOldProgress() throws JsonProcessingException { byte[] progressBytes = SweepProgressStoreImpl.progressToBytes(PROGRESS); kvs.checkAndSet(CheckAndSetRequest.newCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, SweepProgressStoreImpl.LEGACY_CELL, progressBytes)); // Enforce initialisation, which is where we expect the legacy value to be read. SweepProgressStore newProgressStore = SweepProgressStoreImpl.create(kvs, false); Assert.assertEquals(Optional.of(PROGRESS), newProgressStore.loadProgress(TABLE)); }
@Test public void testCheckAndSetLargeValue() { Assume.assumeTrue(checkAndSetSupported()); byte[] megabyteValue = new byte[1048576]; CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, megabyteValue); keyValueService.checkAndSet(request); verifyCheckAndSet(TEST_CELL, megabyteValue); }
@Test public void repeatedCreationDoesNotMoveProgressBackwards() throws JsonProcessingException { byte[] progressBytes = SweepProgressStoreImpl.progressToBytes(PROGRESS); kvs.checkAndSet(CheckAndSetRequest.newCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, SweepProgressStoreImpl.LEGACY_CELL, progressBytes)); // Enforce initialisation, which is where we expect the legacy value to be read. SweepProgressStore newProgressStore = SweepProgressStoreImpl.create(kvs, false); Assert.assertEquals(Optional.of(PROGRESS), newProgressStore.loadProgress(TABLE)); newProgressStore.saveProgress(SECOND_PROGRESS); // This will fail if the legacy value is not removed by the initialisation of newProgressStore SweepProgressStore newerProgressStore = SweepProgressStoreImpl.create(kvs, false); Assert.assertEquals(Optional.of(SECOND_PROGRESS), newerProgressStore.loadProgress(TABLE)); } }
boolean storeNewMapping(TableReference table, int id) { SweepIdToNameColumn column = SweepIdToNameColumn.of(id); SweepIdToNameColumnValue value = SweepIdToNameColumnValue.of(column, table.getQualifiedName()); Cell cell = Cell.create(rowAsBytes, value.persistColumnName()); CheckAndSetRequest request = CheckAndSetRequest.newCell(ID_TO_NAME, cell, value.persistValue()); try { kvs.checkAndSet(request); return true; } catch (CheckAndSetException e) { return get(id).get().equals(table); } }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromNoValueWhenValueIsPresent() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); keyValueService.checkAndSet(request); }
SweepTableIdentifier storeAsPending(TableReference table, int nextId) { SweepNameToIdRow row = SweepNameToIdRow.of(table.getQualifiedName()); Cell cell = Cell.create(row.persistToBytes(), SweepNameToIdNamedColumn.ID.getShortName()); SweepTableIdentifier newValue = SweepTableIdentifier.pending(nextId); CheckAndSetRequest cas = CheckAndSetRequest.newCell(NAME_TO_ID, cell, newValue.persistToBytes()); try { kvs.checkAndSet(cas); return newValue; } catch (CheckAndSetException e) { return currentMapping(table).get(); } }
@Test public void testCheckAndSetFromEmpty() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); verifyCheckAndSet(TEST_CELL, val(0, 0)); }
@Test public void testCheckAndSetIndependentlyFails() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); assertThatThrownBy(() -> keyValueService.checkAndSet( CheckAndSetRequest.singleCell(TEST_TABLE, nextTestCell, val(0, 0), val(0, 1)))) .isInstanceOf(CheckAndSetException.class); verifyCheckAndSet(firstTestCell, val(0, 0)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
@Test public void testCheckAndSetToNewCellsInDistinctRows() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); verifyCheckAndSet(firstTestCell, val(0, 0)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromWrongValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); try { CheckAndSetRequest secondRequest = CheckAndSetRequest .singleCell(TEST_TABLE, TEST_CELL, val(0, 1), val(0, 0)); keyValueService.checkAndSet(secondRequest); } catch (CheckAndSetException ex) { assertThat(ex.getActualValues(), contains(val(0, 0))); throw ex; } }
@Test public void testCheckAndSetIndependentlyWorks() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); keyValueService.checkAndSet(CheckAndSetRequest.singleCell(TEST_TABLE, firstTestCell, val(0, 0), val(0, 1))); verifyCheckAndSet(firstTestCell, val(0, 1)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
@Test public void testCheckAndSetFromOtherValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); CheckAndSetRequest secondRequest = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 0), val(0, 1)); keyValueService.checkAndSet(secondRequest); verifyCheckAndSet(TEST_CELL, val(0, 1)); }
@Test public void fromRowResultProducesLockEntry() { KeyValueService kvs = new InMemoryKeyValueService(false); kvs.createTable(TEST_TABLE, AtlasDbConstants.GENERIC_TABLE_METADATA); kvs.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, LOCK_ENTRY.cell(), LOCK_ENTRY.value())); Iterator<RowResult<Value>> range = kvs.getRange(TEST_TABLE, RangeRequest.all(), AtlasDbConstants.TRANSACTION_TS + 1); RowResult<Value> onlyEntry = Iterables.getOnlyElement(ImmutableSet.copyOf(range)); LockEntry lockEntry = LockEntry.fromRowResult(onlyEntry); assertEquals(LOCK_ENTRY, lockEntry); }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromNoValueWhenValueIsPresent() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); keyValueService.checkAndSet(request); }
@Test public void testCheckAndSetIndependentlyWorks() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); keyValueService.checkAndSet(CheckAndSetRequest.singleCell(TEST_TABLE, firstTestCell, val(0, 0), val(0, 1))); verifyCheckAndSet(firstTestCell, val(0, 1)); verifyCheckAndSet(nextTestCell, val(0, 1)); }