_LIBRADOS_OP_FLAG_FADVISE_NOCACHE "LIBRADOS_OP_FLAG_FADVISE_NOCACHE"
+ enum:
+ _LIBRADOS_CMPXATTR_OP_EQ "LIBRADOS_CMPXATTR_OP_EQ"
+ _LIBRADOS_CMPXATTR_OP_NE "LIBRADOS_CMPXATTR_OP_NE"
+ _LIBRADOS_CMPXATTR_OP_GT "LIBRADOS_CMPXATTR_OP_GT"
+ _LIBRADOS_CMPXATTR_OP_GTE "LIBRADOS_CMPXATTR_OP_GTE"
+ _LIBRADOS_CMPXATTR_OP_LT "LIBRADOS_CMPXATTR_OP_LT"
+ _LIBRADOS_CMPXATTR_OP_LTE "LIBRADOS_CMPXATTR_OP_LTE"
+
enum:
_LIBRADOS_OPERATION_NOFLAG "LIBRADOS_OPERATION_NOFLAG"
_LIBRADOS_OPERATION_BALANCE_READS "LIBRADOS_OPERATION_BALANCE_READS"
int rados_write_op_operate(rados_write_op_t write_op, rados_ioctx_t io, const char * oid, time_t * mtime, int flags)
int rados_aio_write_op_operate(rados_write_op_t write_op, rados_ioctx_t io, rados_completion_t completion, const char *oid, time_t *mtime, int flags)
void rados_write_op_cmpext(rados_write_op_t write_op, const char *cmp_buf, size_t cmp_len, uint64_t off, int *prval)
+ void rados_write_op_omap_cmp(rados_write_op_t write_op, const char *key, uint8_t comparison_operator, const char *val, size_t val_len, int *prval)
void rados_write_op_omap_set(rados_write_op_t write_op, const char * const* keys, const char * const* vals, const size_t * lens, size_t num)
void rados_write_op_omap_rm_keys(rados_write_op_t write_op, const char * const* keys, size_t keys_len)
void rados_write_op_omap_clear(rados_write_op_t write_op)
_LIBRADOS_OP_FLAG_FADVISE_NOCACHE "LIBRADOS_OP_FLAG_FADVISE_NOCACHE"
+ enum:
+ _LIBRADOS_CMPXATTR_OP_EQ "LIBRADOS_CMPXATTR_OP_EQ"
+ _LIBRADOS_CMPXATTR_OP_NE "LIBRADOS_CMPXATTR_OP_NE"
+ _LIBRADOS_CMPXATTR_OP_GT "LIBRADOS_CMPXATTR_OP_GT"
+ _LIBRADOS_CMPXATTR_OP_GTE "LIBRADOS_CMPXATTR_OP_GTE"
+ _LIBRADOS_CMPXATTR_OP_LT "LIBRADOS_CMPXATTR_OP_LT"
+ _LIBRADOS_CMPXATTR_OP_LTE "LIBRADOS_CMPXATTR_OP_LTE"
+
+
enum:
_LIBRADOS_OPERATION_NOFLAG "LIBRADOS_OPERATION_NOFLAG"
_LIBRADOS_OPERATION_BALANCE_READS "LIBRADOS_OPERATION_BALANCE_READS"
pass
void rados_write_op_cmpext(rados_write_op_t write_op, const char *cmp_buf, size_t cmp_len, uint64_t off, int *prval):
pass
+ void rados_write_op_omap_cmp(rados_write_op_t write_op, const char *key, uint8_t comparison_operator, const char *val, size_t val_len, int *prval):
+ pass
void rados_write_op_omap_set(rados_write_op_t write_op, const char * const* keys, const char * const* vals, const size_t * lens, size_t num):
pass
void rados_write_op_omap_rm_keys(rados_write_op_t write_op, const char * const* keys, size_t keys_len):
LIBRADOS_OP_FLAG_FADVISE_DONTNEED = _LIBRADOS_OP_FLAG_FADVISE_DONTNEED
LIBRADOS_OP_FLAG_FADVISE_NOCACHE = _LIBRADOS_OP_FLAG_FADVISE_NOCACHE
+LIBRADOS_CMPXATTR_OP_EQ = _LIBRADOS_CMPXATTR_OP_EQ
+LIBRADOS_CMPXATTR_OP_NE = _LIBRADOS_CMPXATTR_OP_NE
+LIBRADOS_CMPXATTR_OP_GT = _LIBRADOS_CMPXATTR_OP_GT
+LIBRADOS_CMPXATTR_OP_GTE = _LIBRADOS_CMPXATTR_OP_GTE
+LIBRADOS_CMPXATTR_OP_LT = _LIBRADOS_CMPXATTR_OP_LT
+LIBRADOS_CMPXATTR_OP_LTE = _LIBRADOS_CMPXATTR_OP_LTE
+
LIBRADOS_SNAP_HEAD = _LIBRADOS_SNAP_HEAD
LIBRADOS_OPERATION_NOFLAG = _LIBRADOS_OPERATION_NOFLAG
with nogil:
rados_write_op_cmpext(self.write_op, _cmp_buf, _cmp_buf_len, _offset, NULL)
+ def omap_cmp(self, key: str, val: str, cmp_op: int = LIBRADOS_CMPXATTR_OP_EQ):
+ """
+ Ensure that an omap key value satisfies comparison
+ :param key: omap key whose associated value is evaluated for comparison
+ :param val: value to compare with
+ :param cmp_op: comparison operator, one of LIBRADOS_CMPXATTR_OP_EQ (1),
+ LIBRADOS_CMPXATTR_OP_GT (3), or LIBRADOS_CMPXATTR_OP_LT (5).
+ """
+ key_raw = cstr(key, 'key')
+ val_raw = cstr(val, 'val')
+ cdef:
+ char *_key = key_raw
+ char *_val = val_raw
+ size_t _val_len = len(val)
+ uint8_t _comparison_operator = cmp_op
+ with nogil:
+ rados_write_op_omap_cmp(self.write_op, _key, _comparison_operator, _val, _val_len, NULL)
+
class WriteOpCtx(WriteOp, OpCtx):
"""write operation context manager"""
from rados import (Rados, Error, RadosStateError, Object, ObjectExists,
ObjectNotFound, ObjectBusy, NotConnected,
LIBRADOS_ALL_NSPACES, WriteOpCtx, ReadOpCtx, LIBRADOS_CREATE_EXCLUSIVE,
+ LIBRADOS_CMPXATTR_OP_EQ, LIBRADOS_CMPXATTR_OP_GT, LIBRADOS_CMPXATTR_OP_LT, OSError,
LIBRADOS_SNAP_HEAD, LIBRADOS_OPERATION_BALANCE_READS, LIBRADOS_OPERATION_SKIPRWLOCKS, MonitorLog, MAX_ERRNO, NoData, ExtendMismatch)
from datetime import timedelta
import time
self.ioctx.operate_read_op(read_op, "test_obj")
eq(list(iter), [("4", b"dddd")])
+ def test_omap_cmp(self):
+ object_id = 'test'
+ self.ioctx.write(object_id, b'omap_cmp')
+ with WriteOpCtx() as write_op:
+ self.ioctx.set_omap(write_op, ('key1',), ('1',))
+ self.ioctx.operate_write_op(write_op, object_id)
+ with WriteOpCtx() as write_op:
+ write_op.omap_cmp('key1', '1', LIBRADOS_CMPXATTR_OP_EQ)
+ self.ioctx.set_omap(write_op, ('key1',), ('2',))
+ self.ioctx.operate_write_op(write_op, object_id)
+ with ReadOpCtx() as read_op:
+ iter, ret = self.ioctx.get_omap_vals_by_keys(read_op, ('key1',))
+ eq(ret, 0)
+ self.ioctx.operate_read_op(read_op, object_id)
+ eq(list(iter), [('key1', b'2')])
+ with WriteOpCtx() as write_op:
+ write_op.omap_cmp('key1', '1', LIBRADOS_CMPXATTR_OP_GT)
+ self.ioctx.set_omap(write_op, ('key1',), ('3',))
+ self.ioctx.operate_write_op(write_op, object_id)
+ with ReadOpCtx() as read_op:
+ iter, ret = self.ioctx.get_omap_vals_by_keys(read_op, ('key1',))
+ eq(ret, 0)
+ self.ioctx.operate_read_op(read_op, object_id)
+ eq(list(iter), [('key1', b'3')])
+ with WriteOpCtx() as write_op:
+ write_op.omap_cmp('key1', '4', LIBRADOS_CMPXATTR_OP_LT)
+ self.ioctx.set_omap(write_op, ('key1',), ('4',))
+ self.ioctx.operate_write_op(write_op, object_id)
+ with ReadOpCtx() as read_op:
+ iter, ret = self.ioctx.get_omap_vals_by_keys(read_op, ('key1',))
+ eq(ret, 0)
+ self.ioctx.operate_read_op(read_op, object_id)
+ eq(list(iter), [('key1', b'4')])
+ with WriteOpCtx() as write_op:
+ write_op.omap_cmp('key1', '1', LIBRADOS_CMPXATTR_OP_EQ)
+ self.ioctx.set_omap(write_op, ('key1',), ('5',))
+ try:
+ self.ioctx.operate_write_op(write_op, object_id)
+ except (OSError, ExtendMismatch) as e:
+ eq(e.errno, 125)
+ else:
+ message = "omap_cmp did not raise Exception when omap content does not match"
+ raise AssertionError(message)
+
def test_cmpext_op(self):
object_id = 'test'
with WriteOpCtx() as write_op: