forked from projectnessie/nessie
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Rocks condition with update #22
Open
stevelorddremio
wants to merge
89
commits into
rocks-condition-expr-rebase
Choose a base branch
from
rocks-condition-with-update
base: rocks-condition-expr-rebase
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
89 commits
Select commit
Hold shift + click to select a range
82faa37
rebase on main
stevelorddremio e241645
Rocks checkstyle
stevelorddremio 451dc1d
Rocks PR updates. Correct AbstractTestStore put test for failing cond…
stevelorddremio bf5ba27
Rocks PR updates. Revert mongodb changes.
stevelorddremio 2e2ca1c
RocksDB Ext PR updates
stevelorddremio 6760853
RocksDB ext PR updates
stevelorddremio 830a5b6
Rocks ext PR updates
stevelorddremio a85e2e3
Rocks update - initial skeleton
stevelorddremio eb77566
Rocks update add update visitor and start implementing update on L1
stevelorddremio 3c59809
Rocks update
stevelorddremio e4da222
Rocks UpdateExpression SetClause test
stevelorddremio 96d9ff4
Rocks Update L1 Id Set and Remove tests
stevelorddremio d66113c
Rocks update() consolidate tests
stevelorddremio a39be60
Rocks Update() consolidate tests
stevelorddremio 70d94ed
RocksDB update() streams initial handling.
stevelorddremio b62cb30
RocksDB Revert Function back to be used purely for ConditionExpressio…
stevelorddremio 6369e55
Rocks rebase
stevelorddremio 93e10de
Rocks update for L1 children, ancestors and complete key list
stevelorddremio b2a50ea
Fixed up some compile issues.
991541f
Refactored and further implemented update for RocksL1.
fe1ca73
Refactored the update unit tests.
195cb03
Implemented update for RocksL2.
95c3b78
Implemented update for RocksL3.
2235baf
Partially mplemented update for RocksFragment.
f687c6c
Partially implemented update for RocksRef. Some code cleanup.
b50ee84
Implemented update for RocksValue and RocksWrappedValue.
35faf80
Implemented update for RocksCommitMetadata.
a0ec3f1
Reworked the logic for update. Now simpler operations are pushed down…
acfa4b5
Now the path is passed down to the update operations in the child cla…
7383a99
Fixed up checkstyle errors.
1897dd3
Rocks add missing AddClause visitor handling.
stevelorddremio 9f03244
Implemented update for key mutations in RocksL1.
3da86a5
Fixed up issues when processing multiple update functions. Added unit…
a4c15a4
Implemented update for RocksDBStore. Implemented update operations fo…
14183e1
Updated based on PR feedback.
174cb9e
Corrected the wording of a comment.
f89c15b
Ensure that the minimum entities are created.
75c3552
Updated the field names to match what Dynamo is using.
97682b0
Fixed some compile errors.
4ee03d0
Changed the builder names back to what they used to be for the update…
b65deae
Rocks update add update visitor and start implementing update on L1
stevelorddremio b82bb9a
RocksDB Revert Function back to be used purely for ConditionExpressio…
stevelorddremio ef42414
Partially implemented update for RocksRef. Some code cleanup.
cba4685
Implemented update for RocksCommitMetadata.
0413574
Reworked the logic for update. Now simpler operations are pushed down…
ac180df
Now the path is passed down to the update operations in the child cla…
ade4e47
Fixed up checkstyle errors.
daa2224
Updated based on PR feedback.
8fde5f2
Updated the field names to match what Dynamo is using.
d7c5f61
Rocks add update handling for branch.commits id, commit and parent at…
stevelorddremio 861038b
RocksDB Branch.commits.delta remove, set, appendToList handling added
stevelorddremio a46d15e
Rocks Branch Delta update, add tests and make them parameterized.
stevelorddremio 4355b3c
RocksDB update() for branch commits delta
stevelorddremio bdafee5
Rocks update branch commits delta implementation - update tests
stevelorddremio 1fe9354
Rocks branch.commits removal added.
stevelorddremio 0bdbbfd
Checkstyle
stevelorddremio 2859a1b
Rocks update complex types for branch.commits
stevelorddremio 4dbce25
Rocks rebase on rocks-condition-with-update
stevelorddremio 177a0c2
Added some comments to describe the structures that are stored.
9a0d9de
Updated the Javadoc comments for the Rocks entities. Added a new clas…
6a86fd6
Refactored some code to make it more readable for updates.
33d20e3
Updated to get the AbstractITTieredVersionStore tests running and pas…
dc8b996
Implemented more of remove for RocksRef. Added some Javadoc comments …
f6de458
Updated EntityConverter based on PR feedback.
38af3a5
Removed some checks that were reduntant.
d4adde7
Fixed a typo.
59df7bb
Updated PathPattern based on PR feedback.
1cdeb7c
Updated RocksBaseValue based on PR feedback.
1e698b7
Removed stream collection to a list where possible.
eab0e95
Rocks commits appendToList added
stevelorddremio d0b5d4e
Rocks add commits tests
stevelorddremio 1fdaae4
Rocks add set equals for commits
stevelorddremio c9c27d2
Rocks update() for branch.commits.delta
stevelorddremio f9c4217
Rocks branch.commits.delta and key mutations appendToList added
stevelorddremio 7289cc0
Refactored to make more extensive use of PathPattern. PathPattern now…
2123d6c
Updated the PathPattern to support prefix matching.
ccb9c42
Removed the fieldIsList() method.
fa385b6
Added final to a local variable.
2ec82e7
Updated some Javadoc comments.
a947cc2
Rocks add branch.commits.keys set-equals handling
stevelorddremio f0b903a
Rocks checkstyle
stevelorddremio b5d5e76
Merge branch 'rocks-condition-with-update' into rocks-update-branch
stevelorddremio 409ff56
Rocks refactor branch.commits set equals into new structure.
stevelorddremio ff7e849
Moved the PathPattern creation to static variables.
4714642
Rocks branch.commits.keys.key appendToList impl
stevelorddremio f2b3b1e
Merge remote-tracking branch 'origin/rocks-condition-with-update' int…
stevelorddremio 27d5731
Rocks checkstyle
stevelorddremio e2541b0
Rocks internal PR comments.
stevelorddremio 25817ca
Rocks Enable disabled tests
stevelorddremio File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
...ned/tiered/rocksdb/src/main/java/org/projectnessie/versioned/rocksdb/EntityConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* Copyright (C) 2020 Dremio | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.projectnessie.versioned.rocksdb; | ||
|
||
import java.util.Map; | ||
|
||
import org.projectnessie.versioned.store.Entity; | ||
|
||
import com.google.common.primitives.Ints; | ||
|
||
/** | ||
* Static methods to use for converting Entity objects to Rocks protobuf objects. | ||
*/ | ||
class EntityConverter { | ||
|
||
/** | ||
* This converts an Entity into Commit protobuf object. | ||
* @param entity the entity to convert | ||
* @return the object converted from the entity | ||
*/ | ||
static ValueProtos.Commit entityToCommit(Entity entity) { | ||
final ValueProtos.Commit.Builder builder = ValueProtos.Commit.newBuilder(); | ||
|
||
for (Map.Entry<String, Entity> entry : entity.getMap().entrySet()) { | ||
switch (entry.getKey()) { | ||
case RocksRef.COMMITS_ID: | ||
builder.setId(entry.getValue().getBinary()); | ||
break; | ||
case RocksRef.COMMITS_PARENT: | ||
builder.setParent(entry.getValue().getBinary()); | ||
break; | ||
case RocksRef.COMMITS_COMMIT: | ||
builder.setCommit(entry.getValue().getBinary()); | ||
break; | ||
case RocksRef.COMMITS_DELTA: | ||
entry.getValue().getList().forEach(e -> builder.addDelta(entityToDelta(e))); | ||
break; | ||
case RocksRef.COMMITS_KEY_LIST: | ||
entry.getValue().getList().forEach(e -> builder.addKeyMutation(entityToKeyMutation(e))); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(String.format("Unknown field \"%s\" for commit", entry.getKey())); | ||
} | ||
} | ||
return builder.build(); | ||
} | ||
|
||
/** | ||
* This converts an Entity into Delta protobuf object. | ||
* @param entity the entity to convert | ||
* @return the object converted from the entity | ||
*/ | ||
static ValueProtos.Delta entityToDelta(Entity entity) { | ||
final ValueProtos.Delta.Builder builder = ValueProtos.Delta.newBuilder(); | ||
|
||
for (Map.Entry<String, Entity> entry : entity.getMap().entrySet()) { | ||
switch (entry.getKey()) { | ||
case RocksRef.COMMITS_POSITION: | ||
builder.setPosition(Ints.saturatedCast(entry.getValue().getNumber())); | ||
break; | ||
case RocksRef.COMMITS_OLD_ID: | ||
builder.setOldId(entry.getValue().getBinary()); | ||
break; | ||
case RocksRef.COMMITS_NEW_ID: | ||
builder.setNewId(entry.getValue().getBinary()); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(String.format("Unknown field \"%s\" for delta", entry.getKey())); | ||
} | ||
} | ||
return builder.build(); | ||
} | ||
|
||
/** | ||
* This converts an Entity into KeyMutation protobuf object. | ||
* @param entity the entity to convert | ||
* @return the object converted from the entity | ||
*/ | ||
static ValueProtos.KeyMutation entityToKeyMutation(Entity entity) { | ||
final ValueProtos.KeyMutation.Builder builder = ValueProtos.KeyMutation.newBuilder(); | ||
|
||
for (Map.Entry<String, Entity> entry : entity.getMap().entrySet()) { | ||
switch (entry.getKey()) { | ||
case RocksRef.COMMITS_KEY_ADDITION: | ||
builder.setType(ValueProtos.KeyMutation.MutationType.ADDITION); | ||
break; | ||
case RocksRef.COMMITS_KEY_REMOVAL: | ||
builder.setType(ValueProtos.KeyMutation.MutationType.REMOVAL); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(String.format("Unknown field \"%s\" for keyMutation", entry.getKey())); | ||
} | ||
|
||
builder.setKey(entityToKey(entry.getValue())); | ||
} | ||
return builder.build(); | ||
} | ||
|
||
/** | ||
* This converts an Entity into Key protobuf object. | ||
* @param entity the entity to convert | ||
* @return the object converted from the entity | ||
*/ | ||
static ValueProtos.Key entityToKey(Entity entity) { | ||
final ValueProtos.Key.Builder keyBuilder = ValueProtos.Key.newBuilder(); | ||
entity.getList().forEach(e -> keyBuilder.addElements(e.getString())); | ||
|
||
return keyBuilder.build(); | ||
} | ||
|
||
/** | ||
* This converts an Entity into KeyDelta protobuf object. | ||
* @param entity the entity to convert | ||
* @return the object converted from the entity | ||
*/ | ||
static ValueProtos.KeyDelta entityToKeyDelta(Entity entity) { | ||
final Map<String, Entity> entityMap = entity.getMap(); | ||
final ValueProtos.KeyDelta.Builder keyDeltaBuilder = ValueProtos.KeyDelta.newBuilder(); | ||
|
||
for (Map.Entry<String, Entity> entry : entityMap.entrySet()) { | ||
switch (entry.getKey()) { | ||
case RocksL3.TREE_ID: | ||
keyDeltaBuilder.setId(entry.getValue().getBinary()); | ||
break; | ||
case RocksL3.TREE_KEY: | ||
keyDeltaBuilder.setKey(entityToKey(entry.getValue())); | ||
break; | ||
default: | ||
throw new UnsupportedOperationException(String.format("Unknown field \"%s\" for keyDelta", entry.getKey())); | ||
} | ||
} | ||
|
||
return keyDeltaBuilder.build(); | ||
} | ||
} |
207 changes: 207 additions & 0 deletions
207
versioned/tiered/rocksdb/src/main/java/org/projectnessie/versioned/rocksdb/PathPattern.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
/* | ||
* Copyright (C) 2020 Dremio | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.projectnessie.versioned.rocksdb; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.projectnessie.versioned.impl.condition.ExpressionFunction; | ||
import org.projectnessie.versioned.impl.condition.ExpressionPath; | ||
import org.projectnessie.versioned.impl.condition.ValueVisitor; | ||
import org.projectnessie.versioned.store.Entity; | ||
|
||
/** | ||
* Path patterns provide a simple way to verify that an expression path matches what is expected. All | ||
* of the path will be matched against the pattern. An expression path consists of a sequence of name | ||
* and position components. For example, you could have the path "foo[0]". This path has the following components: | ||
* <ol> | ||
* <li>foo - a name</li> | ||
* <li>[0] - an index</li> | ||
* <li>bar - a name</li> | ||
* <li>[1] - an index</li> | ||
* </ol> | ||
* Path patterns support exact matching on parts of the path, and any matching. The following patterns all | ||
* match the example path above. | ||
* <ul> | ||
* <li>PathPattern.exact().anyName().anyPosition()</li> | ||
* <li>PathPattern.exact().anyName().positionEquals(0)</li> | ||
* <li>PathPattern.exact().nameEquals("foo").anyPosition()</li> | ||
* <li>PathPattern.exact().nameEquals("foo").positionEquals(0)</li> | ||
* </ul> | ||
* After building up a path pattern, you can test a path against it with the match method. ex. | ||
* <pre> | ||
* boolean matches = PathPattern.exact().nameEquals("foo").anyPosition().nameEquals("bar").anyPosition().matches(path); | ||
* </pre> | ||
*/ | ||
class PathPattern implements ValueVisitor<Boolean> { | ||
private final MatchType matchType; | ||
private final List<java.util.function.Function<ExpressionPath.PathSegment, Boolean>> pathPatternElements = new ArrayList<>(); | ||
|
||
enum MatchType { | ||
EXACT, | ||
PREFIX | ||
} | ||
|
||
private PathPattern(MatchType matchType) { | ||
this.matchType = matchType; | ||
} | ||
|
||
/** | ||
* Create a new exact match pattern starting with a provided name. | ||
* @param name the name the pattern starts with | ||
* @return the new PathPattern | ||
*/ | ||
static PathPattern exact(String name) { | ||
return new PathPattern(MatchType.EXACT).nameEquals(name); | ||
} | ||
|
||
/** | ||
* Create a new exact match pattern starting with a provided position. | ||
* @param position the position the pattern starts with | ||
* @return the new PathPattern | ||
*/ | ||
static PathPattern exact(int position) { | ||
return new PathPattern(MatchType.EXACT).positionEquals(position); | ||
} | ||
|
||
/** | ||
* Create a new prefix match pattern starting with a provided name. | ||
* @param name the name the pattern starts with | ||
* @return the new PathPattern | ||
*/ | ||
static PathPattern prefix(String name) { | ||
return new PathPattern(MatchType.PREFIX).nameEquals(name); | ||
} | ||
|
||
/** | ||
* Create a new prefix match pattern starting with a provided position. | ||
* @param position the position the pattern starts with | ||
* @return the new PathPattern | ||
*/ | ||
static PathPattern prefix(int position) { | ||
return new PathPattern(MatchType.PREFIX).positionEquals(position); | ||
} | ||
|
||
/** | ||
* Adds an exact name match path component. | ||
* @param name the name to match against | ||
* @return the object the pattern component is added to | ||
*/ | ||
PathPattern nameEquals(String name) { | ||
pathPatternElements.add((p) -> p.isName() && name.equals(p.asName().getName())); | ||
return this; | ||
} | ||
|
||
/** | ||
* Adds an any name match path component. | ||
* @return the object the pattern component is added to | ||
*/ | ||
PathPattern anyName() { | ||
pathPatternElements.add(ExpressionPath.PathSegment::isName); | ||
return this; | ||
} | ||
|
||
/** | ||
* Adds an exact position match component. | ||
* @param position the position to match against | ||
* @return the object the pattern component is added to | ||
*/ | ||
PathPattern positionEquals(int position) { | ||
pathPatternElements.add((p) -> p.isPosition() && position == p.asPosition().getPosition()); | ||
return this; | ||
} | ||
|
||
/** | ||
* Adds an any position match path component. | ||
* @return the object the pattern component is added to | ||
*/ | ||
PathPattern anyPosition() { | ||
pathPatternElements.add(ExpressionPath.PathSegment::isPosition); | ||
return this; | ||
} | ||
|
||
/** | ||
* Not supported. | ||
* @param entity the Entity to visit. | ||
* @return throws an UnsupportedOperationException | ||
*/ | ||
@Override | ||
public Boolean visit(Entity entity) { | ||
throw new UnsupportedOperationException("Entity objects are not supported by PathPattern."); | ||
} | ||
|
||
/** | ||
* Not supported. | ||
* @param value the ExpressionFunction to visit. | ||
* @return throws an UnsupportedOperationException | ||
*/ | ||
@Override | ||
public Boolean visit(ExpressionFunction value) { | ||
throw new UnsupportedOperationException("ExpressionFunction objects are not supported by PathPattern."); | ||
} | ||
|
||
/** | ||
* Tests a path to see if it matches the configured pattern. | ||
* @param path the path to test | ||
* @return true if the path matches | ||
*/ | ||
@Override | ||
public Boolean visit(ExpressionPath path) { | ||
ExpressionPath.PathSegment currentNode = path.getRoot(); | ||
|
||
for (java.util.function.Function<ExpressionPath.PathSegment, Boolean> pathPatternElement : pathPatternElements) { | ||
if (currentNode == null || !pathPatternElement.apply(currentNode)) { | ||
return false; | ||
} | ||
|
||
currentNode = currentNode.getChild().orElse(null); | ||
} | ||
|
||
return matchType == MatchType.PREFIX || currentNode == null; | ||
} | ||
|
||
ExpressionPath removePrefix(ExpressionPath path) { | ||
ExpressionPath.PathSegment currentNode = path.getRoot(); | ||
|
||
for (java.util.function.Function<ExpressionPath.PathSegment, Boolean> pathPatternElement : pathPatternElements) { | ||
if (currentNode == null || !pathPatternElement.apply(currentNode)) { | ||
return path; | ||
} | ||
|
||
currentNode = currentNode.getChild().orElse(null); | ||
} | ||
|
||
if (currentNode != null && currentNode.isName()) { | ||
ExpressionPath.PathSegment.Builder pathBuilder = ExpressionPath.builder(currentNode.asName().getName()); | ||
currentNode = currentNode.getChild().orElse(null); | ||
|
||
while (currentNode != null) { | ||
if (currentNode.isName()) { | ||
pathBuilder = pathBuilder.name(currentNode.asName().getName()); | ||
} else { | ||
pathBuilder = pathBuilder.position(currentNode.asPosition().getPosition()); | ||
} | ||
|
||
currentNode = currentNode.getChild().orElse(null); | ||
} | ||
|
||
return pathBuilder.build(); | ||
} else { | ||
return null; | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this the only exception which has an error message in this class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added messages to the other exceptions.