use of io.pravega.segmentstore.contracts.tables.TableKey in project pravega by pravega.
the class ContainerKeyIndex method validateConditionalUpdateFailures.
private CompletableFuture<Void> validateConditionalUpdateFailures(DirectSegmentAccess segment, Map<TableKey, Long> expectedVersions, TimeoutTimer timer) {
assert !expectedVersions.isEmpty();
val bucketReader = TableBucketReader.key(segment, this::getBackpointerOffset, this.executor);
val searches = expectedVersions.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> findBucketEntry(segment, bucketReader, e.getKey().getKey(), e.getValue(), timer)));
return Futures.allOf(searches.values()).thenRun(() -> {
val failed = new HashMap<TableKey, Long>();
for (val e : searches.entrySet()) {
val actual = e.getValue().join();
boolean isValid = actual == null ? e.getKey().getVersion() == TableKey.NOT_EXISTS : e.getKey().getVersion() == actual.getVersion();
if (!isValid) {
failed.put(e.getKey(), actual == null ? TableKey.NOT_EXISTS : actual.getVersion());
}
}
if (!failed.isEmpty()) {
throw new CompletionException(new BadKeyVersionException(segment.getInfo().getName(), failed));
}
});
}
use of io.pravega.segmentstore.contracts.tables.TableKey in project pravega by pravega.
the class ContainerKeyIndex method validateConditionalUpdate.
/**
* Validates a list of UpdateBatchItems against their actual Table Bucket offsets.
*
* @param items A list of {@link TableKeyBatch.Item} instances to validate.
* @param bucketOffsets A Map of Key Hashes to their corresponding offsets (versions). Each {@link TableKeyBatch.Item}
* will be looked up in this Map (based on the Item's KeyHash) and validated appropriately.
* @param segmentName The name of the segment on which the update is performed.
* @throws KeyNotExistsException If an UpdateBatchItem's Key does not exist in the Table but the item's version does
* not indicate that the key must not exist.
* @throws BadKeyVersionException If an UpdateBatchItem's Key does exist in the Table but the item's version is
* different from that key's version.
*/
@SneakyThrows(ConditionalTableUpdateException.class)
private void validateConditionalUpdate(List<TableKeyBatch.Item> items, Map<UUID, Long> bucketOffsets, String segmentName) {
// Key = Key that failed, Value = Key's bucket offset.
val badKeyVersions = new HashMap<TableKey, Long>();
for (val item : items) {
// Validate compareVersion.
TableKey key = item.getKey();
Long bucketOffset = bucketOffsets.get(item.getHash());
assert key.hasVersion() : "validateConditionalUpdate for TableKey with no compare version";
if (bucketOffset == TableKey.NOT_EXISTS) {
if (key.getVersion() != TableKey.NOT_EXISTS) {
// Key does not exist, but the conditional update provided a specific version.
throw new KeyNotExistsException(segmentName, key.getKey());
}
} else if (bucketOffset != key.getVersion()) {
// Key does exist, but has the wrong version.
badKeyVersions.put(key, bucketOffset);
}
}
if (!badKeyVersions.isEmpty()) {
// Throw the bad key version in bulk - helps speed verification.
throw new BadKeyVersionException(segmentName, badKeyVersions);
}
// All validations for all items passed.
}
use of io.pravega.segmentstore.contracts.tables.TableKey in project pravega by pravega.
the class TableServiceTests method generateRemovals.
private HashMap<String, ArrayList<TableKey>> generateRemovals(HashMap<BufferView, EntryData> keyInfo, boolean conditional) {
val result = new HashMap<String, ArrayList<TableKey>>();
for (val e : keyInfo.entrySet()) {
val ed = e.getValue();
TableKey tk = conditional ? TableKey.versioned(e.getKey(), ed.getVersion()) : TableKey.unversioned(e.getKey());
val segmentUpdate = result.computeIfAbsent(ed.segmentName, ignored -> new ArrayList<>());
segmentUpdate.add(tk);
}
return result;
}
use of io.pravega.segmentstore.contracts.tables.TableKey in project pravega by pravega.
the class TableServiceTests method executeOffsetConditonalRemovals.
private void executeOffsetConditonalRemovals(HashMap<String, ArrayList<TableKey>> removals, long tableSegmentOffset, TableStore tableStore) throws Exception {
val updateResult = removals.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> tableStore.remove(e.getKey(), e.getValue(), tableSegmentOffset, TIMEOUT)));
Futures.allOf(updateResult.values()).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
}
use of io.pravega.segmentstore.contracts.tables.TableKey in project pravega by pravega.
the class TableServiceTests method executeRemovals.
private void executeRemovals(HashMap<String, ArrayList<TableKey>> removals, TableStore tableStore) throws Exception {
val updateResult = removals.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> tableStore.remove(e.getKey(), e.getValue(), TIMEOUT)));
Futures.allOf(updateResult.values()).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
}
Aggregations