diff --git a/rados/ioctx.go b/rados/ioctx.go index 22af2c4..161d291 100644 --- a/rados/ioctx.go +++ b/rados/ioctx.go @@ -6,6 +6,7 @@ package rados import "C" import "unsafe" +import "time" // PoolStat represents Ceph pool statistics. type PoolStat struct { @@ -31,6 +32,14 @@ type PoolStat struct { Num_wr_kb uint64 } +// ObjectStat represents an object stat information +type ObjectStat struct { + // current length in bytes + Size uint64 + // last modification time + ModTime time.Time +} + // IOContext represents a context for performing I/O within a pool. type IOContext struct { ioctx C.rados_ioctx_t @@ -192,6 +201,29 @@ func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error { panic("invalid state") } +// Stat returns the size of the object and its last modification time +func (ioctx *IOContext) Stat(object string) (stat ObjectStat, err error) { + var c_psize C.uint64_t + var c_pmtime C.time_t + c_object := C.CString(object) + defer C.free(unsafe.Pointer(c_object)) + + ret := C.rados_stat( + ioctx.ioctx, + c_object, + &c_psize, + &c_pmtime) + + if ret < 0 { + return ObjectStat{}, RadosError(int(ret)) + } else { + return ObjectStat{ + Size: uint64(c_psize), + ModTime: time.Unix(int64(c_pmtime), 0), + }, nil + } +} + // GetXattr gets an xattr with key `name`, it returns the length of // the key read or an error if not successful func (ioctx *IOContext) GetXattr(object string, name string, data []byte) (int, error) { diff --git a/rados/rados_test.go b/rados/rados_test.go index 22f3090..454da2e 100644 --- a/rados/rados_test.go +++ b/rados/rados_test.go @@ -310,6 +310,30 @@ func TestReadWrite(t *testing.T) { pool.Destroy() } +func TestObjectStat(t *testing.T) { + conn, _ := rados.NewConn() + conn.ReadDefaultConfigFile() + conn.Connect() + + pool_name := GetUUID() + err := conn.MakePool(pool_name) + assert.NoError(t, err) + + pool, err := conn.OpenIOContext(pool_name) + assert.NoError(t, err) + + bytes_in := []byte("input data") + err = pool.Write("obj", bytes_in, 0) + assert.NoError(t, err) + + stat, err := pool.Stat("obj") + assert.Equal(t, uint64(len(bytes_in)), stat.Size) + assert.NotNil(t, stat.ModTime) + + pool.Destroy() + conn.Shutdown() +} + func TestGetPoolStats(t *testing.T) { conn, _ := rados.NewConn() conn.ReadDefaultConfigFile()