Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.scalar.db.transaction.consensuscommit;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
import com.scalar.db.api.Consistency;
import com.scalar.db.api.Delete;
import com.scalar.db.api.DistributedStorage;
import com.scalar.db.api.Get;
import com.scalar.db.api.Operation;
import com.scalar.db.api.Put;
import com.scalar.db.api.Result;
import com.scalar.db.api.Scan;
import com.scalar.db.api.ScanAll;
import com.scalar.db.api.ScanWithIndex;
import com.scalar.db.api.Scanner;
import com.scalar.db.api.Selection.Conjunction;
import com.scalar.db.api.TableMetadata;
import com.scalar.db.common.error.CoreError;
import com.scalar.db.exception.storage.ExecutionException;
import com.scalar.db.exception.transaction.CrudException;
import com.scalar.db.exception.transaction.PreparationConflictException;
import com.scalar.db.exception.transaction.ValidationConflictException;
import com.scalar.db.io.Column;
import com.scalar.db.transaction.consensuscommit.ParallelExecutor.ParallelExecutorTask;
import com.scalar.db.util.ScalarDbUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@NotThreadSafe
public class Snapshot {
private static final Logger logger = LoggerFactory.getLogger(Snapshot.class);
private final String id;
private final Isolation isolation;
private final SerializableStrategy strategy;
private final TransactionTableMetadataManager tableMetadataManager;
private final ParallelExecutor parallelExecutor;
private final ConcurrentMap> readSet;
private final ConcurrentMap> getSet;
private final Map> scanSet;
private final Map writeSet;
private final Map deleteSet;
public Snapshot(
String id,
Isolation isolation,
SerializableStrategy strategy,
TransactionTableMetadataManager tableMetadataManager,
ParallelExecutor parallelExecutor) {
this.id = id;
this.isolation = isolation;
this.strategy = strategy;
this.tableMetadataManager = tableMetadataManager;
this.parallelExecutor = parallelExecutor;
readSet = new ConcurrentHashMap<>();
getSet = new ConcurrentHashMap<>();
scanSet = new HashMap<>();
writeSet = new HashMap<>();
deleteSet = new HashMap<>();
}
@VisibleForTesting
Snapshot(
String id,
Isolation isolation,
SerializableStrategy strategy,
TransactionTableMetadataManager tableMetadataManager,
ParallelExecutor parallelExecutor,
ConcurrentMap> readSet,
ConcurrentMap> getSet,
Map> scanSet,
Map writeSet,
Map deleteSet) {
this.id = id;
this.isolation = isolation;
this.strategy = strategy;
this.tableMetadataManager = tableMetadataManager;
this.parallelExecutor = parallelExecutor;
this.readSet = readSet;
this.getSet = getSet;
this.scanSet = scanSet;
this.writeSet = writeSet;
this.deleteSet = deleteSet;
}
@Nonnull
public String getId() {
return id;
}
@VisibleForTesting
@Nonnull
Isolation getIsolation() {
return isolation;
}
// Although this class is not thread-safe, this method is actually thread-safe because the readSet
// is a concurrent map
public void put(Key key, Optional result) {
readSet.put(key, result);
}
// Although this class is not thread-safe, this method is actually thread-safe because the getSet
// is a concurrent map
public void put(Get get, Optional result) {
getSet.put(get, result);
}
public void put(Scan scan, Map results) {
scanSet.put(scan, results);
}
public void put(Key key, Put put) {
if (deleteSet.containsKey(key)) {
throw new IllegalArgumentException(
CoreError.CONSENSUS_COMMIT_WRITING_ALREADY_DELETED_DATA_NOT_ALLOWED.buildMessage());
}
if (writeSet.containsKey(key)) {
// merge the previous put in the write set and the new put
Put originalPut = writeSet.get(key);
put.getColumns().values().forEach(originalPut::withValue);
} else {
writeSet.put(key, put);
}
}
public void put(Key key, Delete delete) {
writeSet.remove(key);
deleteSet.put(key, delete);
}
public boolean containsKeyInReadSet(Key key) {
return readSet.containsKey(key);
}
public Optional getFromReadSet(Key key) {
return readSet.getOrDefault(key, Optional.empty());
}
public List getPutsInWriteSet() {
return new ArrayList<>(writeSet.values());
}
public List getDeletesInDeleteSet() {
return new ArrayList<>(deleteSet.values());
}
public Optional mergeResult(Key key, Optional result)
throws CrudException {
if (deleteSet.containsKey(key)) {
return Optional.empty();
} else if (writeSet.containsKey(key)) {
// merge the result in the read set and the put in the write set
return Optional.of(
new TransactionResult(
new MergedResult(result, writeSet.get(key), getTableMetadata(key))));
} else {
return result;
}
}
public Optional mergeResult(
Key key, Optional result, Set conjunctions)
throws CrudException {
return mergeResult(key, result)
.filter(
r ->
// We need to apply conditions if it is a merged result because the transaction’s
// write makes the record no longer match the conditions. Of course, we can just
// return the result without checking the condition if there is no condition.
!r.isMergedResult()
|| conjunctions.isEmpty()
|| ScalarDbUtils.columnsMatchAnyOfConjunctions(r.getColumns(), conjunctions));
}
private TableMetadata getTableMetadata(Key key) throws CrudException {
try {
TransactionTableMetadata metadata =
tableMetadataManager.getTransactionTableMetadata(key.getNamespace(), key.getTable());
if (metadata == null) {
throw new IllegalArgumentException(
CoreError.TABLE_NOT_FOUND.buildMessage(
ScalarDbUtils.getFullTableName(key.getNamespace(), key.getTable())));
}
return metadata.getTableMetadata();
} catch (ExecutionException e) {
throw new CrudException(e.getMessage(), e, id);
}
}
private TableMetadata getTableMetadata(Scan scan) throws ExecutionException {
TransactionTableMetadata metadata = tableMetadataManager.getTransactionTableMetadata(scan);
if (metadata == null) {
throw new IllegalArgumentException(
CoreError.TABLE_NOT_FOUND.buildMessage(scan.forFullTableName().get()));
}
return metadata.getTableMetadata();
}
public boolean containsKeyInGetSet(Get get) {
return getSet.containsKey(get);
}
public Optional get(Get get) {
// We expect this method is called after putting the result of the get operation in the get set.
assert getSet.containsKey(get);
return getSet.get(get);
}
public Optional