use of org.projectnessie.versioned.Operation in project nessie by projectnessie.
the class AbstractDuplicateTable method duplicateTableOnBranches.
/**
* Test behavior when a table (content-key) is created on two different branches using either
* table-types with and without global-states and same/different content-ids.
*/
@ParameterizedTest
@EnumSource(value = DuplicateTableMode.class)
void duplicateTableOnBranches(DuplicateTableMode mode) throws Throwable {
Key key = Key.of("some", "table");
BranchName branch0 = BranchName.of("globalStateDuplicateTable-main");
store().create(branch0, Optional.empty());
// commit just something to have a "real" common ancestor and not "beginning of time", which
// means no-common-ancestor
Hash ancestor = store().commit(branch0, Optional.empty(), commitMessage("initial commit"), ImmutableList.of(Put.of(Key.of("unrelated", "table"), newOnRef("value"))));
// Create a table with the same name on two branches.
// WITH global-states, that must fail
// WITHOUT global-state, it is okay to work
BranchName branch1 = BranchName.of("globalStateDuplicateTable-branch1");
BranchName branch2 = BranchName.of("globalStateDuplicateTable-branch2");
assertThat(store().create(branch1, Optional.of(ancestor))).isEqualTo(ancestor);
assertThat(store().create(branch2, Optional.of(ancestor))).isEqualTo(ancestor);
List<Operation<BaseContent>> putForBranch1;
List<Operation<BaseContent>> putForBranch2;
BaseContent valuebranch1;
BaseContent valuebranch2;
switch(mode) {
case NO_GLOBAL:
valuebranch1 = newOnRef("create table");
valuebranch2 = newOnRef("create table");
putForBranch1 = ImmutableList.of(Put.of(key, valuebranch1));
putForBranch2 = ImmutableList.of(Put.of(key, valuebranch2));
break;
case STATEFUL_SAME_CONTENT_ID:
valuebranch1 = withGlobal("state", "create table", "content-id-equal");
valuebranch2 = withGlobal("state", "create table", "content-id-equal");
putForBranch1 = singletonList(Put.of(key, withGlobal("state", "create table", "content-id-equal")));
putForBranch2 = singletonList(Put.of(key, withGlobal("state", "create table", "content-id-equal")));
break;
case STATEFUL_DIFFERENT_CONTENT_ID:
valuebranch1 = withGlobal("state", "create table", "content-id-1");
valuebranch2 = withGlobal("state", "create table", "content-id-2");
putForBranch1 = singletonList(Put.of(key, withGlobal("state", "create table", "content-id-1")));
putForBranch2 = singletonList(Put.of(key, withGlobal("state", "create table", "content-id-2")));
break;
default:
throw new IllegalStateException();
}
store().commit(branch1, Optional.empty(), commitMessage("create table"), putForBranch1);
assertThat(store().getValue(branch1, key)).isEqualTo(valuebranch1);
ThrowingCallable createTableOnOtherBranch = () -> store().commit(branch2, Optional.empty(), commitMessage("create table on other branch"), putForBranch2);
if (mode == DuplicateTableMode.STATEFUL_SAME_CONTENT_ID) {
assertThatThrownBy(createTableOnOtherBranch).isInstanceOf(ReferenceConflictException.class).hasMessage("Global-state for content-id 'content-id-equal' already exists.");
assertThat(store().getValue(branch2, key)).isNull();
} else {
createTableOnOtherBranch.call();
assertThat(store().getValue(branch2, key)).isEqualTo(valuebranch2);
}
}
use of org.projectnessie.versioned.Operation in project nessie by projectnessie.
the class CommitBench method initialOperations.
static List<Operation<BaseContent>> initialOperations(BenchmarkParam bp, List<Key> keys, Map<Key, String> contentIds) {
List<Operation<BaseContent>> operations = new ArrayList<>(bp.tablesPerCommit);
for (Key key : keys) {
String contentId = contentIds.get(key);
operations.add(Put.of(key, withGlobal("0", "initial commit content", contentId)));
}
return operations;
}
use of org.projectnessie.versioned.Operation in project nessie by projectnessie.
the class AbstractSingleBranch method singleBranchManyUsers.
/**
* Use case simulation matrix: single branch, multiple users, each or all user updating a separate
* or single table.
*/
@ParameterizedTest
@MethodSource("singleBranchManyUsersCases")
void singleBranchManyUsers(SingleBranchParam param) throws Exception {
BranchName branch = BranchName.of(param.branchName);
int numUsers = 5;
int numCommits = 50;
Hash[] hashesKnownByUser = new Hash[numUsers];
Hash createHash = store().create(branch, Optional.empty());
Arrays.fill(hashesKnownByUser, createHash);
List<CommitMessage> expectedValues = new ArrayList<>();
Map<Key, String> previousState = new HashMap<>();
for (int commitNum = 0; commitNum < numCommits; commitNum++) {
for (int user = 0; user < numUsers; user++) {
Hash hashKnownByUser = hashesKnownByUser[user];
CommitMessage msg = commitMessage(String.format("user %03d/commit %03d", user, commitNum));
expectedValues.add(msg);
Key key = Key.of(param.tableNameGen.apply(user));
String contentId = param.contentIdGen.apply(user);
Operation<BaseContent> put;
if (param.globalState) {
String state = String.format("%03d_%03d", user, commitNum);
if (previousState.containsKey(key)) {
put = Put.of(key, withGlobal(state, "data_file", contentId), withGlobal(previousState.get(key), "foo", contentId));
} else {
put = Put.of(key, withGlobal(state, "data_file", contentId));
}
previousState.put(key, state);
} else {
BaseContent value = newOnRef(String.format("data_file_%03d_%03d", user, commitNum));
put = Put.of(key, value);
}
Hash commitHash;
List<Operation<BaseContent>> ops = ImmutableList.of(put);
try {
commitHash = store().commit(branch, Optional.of(hashKnownByUser), msg, ops);
} catch (ReferenceConflictException inconsistentValueException) {
if (param.allowInconsistentValueException) {
hashKnownByUser = store().hashOnReference(branch, Optional.empty());
commitHash = store().commit(branch, Optional.of(hashKnownByUser), msg, ops);
} else {
throw inconsistentValueException;
}
}
assertNotEquals(hashKnownByUser, commitHash);
hashesKnownByUser[user] = commitHash;
}
}
// Verify that all commits are there and that the order of the commits is correct
List<CommitMessage> committedValues = commitsList(branch, s -> s.map(Commit::getCommitMeta), false);
Collections.reverse(expectedValues);
assertEquals(expectedValues, committedValues);
}
use of org.projectnessie.versioned.Operation in project nessie by projectnessie.
the class CommitBench method doCommit.
private void doCommit(BenchmarkParam bp, BranchName branch, List<Key> keys, Map<Key, String> contentIds) throws Exception {
Map<Key, BaseContent> contentByKey = bp.versionStore.getValues(branch, keys);
try {
List<Operation<BaseContent>> operations = new ArrayList<>(bp.tablesPerCommit);
for (int i = 0; i < bp.tablesPerCommit; i++) {
Key key = keys.get(i);
BaseContent value = contentByKey.get(key);
if (value == null) {
throw new RuntimeException("no value for key " + key + " in " + branch);
}
String currentState = ((WithGlobalStateContent) value).getGlobal();
String newGlobalState = Integer.toString(Integer.parseInt(currentState) + 1);
String contentId = contentIds.get(key);
operations.add(Put.of(key, // hashes, because parent, "content", key are all the same.
withGlobal(newGlobalState, "commit value " + ThreadLocalRandom.current().nextLong(), contentId), withGlobal(currentState, "foo", contentId)));
}
bp.versionStore.commit(branch, Optional.empty(), commitMessage("commit meta data"), operations);
bp.success.incrementAndGet();
} catch (ReferenceRetryFailureException e) {
bp.retryFailures.incrementAndGet();
} catch (ReferenceConflictException e) {
bp.conflictsFailures.incrementAndGet();
}
}
Aggregations