Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rados: implement binding for rados_write_op_cmpext #581

Merged
merged 1 commit into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 |
---- | ---------------- | ----------------------- |

3 changes: 3 additions & 0 deletions internal/cutil/aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const (
SizeTSize = C.sizeof_size_t
)

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

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

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

package rados

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

import (
"unsafe"
)

// 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(C.sizeof_int)),
}
}

// 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))
}