Skip to content

Commit

Permalink
CLIENT-2626 Support persistent map indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
shannonklaus authored Nov 2, 2023
1 parent 4b23ec5 commit 47b6181
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
48 changes: 43 additions & 5 deletions AerospikeClient/CDT/MapOperation.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 Aerospike, Inc.
* Copyright 2012-2023 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements.
Expand All @@ -14,9 +14,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
using System;
using System.Collections;
using System.Collections.Generic;

namespace Aerospike.Client
{
Expand Down Expand Up @@ -113,7 +111,8 @@ public static Operation Create(string binName, MapOrder order, params CTX[] ctx)
// If context not defined, the set order for top-level bin map.
if (ctx == null || ctx.Length == 0)
{
return SetMapPolicy(new MapPolicy(order, MapWriteMode.UPDATE), binName);
byte[] bytes = PackUtil.Pack(MapOperation.SET_TYPE, (int)order, ctx);
return new Operation(Operation.Type.MAP_MODIFY, binName, Value.Get(bytes));
}

Packer packer = new Packer();
Expand All @@ -122,6 +121,38 @@ public static Operation Create(string binName, MapOrder order, params CTX[] ctx)
return new Operation(Operation.Type.MAP_MODIFY, binName, Value.Get(packer.ToByteArray()));
}

/// <summary>
/// Create map create operation.
/// Server creates map at given context level.
/// </summary>
/// <param name="binName">bin name</param>
/// <param name="order">map order</param>
/// <param name="persistIndex">if true, persist map index. A map index improves lookup performance,
/// but requires more storage.A map index can be created for a top-level
/// ordered map only. Nested and unordered map indexes are not supported.</param>
/// <param name="ctx">optional path to nested map. If not defined, the top-level map is used</param>
public static Operation Create(string binName, MapOrder order, bool persistIndex, params CTX[] ctx)
{
// If context not defined, the set order for top-level bin map.
if (ctx == null || ctx.Length == 0)
{
int attr = (int)order;

if (persistIndex)
{
attr |= 0x10;
}
byte[] bytes = PackUtil.Pack(MapOperation.SET_TYPE, attr, ctx);
return new Operation(Operation.Type.MAP_MODIFY, binName, Value.Get(bytes));
}

// Create nested map. persistIndex does not apply here, so ignore it
Packer packer = new Packer();
CDT.Init(packer, ctx, SET_TYPE, 1, CTX.GetFlag(order));
packer.PackNumber((int)order);
return new Operation(Operation.Type.MAP_MODIFY, binName, Value.Get(packer.ToByteArray()));
}

/// <summary>
/// Create set map policy operation.
/// Server sets map policy attributes. Server returns null.
Expand All @@ -131,7 +162,14 @@ public static Operation Create(string binName, MapOrder order, params CTX[] ctx)
/// </summary>
public static Operation SetMapPolicy(MapPolicy policy, string binName, params CTX[] ctx)
{
byte[] bytes = PackUtil.Pack(MapOperation.SET_TYPE, policy.attributes, ctx);
int attr = policy.attributes;

// Remove persistIndex flag for nested maps.
if (ctx != null && ctx.Length != 0 && (attr & 0x10) != 0)
{
attr &= ~0x10;
}
byte[] bytes = PackUtil.Pack(MapOperation.SET_TYPE, attr, ctx);
return new Operation(Operation.Type.MAP_MODIFY, binName, Value.Get(bytes));
}

Expand Down
28 changes: 26 additions & 2 deletions AerospikeClient/CDT/MapPolicy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2018 Aerospike, Inc.
* Copyright 2012-2023 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements.
Expand Down Expand Up @@ -77,14 +77,38 @@ public MapPolicy(MapOrder order, MapWriteMode writeMode)

/// <summary>
/// Create unique key map with specified order when map does not exist.
/// Use specified write flags when writing map items.
/// </summary>
/// <param name="order">map order</param>
/// <param name="flags">map write flags <see cref="MapWriteFlags"/></param>
public MapPolicy(MapOrder order, MapWriteFlags flags)
{
this.attributes = (int)order;
this.flags = (int)flags;
this.itemCommand = MapOperation.PUT;
this.itemsCommand = MapOperation.PUT_ITEMS;
}

/// <summary>
/// Create unique key map with specified order and persist index flag when map does not exist.
/// </summary>
/// <param name="order">map order</param>
/// <param name="flags">map write flags <see cref="MapWriteFlags"/></param>
/// <param name="persistIndex">if true, persist map index. A map index improves lookup performance,
/// but requires more storage.A map index can be created for a top-level
/// ordered map only. Nested and unordered map indexes are not supported.</param>
public MapPolicy(MapOrder order, MapWriteFlags flags, bool persistIndex)
{
int attr = (int)order;

if (persistIndex)
{
attr |= 0x10;
}

this.attributes = attr;
this.flags = (int)flags;
this.itemCommand = MapOperation.PUT;
this.itemsCommand = MapOperation.PUT_ITEMS;
}
}
}
2 changes: 1 addition & 1 deletion AerospikeTest/Sync/Basic/TestOperateMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public void OperateMapSwitch()
Assert.AreEqual(4, list.Count);

record = client.Operate(null, key,
MapOperation.SetMapPolicy(new MapPolicy(MapOrder.KEY_ORDERED, MapWriteMode.UPDATE), binName),
MapOperation.SetMapPolicy(new MapPolicy(MapOrder.KEY_ORDERED, MapWriteFlags.DEFAULT, true), binName),
MapOperation.GetByKeyRange(binName, Value.Get(3), Value.Get(5), MapReturnType.COUNT),
MapOperation.GetByKeyRange(binName, Value.Get(-5), Value.Get(2), MapReturnType.KEY_VALUE),
MapOperation.GetByIndexRange(binName, 0, 10, MapReturnType.KEY_VALUE));
Expand Down

0 comments on commit 47b6181

Please sign in to comment.