use of org.projectnessie.versioned.ReferenceNotFoundException in project nessie by projectnessie.
the class NonTransactionalDatabaseAdapter method delete.
@Override
public void delete(NamedRef reference, Optional<Hash> expectedHead) throws ReferenceNotFoundException, ReferenceConflictException {
try {
casOpLoop("deleteRef", reference, CasOpVariant.DELETE_REF, (ctx, pointer, branchCommits, newKeyLists) -> {
Hash branchHead = branchHead(pointer, reference);
verifyExpectedHash(branchHead, reference, expectedHead);
GlobalStateLogEntry newGlobalHead = noopGlobalLogEntry(ctx, pointer);
RefLogEntry.RefType refType = reference instanceof TagName ? RefLogEntry.RefType.Tag : RefLogEntry.RefType.Branch;
RefLogEntry newRefLog = writeRefLogEntry(ctx, pointer, reference.getName(), refType, branchHead, RefLogEntry.Operation.DELETE_REFERENCE, commitTimeInMicros(), Collections.emptyList());
return updateGlobalStatePointer(reference, pointer, null, newGlobalHead, newRefLog);
}, () -> deleteConflictMessage("Retry-Failure", reference, expectedHead));
} catch (ReferenceNotFoundException | ReferenceConflictException | RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.projectnessie.versioned.ReferenceNotFoundException in project nessie by projectnessie.
the class AbstractDatabaseAdapter method mergeAttempt.
/**
* Logic implementation of a merge-attempt.
*
* @param ctx technical operation context
* @param from merge-from commit
* @param toBranch merge-into reference with expected hash of HEAD
* @param expectedHead if present, {@code toBranch}'s current HEAD must be equal to this value
* @param toHead current HEAD of {@code toBranch}
* @param branchCommits consumer for the individual commits to merge
* @param newKeyLists consumer for optimistically written {@link KeyListEntity}s
* @param rewriteMetadata function to rewrite the commit-metadata for copied commits
* @return hash of the last commit-log-entry written to {@code toBranch}
*/
protected Hash mergeAttempt(OP_CONTEXT ctx, long timeInMicros, Hash from, BranchName toBranch, Optional<Hash> expectedHead, Hash toHead, Consumer<Hash> branchCommits, Consumer<Hash> newKeyLists, Function<ByteString, ByteString> rewriteMetadata) throws ReferenceNotFoundException, ReferenceConflictException {
validateHashExists(ctx, from);
// 1. ensure 'expectedHash' is a parent of HEAD-of-'toBranch'
hashOnRef(ctx, toBranch, expectedHead, toHead);
// 2. find nearest common-ancestor between 'from' + 'fromHash'
Hash commonAncestor = findCommonAncestor(ctx, from, toBranch, toHead);
// 3. Collect commit-log-entries
List<CommitLogEntry> toEntriesReverseChronological = takeUntilExcludeLast(readCommitLogStream(ctx, toHead), e -> e.getHash().equals(commonAncestor)).collect(Collectors.toList());
Collections.reverse(toEntriesReverseChronological);
List<CommitLogEntry> commitsToMergeChronological = takeUntilExcludeLast(readCommitLogStream(ctx, from), e -> e.getHash().equals(commonAncestor)).collect(Collectors.toList());
if (commitsToMergeChronological.isEmpty()) {
// Nothing to merge, shortcut
throw new IllegalArgumentException(String.format("No hashes to merge from '%s' onto '%s' @ '%s'.", from.asString(), toBranch.getName(), toHead));
}
// 4. Collect modified keys.
Set<Key> keysTouchedOnTarget = collectModifiedKeys(toEntriesReverseChronological);
// 5. check for key-collisions
checkForKeyCollisions(ctx, toHead, keysTouchedOnTarget, commitsToMergeChronological);
// (no need to verify the global states during a transplant)
// 6. re-apply commits in 'sequenceToTransplant' onto 'targetBranch'
toHead = copyCommits(ctx, timeInMicros, toHead, commitsToMergeChronological, newKeyLists, rewriteMetadata);
// 7. Write commits
commitsToMergeChronological.stream().map(CommitLogEntry::getHash).forEach(branchCommits);
writeMultipleCommits(ctx, commitsToMergeChronological);
return toHead;
}
use of org.projectnessie.versioned.ReferenceNotFoundException 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;
}
Aggregations