diff --git a/rados/omap.go b/rados/omap.go index 9e65e15..5c78162 100644 --- a/rados/omap.go +++ b/rados/omap.go @@ -183,6 +183,42 @@ func (gos *GetOmapStep) More() bool { return gos.more != 0 } +// removeOmapKeysStep is a write operation step used to track state, especially +// C memory, across the setup and use of a WriteOp. +type removeOmapKeysStep struct { + withRefs + withoutUpdate + + // arguments: + cKeys **C.char + cNum C.size_t +} + +func newRemoveOmapKeysStep(keys []string) *removeOmapKeysStep { + cKeys := C.malloc(C.size_t(len(keys)) * ptrSize) + roks := &removeOmapKeysStep{ + cKeys: (**C.char)(cKeys), + cNum: C.size_t(len(keys)), + } + roks.add(cKeys) + + i := 0 + for _, key := range keys { + ckp := (**C.char)(unsafe.Pointer(uintptr(cKeys) + uintptr(i)*ptrSize)) + *ckp = C.CString(key) + roks.add(unsafe.Pointer(*ckp)) + i++ + } + + runtime.SetFinalizer(roks, opStepFinalizer) + return roks +} + +func (roks *removeOmapKeysStep) free() { + roks.cKeys = nil + roks.withRefs.free() +} + // SetOmap appends the map `pairs` to the omap `oid` func (ioctx *IOContext) SetOmap(oid string, pairs map[string][]byte) error { op := CreateWriteOp() @@ -276,33 +312,10 @@ func (ioctx *IOContext) GetAllOmapValues(oid string, startAfter string, filterPr // RmOmapKeys removes the specified `keys` from the omap `oid` func (ioctx *IOContext) RmOmapKeys(oid string, keys []string) error { - c_oid := C.CString(oid) - defer C.free(unsafe.Pointer(c_oid)) - - var c *C.char - ptrSize := unsafe.Sizeof(c) - - c_keys := C.malloc(C.size_t(len(keys)) * C.size_t(ptrSize)) - defer C.free(unsafe.Pointer(c_keys)) - - i := 0 - for _, key := range keys { - c_key_ptr := (**C.char)(unsafe.Pointer(uintptr(c_keys) + uintptr(i)*ptrSize)) - *c_key_ptr = C.CString(key) - defer C.free(unsafe.Pointer(*c_key_ptr)) - i++ - } - - op := C.rados_create_write_op() - C.rados_write_op_omap_rm_keys( - op, - (**C.char)(c_keys), - C.size_t(len(keys))) - - ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) - C.rados_release_write_op(op) - - return getError(ret) + op := CreateWriteOp() + defer op.Release() + op.RmOmapKeys(keys) + return op.operateCompat(ioctx, oid) } // CleanOmap clears the omap `oid` diff --git a/rados/write_op.go b/rados/write_op.go index 229aaeb..c542ec4 100644 --- a/rados/write_op.go +++ b/rados/write_op.go @@ -101,3 +101,13 @@ func (w *WriteOp) SetOmap(pairs map[string][]byte) { sos.cLengths, sos.cNum) } + +// RmOmapKeys removes the specified `keys` from the omap `oid`. +func (w *WriteOp) RmOmapKeys(keys []string) { + roks := newRemoveOmapKeysStep(keys) + w.steps = append(w.steps, roks) + C.rados_write_op_omap_rm_keys( + w.op, + roks.cKeys, + roks.cNum) +}