Skip to content

Commit

Permalink
rados: implement binding for rados_write_op_cmpext
Browse files Browse the repository at this point in the history
This commit implements binding for rados_write_op_cmpext RADOS Write operation.
Includes a unit test.

Signed-off-by: Robert Vasek <[email protected]>
  • Loading branch information
gman0 committed Dec 1, 2021
1 parent 20da1c6 commit 0955c0b
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 3 deletions.
10 changes: 9 additions & 1 deletion docs/api-status.json
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,14 @@
"name": "WriteOp.WriteSame",
"comment": "WriteSame write a given byte slice to the object multiple times, until\nwriteLen is satisfied.\n\nImplements:\n void rados_write_op_writesame(rados_write_op_t write_op,\n const char *buffer,\n size_t data_len,\n size_t write_len,\n uint64_t offset);\n"
}
],
"preview_api": [
{
"name": "WriteOp.CmpExt",
"comment": "CmpExt ensures that given object range (extent) satisfies comparison.\n PREVIEW\n\nImplements:\n void rados_write_op_cmpext(rados_write_op_t write_op,\n const char * cmp_buf,\n size_t cmp_len,\n uint64_t off,\n int * prval);\n",
"added_in_version": "v0.12.0",
"expected_stable_version": "v0.14.0"
}
]
},
"rbd": {
Expand Down Expand Up @@ -1709,4 +1717,4 @@
}
]
}
}
}
10 changes: 8 additions & 2 deletions docs/api-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

## Package: rados

### Preview APIs

Name | Added in Version | Expected Stable Version |
---- | ---------------- | ----------------------- |
WriteOp.CmpExt | v0.12.0 | v0.14.0 |

## Package: rbd

### Deprecated APIs
Expand All @@ -20,10 +26,10 @@ Snapshot.Set | v0.10.0 | |

## Package: rbd/admin

### Preview APIs

## Package: rgw/admin

### Preview APIs

Name | Added in Version | Expected Stable Version |
---- | ---------------- | ----------------------- |

6 changes: 6 additions & 0 deletions internal/cutil/aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ const (

// SizeTSize is the size of C.size_t
SizeTSize = C.sizeof_size_t

// IntSize is the size of C.int
IntSize = C.sizeof_int
)

// Compile-time assertion ensuring that Go's `int` is at least as large as C's.
const _ = unsafe.Sizeof(int(0)) - unsafe.Sizeof(C.int(0))

// SizeT wraps size_t from C.
type SizeT C.size_t

Expand Down
65 changes: 65 additions & 0 deletions rados/write_op_preview.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//go:build ceph_preview
// +build ceph_preview

package rados

// #cgo LDFLAGS: -lrados
// #include <rados/librados.h>
// #include <stdlib.h>
//
import "C"

import (
"unsafe"

"github.com/ceph/go-ceph/internal/cutil"
)

// WriteOpCmpExtStep holds result of the CmpExt write operation.
// Result is valid only after Operate() was called.
type WriteOpCmpExtStep struct {
// C returned data:
prval *C.int

// Result of the CmpExt write operation.
Result int
}

func (s *WriteOpCmpExtStep) update() error {
s.Result = (int)(*s.prval)
return nil
}

func (s *WriteOpCmpExtStep) free() {
C.free(unsafe.Pointer(s.prval))
s.prval = nil
}

func newWriteOpCmpExtStep() *WriteOpCmpExtStep {
return &WriteOpCmpExtStep{
prval: (*C.int)(C.malloc(cutil.IntSize)),
}
}

// CmpExt ensures that given object range (extent) satisfies comparison.
// PREVIEW
//
// Implements:
// void rados_write_op_cmpext(rados_write_op_t write_op,
// const char * cmp_buf,
// size_t cmp_len,
// uint64_t off,
// int * prval);
func (w *WriteOp) CmpExt(b []byte, offset uint64) *WriteOpCmpExtStep {
oe := newWriteStep(b, 0, offset)
cmpExtStep := newWriteOpCmpExtStep()
w.steps = append(w.steps, oe, cmpExtStep)
C.rados_write_op_cmpext(
w.op,
oe.cBuffer,
oe.cDataLen,
oe.cOffset,
cmpExtStep.prval)

return cmpExtStep
}
40 changes: 40 additions & 0 deletions rados/write_op_preview_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//go:build ceph_preview
// +build ceph_preview

package rados

import (
"github.com/stretchr/testify/assert"
)

func (suite *RadosTestSuite) TestWriteOpCmpExt() {
suite.SetupConnection()
ta := assert.New(suite.T())

oid := "TestWriteOpCmpExt"
data := []byte("compare this")

// Create an object and populate it with data.
op1 := CreateWriteOp()
defer op1.Release()
op1.Create(CreateIdempotent)
op1.WriteFull([]byte(data))
err := op1.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)

// Compare contents of the object. Should succeed.
op2 := CreateWriteOp()
defer op2.Release()
cmpExtRes1 := op2.CmpExt(data, 0)
err = op2.Operate(suite.ioctx, oid, OperationNoFlag)
ta.NoError(err)
ta.Equal(cmpExtRes1.Result, int(0))

// Compare contents of the object. Should fail.
op3 := CreateWriteOp()
defer op3.Release()
cmpExtRes2 := op3.CmpExt([]byte("xxx"), 0)
err = op3.Operate(suite.ioctx, oid, OperationNoFlag)
ta.Error(err)
ta.NotEqual(cmpExtRes2.Result, int(0))
}

0 comments on commit 0955c0b

Please sign in to comment.