Search in sources :

Example 96 with Hash

use of org.projectnessie.versioned.Hash in project nessie by projectnessie.

the class AbstractGlobalStates method globalStates.

/**
 * Rudimentary test for Nessie-GC related basic operations to collect all globally known keys and
 * the global-state-logs.
 */
@ParameterizedTest
@MethodSource("globalStatesParams")
void globalStates(GlobalStateParam param) throws Exception {
    List<BranchName> branches = IntStream.range(0, param.branches).mapToObj(i -> BranchName.of("globalStates-" + i)).collect(Collectors.toList());
    Map<BranchName, Hash> heads = branches.stream().collect(Collectors.toMap(b -> b, b -> catchingFunction(() -> databaseAdapter.create(b, databaseAdapter.hashOnReference(BranchName.of("main"), Optional.empty())))));
    Map<ContentId, ByteString> currentStates = new HashMap<>();
    Set<Key> keys = IntStream.range(0, param.tables).mapToObj(i -> Key.of("table", Integer.toString(i))).collect(Collectors.toSet());
    Set<ContentId> usedContentIds = new HashSet<>();
    Map<ContentId, ByteString> expectedGlobalStates = new HashMap<>();
    for (int commit = 0; commit < param.commitsPerBranch; commit++) {
        for (BranchName branch : branches) {
            ImmutableCommitAttempt.Builder commitAttempt = ImmutableCommitAttempt.builder().commitToBranch(branch).expectedHead(Optional.of(heads.get(branch))).commitMetaSerialized(ByteString.copyFromUtf8("some commit#" + commit + " branch " + branch.getName()));
            for (Key key : keys) {
                if (param.tableCommitProbability == 1.0f || ThreadLocalRandom.current().nextDouble(0d, 1d) <= param.tableCommitProbability) {
                    String state = "state-commit-" + commit + "+" + key;
                    String value = "value-commit-" + commit + "+" + key;
                    ContentId contentId = ContentId.of(key.toString() + "-" + branch.getName());
                    ByteString put = ByteString.copyFromUtf8(value);
                    ByteString global = ByteString.copyFromUtf8(state);
                    commitAttempt.putExpectedStates(contentId, Optional.ofNullable(currentStates.get(contentId))).putGlobal(contentId, global).addPuts(KeyWithBytes.of(key, contentId, (byte) 0, put));
                    expectedGlobalStates.put(contentId, global);
                    usedContentIds.add(contentId);
                    currentStates.put(contentId, global);
                }
            }
            ImmutableCommitAttempt attempt = commitAttempt.build();
            if (!attempt.getPuts().isEmpty()) {
                heads.put(branch, databaseAdapter.commit(attempt));
            }
        }
    }
    // verify that all global-state keys (== Key + content-id) are returned (in any order)
    try (Stream<ContentId> globalKeys = databaseAdapter.globalKeys()) {
        assertThat(globalKeys).containsExactlyInAnyOrderElementsOf(expectedGlobalStates.keySet());
    }
    try (Stream<ContentIdAndBytes> allStates = databaseAdapter.globalContent(expectedGlobalStates.keySet())) {
        List<ContentIdAndBytes> all = allStates.collect(Collectors.toList());
        // verify that the global-state-log returns all keys (in any order)
        assertThat(all.stream().map(ContentIdAndBytes::getContentId).distinct()).containsExactlyInAnyOrderElementsOf(usedContentIds);
        // verify that the global-state-log returns all content-ids (in any order)
        assertThat(all.stream().map(ContentIdAndBytes::getContentId).distinct()).containsExactlyInAnyOrderElementsOf(currentStates.keySet());
        Collection<ByteString> allExpected = expectedGlobalStates.values();
        // verify that the global-state-log returns all state-values
        assertThat(all.stream().map(ContentIdAndBytes::getValue)).containsExactlyInAnyOrderElementsOf(allExpected);
    }
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) HashMap(java.util.HashMap) HashSet(java.util.HashSet) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) DatabaseAdapter(org.projectnessie.versioned.persist.adapter.DatabaseAdapter) MethodSource(org.junit.jupiter.params.provider.MethodSource) ContentIdAndBytes(org.projectnessie.versioned.persist.adapter.ContentIdAndBytes) Hash(org.projectnessie.versioned.Hash) Collection(java.util.Collection) Set(java.util.Set) Key(org.projectnessie.versioned.Key) Collectors(java.util.stream.Collectors) KeyWithBytes(org.projectnessie.versioned.persist.adapter.KeyWithBytes) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) BranchName(org.projectnessie.versioned.BranchName) ReferenceConflictException(org.projectnessie.versioned.ReferenceConflictException) List(java.util.List) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Stream(java.util.stream.Stream) ImmutableCommitAttempt(org.projectnessie.versioned.persist.adapter.ImmutableCommitAttempt) Optional(java.util.Optional) ContentId(org.projectnessie.versioned.persist.adapter.ContentId) ContentIdAndBytes(org.projectnessie.versioned.persist.adapter.ContentIdAndBytes) HashMap(java.util.HashMap) ByteString(com.google.protobuf.ByteString) ImmutableCommitAttempt(org.projectnessie.versioned.persist.adapter.ImmutableCommitAttempt) ByteString(com.google.protobuf.ByteString) Hash(org.projectnessie.versioned.Hash) ContentId(org.projectnessie.versioned.persist.adapter.ContentId) BranchName(org.projectnessie.versioned.BranchName) Key(org.projectnessie.versioned.Key) HashSet(java.util.HashSet) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 97 with Hash

