Can we do read modify write using operations API on bins of type CDT (map)?

To do read modify write on a bins having CDT (map) is to

  1. read the record
  2. get the generation number
  3. write the record with the generation came from step b. Can we do the above with operations API with one call to Aerospike (instead of making the calls twice once to read and second time to write)?

Which client language are you using?

Option 1:

If you need to avoid writing the applying the same transaction multiple times. The simplest method is to use the generation check, as you are doing.

Since you don’t need to record’s data in the initial read, you could read the meta-data only. In java you would do this by using the getHeader API.

Option 2:

To do this in one transaction, you could use a predexp on a list of integer transaction-ids that’s stored on the record. Something similar to:

predexps =  {
    predexp.integerVar("item"),
    predexp.integerValue(42),
    predexp.integerEqual(),
    predexp.listBin("txn_ids"),
    predexp.listIterateOr("item")
}

Basically each transaction would need to also generate a random “transaction id” and prepend it onto a list. This list shouldn’t be allowed to grow without bounds so you will also need to have an op to trim the list of transaction ids to a reasonable size (100 to 1000 entries depending on the rate of updates).

The client language I am looking at is Java. The CDT type I am looking at is map. Instead of doing read-modify-write, which requires two calls to Aerospike (read and write) with one operations call I want to do both.

You certainly can do this, depending on how you want to modify the map. Aerospike supports a rich set of operations through the MapOperation class which can be used in conjunction with the AerospikeClient.operate() method.

Can you please specify how you’re trying to update the map so I can judge if you can do this atomically on the server or you need to do a read-modify-write?

Hi Tim,

If a record has two bins (b0, b1). Both are having CDT type map with entries as b0 = { a : b, c : d} b1 = {e:f g:h} Now I want to write {c : d1, i : j} to b0 bin. Basically I want to overwrite some entries in the map and remove few entries in the old map and add new entries to the map. How can we do it with operate API (which is similar to read-modify-write with generation test and set)?

Hi,

You can use the operate() method, similar to:

	MapPolicy mp = new MapPolicy(MapOrder.KEY_ORDERED, 0);
	client.operate(null, key, MapOperation.put(mp, BIN_NAME, Value.get("c"), Value.get("d1")),
			MapOperation.put(mp, BIN_NAME, Value.get("j"), Value.get("j")));