This document summarizes the enhancements made to the Aerospike Fluent Client Java library's Complex Data Type (CDT) operations, specifically adding support for relative range operations on maps and fixing a typo in an existing method.
- Files Modified: 3
- Lines Added: 291
- Lines Removed: 1
src/main/java/com/aerospike/CdtGetOrRemoveBuilder.java(+176 lines)src/main/java/com/aerospike/BinBuilder.java(+83 lines)src/main/java/com/aerospike/CdtOperationParams.java(+33 lines)
Fixed: Method name typo onMapKeuRange → onMapKeyRange
/**
* @deprecated Typo in method name. Use {@link #onMapKeyRange(long, long)} instead.
*/
@Deprecated
public CdtContextInvertableBuilder onMapKeuRange(long startIncl, long endExcl) {
return onMapKeyRange(startIncl, endExcl);
}
public CdtContextInvertableBuilder onMapKeyRange(long startIncl, long endExcl) {
params.pushCurrentToContextAndReplaceWith(CdtOperation.MAP_BY_KEY_RANGE,
Value.get(startIncl), Value.get(endExcl));
return this;
}Backward Compatibility: The old method is retained but marked as @Deprecated to maintain backward compatibility.
Added 12 new navigation methods for relative range operations:
1. Map Key Relative Index Range (3 overloads without count):
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(long key, int index)
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(String key, int index)
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(byte[] key, int index)2. Map Key Relative Index Range with Count (3 overloads):
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(long key, int index, int count)
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(String key, int index, int count)
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(byte[] key, int index, int count)3. Map Value Relative Rank Range (3 overloads without count):
public CdtActionInvertableBuilder onMapValueRelativeRankRange(long value, int rank)
public CdtActionInvertableBuilder onMapValueRelativeRankRange(String value, int rank)
public CdtActionInvertableBuilder onMapValueRelativeRankRange(byte[] value, int rank)4. Map Value Relative Rank Range with Count (3 overloads):
public CdtActionInvertableBuilder onMapValueRelativeRankRange(long value, int rank, int count)
public CdtActionInvertableBuilder onMapValueRelativeRankRange(String value, int rank, int count)
public CdtActionInvertableBuilder onMapValueRelativeRankRange(byte[] value, int rank, int count)Updated 6 action methods to handle the new relative range operations:
-
getValues()- Added cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
-
getKeys()- Added cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
-
count()- Added cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
-
countAllOthers()- Added inverted cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
-
remove()- Added removal cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
-
removeAllOthers()- Added inverted removal cases for:MAP_BY_KEY_REL_INDEX_RANGEMAP_BY_VALUE_REL_RANK_RANGE- Both with and without count parameter
Example Implementation Pattern:
case MAP_BY_KEY_REL_INDEX_RANGE:
if (params.hasInt2()) {
return opBuilder.addOp(MapOperation.getByKeyRelativeIndexRange(
binName, params.getVal1(), params.getInt1(), params.getInt2(),
MapReturnType.VALUE, params.context()));
} else {
return opBuilder.addOp(MapOperation.getByKeyRelativeIndexRange(
binName, params.getVal1(), params.getInt1(),
MapReturnType.VALUE, params.context()));
}Added 12 navigation methods that mirror the CdtGetOrRemoveBuilder changes. These methods create new CdtGetOrRemoveBuilder instances with the appropriate operation parameters.
Pattern:
public CdtActionInvertableBuilder onMapKeyRelativeIndexRange(long key, int index) {
return new CdtGetOrRemoveBuilder(binName, opBuilder,
new CdtOperationParams(CdtOperation.MAP_BY_KEY_REL_INDEX_RANGE,
Value.get(key), index));
}All 12 overloads follow the same structure as in CdtGetOrRemoveBuilder.java, ensuring consistency across the API.
Added 2 new constructors to support relative range operations:
public CdtOperationParams(CdtOperation operation, Value val1, int int1) {
this.val1 = val1;
this.int1 = int1;
this.operation = operation;
}
public CdtOperationParams(CdtOperation operation, Value val1, int int1, int int2) {
this.val1 = val1;
this.int1 = int1;
this.int2 = int2;
this.operation = operation;
}Added 3 new helper methods:
public void pushCurrentToContextAndReplaceWith(CdtOperation operation, Value val1, int int1) {
pushCurrentToContext();
this.operation = operation;
this.val1 = val1;
this.int1 = int1;
}
public void pushCurrentToContextAndReplaceWith(CdtOperation operation, Value val1,
int int1, int int2) {
pushCurrentToContext();
this.operation = operation;
this.val1 = val1;
this.int1 = int1;
this.int2 = int2;
}
public boolean hasInt2() {
return this.int2 != 0;
}The CdtOperation enum already contained the necessary values:
protected static enum CdtOperation {
// ... other operations ...
MAP_BY_KEY_REL_INDEX_RANGE, // Used for key relative index range operations
MAP_BY_VALUE_REL_RANK_RANGE, // Used for value relative rank range operations
// ... other operations ...
}session.upsert(dataSet.id("user123"))
.bin("scores")
.onMapKeyRelativeIndexRange("math", 2) // Start at "math" key, offset by 2
.getValues()
.execute();session.upsert(dataSet.id("user123"))
.bin("scores")
.onMapKeyRelativeIndexRange("math", 2, 5) // Get 5 items starting at offset 2
.getValues()
.execute();session.upsert(dataSet.id("user123"))
.bin("scores")
.onMapValueRelativeRankRange(75L, 3) // Start at value 75, offset by rank 3
.getValues()
.execute();session.upsert(dataSet.id("user123"))
.bin("scores")
.onMapKeyRelativeIndexRange("math", 2, 5)
.countAllOthers() // Count all items NOT in the range
.execute();session.upsert(dataSet.id("user123"))
.bin("scores")
.onMapValueRelativeRankRange(50L, 0, 10) // Remove 10 lowest scores >= 50
.remove()
.execute();All changes follow the established fluent API patterns:
- Method Chaining: All navigation methods return builder interfaces for continued chaining
- Type Overloading: Support for
long,String, andbyte[]parameter types - Invertable Operations: Return
CdtActionInvertableBuilderto enable inverted operations - Consistent Naming: Follow the
on<Type><Criteria>pattern - Javadoc Documentation: All new methods include comprehensive Javadoc comments
- Backward Compatibility: Deprecated old method instead of removing it
The following scenarios should be tested:
-
Relative Index Range Operations:
- Without count parameter (unbounded range)
- With count parameter (bounded range)
- With different key types (long, String, byte[])
-
Relative Rank Range Operations:
- Without count parameter (unbounded range)
- With count parameter (bounded range)
- With different value types (long, String, byte[])
-
Action Method Variants:
getValues()- Retrieve values in rangegetKeys()- Retrieve keys in rangecount()- Count items in rangecountAllOthers()- Count items NOT in rangeremove()- Remove items in rangeremoveAllOthers()- Remove items NOT in range
-
Nested Context Operations:
- Using relative range operations within nested map/list contexts
- Chaining multiple context navigations
-
Edge Cases:
- Empty maps
- Single-element maps
- Negative index/rank offsets
- Count exceeding available items
✅ No compilation errors related to these changes
- All new methods compile successfully
- The pre-existing DSL-related compilation errors in the project are unrelated to these changes
If you're using onMapKeuRange:
// Old (still works but deprecated)
.bin("map").onMapKeuRange(10L, 20L).getValues()
// New (recommended)
.bin("map").onMapKeyRange(10L, 20L).getValues()// Key relative index range (new feature)
.bin("map")
.onMapKeyRelativeIndexRange("startKey", 2) // Start 2 positions after "startKey"
.getValues()
// With count limit (new feature)
.bin("map")
.onMapKeyRelativeIndexRange("startKey", 2, 5) // Get 5 items
.getValues()
// Value relative rank range (new feature)
.bin("map")
.onMapValueRelativeRankRange(100L, 3) // Start 3 ranks after value 100
.getValues()| Feature | CdtGetOrRemoveBuilder | BinBuilder | Status |
|---|---|---|---|
onMapKeyRange (fixed typo) |
✅ | N/A | Complete |
onMapKeyRelativeIndexRange (no count) |
✅ | ✅ | Complete |
onMapKeyRelativeIndexRange (with count) |
✅ | ✅ | Complete |
onMapValueRelativeRankRange (no count) |
✅ | ✅ | Complete |
onMapValueRelativeRankRange (with count) |
✅ | ✅ | Complete |
| Action method support | ✅ | N/A | Complete |
| CdtOperationParams support | ✅ | ✅ | Complete |
- Testing: Create comprehensive unit and integration tests
- Documentation: Update API documentation and user guides
- Examples: Add more usage examples to the examples package
- Release Notes: Document these changes in the next release
- DSL Integration: Ensure DSL-based queries can leverage these new operations
- Aerospike CDT Operations: https://docs.aerospike.com/docs/guide/cdt-map.html
- Original Syntax Guide:
SYNTAX_GUIDE.md - API Documentation:
API_DOCUMENTATION.md
Implementation Date: October 13, 2025 Status: ✅ Complete and Ready for Testing