use of org.projectnessie.versioned.Hash in project nessie by projectnessie.

the class AbstractDatabaseAdapter method commitAttempt.

/**
 * Logic implementation of a commit-attempt.
 *
 * @param ctx technical operation-context
 * @param commitAttempt commit parameters
 * @param branchHead current HEAD of {@code branch}
 * @param newKeyLists consumer for optimistically written {@link KeyListEntity}s
 * @return optimistically written commit-log-entry
 */
protected CommitLogEntry commitAttempt(OP_CONTEXT ctx, long timeInMicros, Hash branchHead, CommitAttempt commitAttempt, Consumer<Hash> newKeyLists) throws ReferenceNotFoundException, ReferenceConflictException {
    List<String> mismatches = new ArrayList<>();
    Callable<Void> validator = commitAttempt.getValidator();
    if (validator != null) {
        try {
            validator.call();
        } catch (RuntimeException e) {
            // just propagate the RuntimeException up
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    // verify expected global-states
    checkExpectedGlobalStates(ctx, commitAttempt, mismatches::add);
    checkForModifiedKeysBetweenExpectedAndCurrentCommit(ctx, commitAttempt, branchHead, mismatches);
    if (!mismatches.isEmpty()) {
        throw new ReferenceConflictException(String.join("\n", mismatches));
    }
    CommitLogEntry currentBranchEntry = fetchFromCommitLog(ctx, branchHead);
    int parentsPerCommit = config.getParentsPerCommit();
    List<Hash> newParents = new ArrayList<>(parentsPerCommit);
    newParents.add(branchHead);
    long commitSeq;
    if (currentBranchEntry != null) {
        List<Hash> p = currentBranchEntry.getParents();
        newParents.addAll(p.subList(0, Math.min(p.size(), parentsPerCommit - 1)));
        commitSeq = currentBranchEntry.getCommitSeq() + 1;
    } else {
        commitSeq = 1;
    }
    CommitLogEntry newBranchCommit = buildIndividualCommit(ctx, timeInMicros, newParents, commitSeq, commitAttempt.getCommitMetaSerialized(), commitAttempt.getPuts(), commitAttempt.getDeletes(), currentBranchEntry != null ? currentBranchEntry.getKeyListDistance() : 0, newKeyLists, NO_IN_MEMORY_COMMITS);
    writeIndividualCommit(ctx, newBranchCommit);
    return newBranchCommit;
}
Also used : ReferenceConflictException(org.projectnessie.versioned.ReferenceConflictException) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) Hash(org.projectnessie.versioned.Hash) DatabaseAdapterUtil.randomHash(org.projectnessie.versioned.persist.adapter.spi.DatabaseAdapterUtil.randomHash) ReferenceConflictException(org.projectnessie.versioned.ReferenceConflictException) RefLogNotFoundException(org.projectnessie.versioned.RefLogNotFoundException) ReferenceNotFoundException(org.projectnessie.versioned.ReferenceNotFoundException) CommitLogEntry(org.projectnessie.versioned.persist.adapter.CommitLogEntry) ImmutableCommitLogEntry(org.projectnessie.versioned.persist.adapter.ImmutableCommitLogEntry)

Example 98 with Hash

use of org.projectnessie.versioned.Hash in project nessie by projectnessie.

the class PersistVersionStore method getCommits.

@Override
public Stream<Commit<METADATA, CONTENT>> getCommits(Ref ref, boolean fetchAdditionalInfo) throws ReferenceNotFoundException {
    Hash hash = refToHash(ref);
    Stream<CommitLogEntry> stream = databaseAdapter.commitLog(hash);
    BiConsumer<ImmutableCommit.Builder<METADATA, CONTENT>, CommitLogEntry> enhancer = enhancerForCommitLog(fetchAdditionalInfo);
    return stream.map(e -> {
        ImmutableCommit.Builder<METADATA, CONTENT> commit = Commit.<METADATA, CONTENT>builder().hash(e.getHash()).commitMeta(deserializeMetadata(e.getMetadata()));
        enhancer.accept(commit, e);
        return commit.build();
    });
}
Also used : ImmutableCommit(org.projectnessie.versioned.ImmutableCommit) CommitLogEntry(org.projectnessie.versioned.persist.adapter.CommitLogEntry) Hash(org.projectnessie.versioned.Hash)

Example 99 with Hash

use of org.projectnessie.versioned.Hash in project nessie by projectnessie.

the class AbstractCommitScenarios method commit.

@ParameterizedTest
@ValueSource(ints = { 1, 3, 5 })
void commit(int tablesPerCommit) throws Exception {
    BranchName branch = BranchName.of("main");
    ArrayList<Key> keys = new ArrayList<>(tablesPerCommit);
    ImmutableCommitAttempt.Builder commit = ImmutableCommitAttempt.builder().commitToBranch(branch).commitMetaSerialized(ByteString.copyFromUtf8("initial commit meta"));
    for (int i = 0; i < tablesPerCommit; i++) {
        Key key = Key.of("my", "table", "num" + i);
        keys.add(key);
        String cid = "id-" + i;
        WithGlobalStateContent c = WithGlobalStateContent.withGlobal("0", "initial commit content", cid);
        commit.addPuts(KeyWithBytes.of(key, ContentId.of(cid), SimpleStoreWorker.INSTANCE.getPayload(c), SimpleStoreWorker.INSTANCE.toStoreOnReferenceState(c))).putGlobal(ContentId.of(cid), SimpleStoreWorker.INSTANCE.toStoreGlobalState(c)).putExpectedStates(ContentId.of(cid), Optional.empty());
    }
    Hash head = databaseAdapter.commit(commit.build());
    for (int commitNum = 0; commitNum < 3; commitNum++) {
        Map<Key, ContentAndState<ByteString>> values = databaseAdapter.values(databaseAdapter.hashOnReference(branch, Optional.empty()), keys, KeyFilterPredicate.ALLOW_ALL);
        commit = ImmutableCommitAttempt.builder().commitToBranch(branch).commitMetaSerialized(ByteString.copyFromUtf8("initial commit meta"));
        for (int i = 0; i < tablesPerCommit; i++) {
            String currentState = values.get(keys.get(i)).getGlobalState().toStringUtf8();
            String newGlobalState = Integer.toString(Integer.parseInt(currentState) + 1);
            String cid = "id-" + i;
            WithGlobalStateContent newContent = WithGlobalStateContent.withGlobal(newGlobalState, "branch value", cid);
            WithGlobalStateContent expectedContent = WithGlobalStateContent.withGlobal(currentState, currentState, cid);
            commit.addPuts(KeyWithBytes.of(keys.get(i), ContentId.of(cid), SimpleStoreWorker.INSTANCE.getPayload(newContent), SimpleStoreWorker.INSTANCE.toStoreOnReferenceState(newContent))).putGlobal(ContentId.of(cid), SimpleStoreWorker.INSTANCE.toStoreGlobalState(newContent)).putExpectedStates(ContentId.of(cid), Optional.of(SimpleStoreWorker.INSTANCE.toStoreGlobalState(expectedContent)));
        }
        Hash newHead = databaseAdapter.commit(commit.build());
        assertThat(newHead).isNotEqualTo(head);
        head = newHead;
    }
}
Also used : ImmutableCommitAttempt(org.projectnessie.versioned.persist.adapter.ImmutableCommitAttempt) ContentAndState(org.projectnessie.versioned.persist.adapter.ContentAndState) ArrayList(java.util.ArrayList) BranchName(org.projectnessie.versioned.BranchName) ByteString(com.google.protobuf.ByteString) Hash(org.projectnessie.versioned.Hash) Key(org.projectnessie.versioned.Key) WithGlobalStateContent(org.projectnessie.versioned.testworker.WithGlobalStateContent) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

Hash (org.projectnessie.versioned.Hash)99 BranchName (org.projectnessie.versioned.BranchName)49 DatabaseAdapterUtil.randomHash (org.projectnessie.versioned.persist.adapter.spi.DatabaseAdapterUtil.randomHash)44 ReferenceConflictException (org.projectnessie.versioned.ReferenceConflictException)36 Test (org.junit.jupiter.api.Test)33 DatabaseAdapterUtil.verifyExpectedHash (org.projectnessie.versioned.persist.adapter.spi.DatabaseAdapterUtil.verifyExpectedHash)30 ByteString (com.google.protobuf.ByteString)28 ReferenceNotFoundException (org.projectnessie.versioned.ReferenceNotFoundException)27 Key (org.projectnessie.versioned.Key)25 CommitLogEntry (org.projectnessie.versioned.persist.adapter.CommitLogEntry)23 ArrayList (java.util.ArrayList)20 RefLogNotFoundException (org.projectnessie.versioned.RefLogNotFoundException)20 Stream (java.util.stream.Stream)19 Collectors (java.util.stream.Collectors)17 TagName (org.projectnessie.versioned.TagName)17 HashMap (java.util.HashMap)16 Optional (java.util.Optional)16 ReferenceAlreadyExistsException (org.projectnessie.versioned.ReferenceAlreadyExistsException)16 ReferenceInfo (org.projectnessie.versioned.ReferenceInfo)16 Collections (java.util.Collections)15