Knot Operations¶
Bonsai provides a comprehensive set of operations for managing Knots in the tree structure. These operations allow you to create, read, update, and delete Knots, as well as manage their properties and data.
Creating Knots¶
Create a Knot with Data¶
// Create a Knot with a string value
Knot stringKnot = bonsai.createKnot(
ValuedKnotData.builder().stringValue("Hello, World!").build(),
Map.of("description", "A simple string knot")
);
// Create a Knot with a boolean value
Knot booleanKnot = bonsai.createKnot(
ValuedKnotData.builder().booleanValue(true).build(),
Map.of("description", "A boolean knot")
);
// Create a Knot with a number value
Knot numberKnot = bonsai.createKnot(
ValuedKnotData.builder().numberValue(42.5).build(),
Map.of("description", "A number knot")
);
// Create a Knot with references to other Knots (Map)
Knot mapKnot = bonsai.createKnot(
MapKnotData.builder()
.keyMapping(Map.of(
"string", stringKnot.getId(),
"boolean", booleanKnot.getId(),
"number", numberKnot.getId()
))
.build(),
Map.of("description", "A map knot")
);
// Create a Knot with references to other Knots (List)
Knot listKnot = bonsai.createKnot(
MultiKnotData.builder()
.knotIds(List.of(stringKnot.getId(), booleanKnot.getId(), numberKnot.getId()))
.build(),
Map.of("description", "A list knot")
);
Reading Knots¶
Check if a Knot Exists¶
boolean exists = bonsai.containsKnot("knotId");
Get a Knot by ID¶
Knot knot = bonsai.getKnot("knotId");
Get Multiple Knots by IDs¶
Set<String> knotIds = Set.of("knot1", "knot2", "knot3");
Map<String, Knot> knots = bonsai.getAllKnots(knotIds);
Updating Knots¶
Update a Knot's Data¶
// Update a Knot's data
Knot oldKnot = bonsai.updateKnotData(
"knotId",
ValuedKnotData.builder().stringValue("Updated value").build(),
Map.of("description", "Updated knot", "version", knot.getVersion())
);
The updateKnotData
method returns the previous version of the Knot before the update.
Update a Knot's Properties¶
// Update a Knot's properties
Map<String, Object> newProperties = new HashMap<>(knot.getProperties());
newProperties.put("lastUpdated", System.currentTimeMillis());
newProperties.put("updatedBy", "user123");
newProperties.put("version", knot.getVersion());
Knot oldKnot = bonsai.updateKnotProperties("knotId", newProperties);
Deleting Knots¶
Delete a Knot¶
// Delete a Knot (without recursive deletion)
TreeKnot deletedTree = bonsai.deleteKnot("knotId", false);
// Delete a Knot and all its children (recursive deletion)
TreeKnot deletedTree = bonsai.deleteKnot("knotId", true);
The deleteKnot
method returns a TreeKnot
object representing the deleted subtree. This can be useful for auditing or potentially restoring the deleted structure.
Managing Variations (Edges)¶
Add a Variation to a Knot¶
// Add a Variation to a Knot
Edge edge = bonsai.addVariation("knotId", Variation.builder()
.knotId("targetKnotId")
.filters(List.of(
Filter.builder()
.path("$.user.age")
.operator(Operator.GREATER_THAN_EQUAL)
.value(18)
.build()
))
.build());
Update a Variation on a Knot¶
// Update a Variation on a Knot
Edge updatedEdge = bonsai.updateVariation("knotId", "edgeId", Variation.builder()
.knotId("newTargetKnotId")
.filters(List.of(
Filter.builder()
.path("$.user.age")
.operator(Operator.GREATER_THAN_EQUAL)
.value(21)
.build()
))
.build());
Delete a Variation from a Knot¶
// Delete a Variation (without recursive deletion)
TreeEdge deletedEdge = bonsai.deleteVariation("knotId", "edgeId", false);
// Delete a Variation and all its children (recursive deletion)
TreeEdge deletedEdge = bonsai.deleteVariation("knotId", "edgeId", true);
Unlink a Variation¶
// Unlink a Variation (remove the Edge but keep the target Knot)
bonsai.unlinkVariation("knotId", "edgeId");
Error Handling¶
Knot operations can throw various exceptions:
BonsaiError.KNOT_NOT_FOUND
: When trying to access a non-existent KnotBonsaiError.VERSION_MISMATCH
: When trying to update a Knot with an outdated versionBonsaiError.CYCLE_DETECTED
: When an operation would create a cycle in the treeBonsaiError.MAX_VARIATIONS_EXCEEDED
: When adding too many variations to a Knot
Example of handling errors:
try {
Knot knot = bonsai.getKnot("nonExistentKnotId");
} catch (BonsaiError e) {
if (e.getErrorCode() == BonsaiErrorCode.KNOT_NOT_FOUND) {
// Handle knot not found error
System.err.println("Knot not found: " + e.getMessage());
} else {
// Handle other errors
throw e;
}
}
Best Practices¶
- Use meaningful IDs or let Bonsai generate them for you
- Include descriptive properties to make Knots easier to understand and manage
- Consider versioning implications when updating Knots
- Use recursive deletion carefully, as it can remove large portions of the tree
- Handle errors appropriately to maintain tree consistency