Example #1
0
// Iterate on a set of keys and their values from an omap
// `startAfter`: iterate only on the keys after this specified one
// `filterPrefix`: iterate only on the keys beginning with this prefix
// `maxReturn`: iterate no more than `maxReturn` key/value pairs
// `listFn`: the function called at each iteration
func (ioctx *IOContext) ListOmapValues(oid string, startAfter string, filterPrefix string, maxReturn int64, listFn OmapListFunc) error {
	c_oid := C.CString(oid)
	c_start_after := C.CString(startAfter)
	c_filter_prefix := C.CString(filterPrefix)
	c_max_return := C.uint64_t(maxReturn)

	defer C.free(unsafe.Pointer(c_oid))
	defer C.free(unsafe.Pointer(c_start_after))
	defer C.free(unsafe.Pointer(c_filter_prefix))

	op := C.rados_create_read_op()

	var c_iter C.rados_omap_iter_t
	var c_prval C.int
	C.rados_read_op_omap_get_vals(
		op,
		c_start_after,
		c_filter_prefix,
		c_max_return,
		&c_iter,
		&c_prval,
	)

	ret := C.rados_read_op_operate(op, ioctx.ioctx, c_oid, 0)

	if int(c_prval) != 0 {
		return RadosError(int(c_prval))
	} else if int(ret) != 0 {
		return GetRadosError(ret)
	}

	for {
		var c_key *C.char
		var c_val *C.char
		var c_len C.size_t

		ret = C.rados_omap_get_next(c_iter, &c_key, &c_val, &c_len)

		if int(ret) != 0 {
			return GetRadosError(ret)
		}

		if c_key == nil {
			break
		}

		listFn(C.GoString(c_key), C.GoBytes(unsafe.Pointer(c_val), C.int(c_len)))
	}

	C.rados_omap_get_end(c_iter)
	C.rados_release_read_op(op)

	return nil
}
Example #2
0
func (ro *ReadOperation) Operate(object *Object, flags ...LibradosOperation) (io.Reader, error) {
	oid := C.CString(object.name)
	defer freeString(oid)
	var f C.int = 0
	for _, flag := range flags {
		f |= C.int(flag)
	}
	ret := C.rados_read_op_operate(ro.opContext, ro.ioContext, oid, f)
	if err := toRadosError(ret); err != nil {
		err.Message = fmt.Sprintf("Unable to perform read operations on object %s.", object.name)
		return nil, err
	}
	if err := toRadosError(ro.retVal); err != nil {
		err.Message = fmt.Sprintf("Unable to read from object %s.", object.name)
		return nil, err
	}
	if ro.bytesRead == 0 {
		err := toRadosError(-1)
		err.Message = fmt.Sprintf("Nothing read from object %s.", object.name)
		return nil, err
	}
	data := bufToReader(ro.buffer, C.int(ro.bytesRead))
	return data, nil
}
Example #3
0
func (ioctx *IOContext) ReadTaggedFull(oid string, tagName string, data []byte, offset int) (n int, tag []byte, err error) {
	if len(data) == 0 {
		return 0, nil, nil
	}

	c_oid := C.CString(oid)
	c_tagName := C.CString(tagName)
	defer C.free(unsafe.Pointer(c_oid))
	defer C.free(unsafe.Pointer(c_tagName))

	var size C.size_t
	var rval_read C.int
	var rval_attr C.int
	var it C.rados_xattrs_iter_t

	op := C.rados_create_read_op()
	defer func() { C.rados_release_read_op(op) }()

	C.rados_read_op_read(
		op,
		(C.uint64_t)(offset),
		(C.size_t)(len(data)),
		(*C.char)(unsafe.Pointer(&data[0])),
		&size,
		&rval_read)

	C.rados_read_op_getxattrs(
		op,
		&it,
		&rval_attr)

	ret := C.rados_read_op_operate(op, ioctx.ioctx, c_oid, 0)

	if ret < 0 {
		return 0, nil, GetRadosError(ret)
	}
	if rval_read < 0 {
		return 0, nil, GetRadosError(rval_read)
	}
	if rval_attr < 0 {
		return 0, nil, GetRadosError(ret)
	}

	defer func() { C.rados_getxattrs_end(it) }()

	for {
		var c_name, c_val *C.char
		var c_len C.size_t
		defer C.free(unsafe.Pointer(c_name))
		defer C.free(unsafe.Pointer(c_val))

		ret := C.rados_getxattrs_next(it, &c_name, &c_val, &c_len)
		if ret < 0 {
			return int(size), nil, GetRadosError(ret)
		}
		// rados api returns a null name,val & 0-length upon
		// end of iteration
		if c_name == nil {
			return int(size), nil, GetRadosError(ret)
		}
		if tagName == C.GoString(c_name) {
			tag = C.GoBytes(unsafe.Pointer(c_val), (C.int)(c_len))
			break
		}
	}

	return int(size), tag, nil

}