Example #1
0
func directMultiGet(kvstore *goforestdb.KVStore, keysIn [][]byte) (
	valsOut [][]byte,
	valsRelease func(),
	err error) {
	keys := make([]*C.char, len(keysIn))
	key_lens := make([]C.size_t, len(keysIn))
	vals := make([]*C.char, len(keysIn))
	val_lens := make([]C.size_t, len(keysIn))

	for i, key := range keysIn {
		keys[i] = (*C.char)(unsafe.Pointer(&key[0]))
		key_lens[i] = (C.size_t)(len(key))
	}

	valsRelease = func() {
		C.blevex_forestdb_free_bufs(
			(C.size_t)(len(vals)), (**C.char)(unsafe.Pointer(&vals[0])))

		for i := range vals {
			vals[i] = nil
		}
	}

	errNo := C.blevex_forestdb_multi_get(
		(*C.fdb_kvs_handle)(kvstore.Handle()),
		(C.size_t)(len(keys)),
		(**C.char)(unsafe.Pointer(&keys[0])),
		(*C.size_t)(unsafe.Pointer(&key_lens[0])),
		(**C.char)(unsafe.Pointer(&vals[0])),
		(*C.size_t)(unsafe.Pointer(&val_lens[0])))
	if int(errNo) != 0 {
		valsRelease()

		return nil, nil, goforestdb.Error(errNo)
	}

	valsOut = make([][]byte, len(vals))
	for i, val := range vals {
		if val != nil {
			valsOut[i] = charToByte(val, val_lens[i])
		}
	}

	return valsOut, valsRelease, nil
}
Example #2
0
func (b *BatchEx) apply() error {
	// Hold onto final merge key/val bytes so GC doesn't collect them
	// until we're done.
	var mergeBytes [][]byte

	if len(b.merge.Merges) > 0 {
		mergeBytes = make([][]byte, 0, len(b.merge.Merges)*2)

		mergeKeys := make([][]byte, len(b.merge.Merges))
		mergeOps := make([][][]byte, len(b.merge.Merges))

		i := 0
		for key, ops := range b.merge.Merges {
			mergeKeys[i] = []byte(key)
			mergeOps[i] = ops
			i += 1
		}

		currVals, releaseVals, err := directMultiGet(b.w.kvstore, mergeKeys)
		if err != nil {
			return err
		}

		defer releaseVals()

		for i, key := range mergeKeys {
			mergedVal, ok := b.w.store.mo.FullMerge(key, currVals[i], mergeOps[i])
			if !ok {
				return fmt.Errorf("forestdb BatchEx merge operator failure,"+
					" key: %s, currVal: %q, mergeOps: %#v, i: %d",
					key, currVals[i], mergeOps[i], i)
			}

			mergeBytes = append(mergeBytes, key, mergedVal)

			b.Set(key, mergedVal)
		}
	}

	var num_sets C.int
	var set_keys **C.char
	var set_keys_sizes *C.size_t
	var set_vals **C.char
	var set_vals_sizes *C.size_t

	var num_deletes C.int
	var delete_keys **C.char
	var delete_keys_sizes *C.size_t

	if b.num_sets > 0 {
		num_sets = (C.int)(b.num_sets)
		set_keys = (**C.char)(unsafe.Pointer(&b.set_keys[0]))
		set_keys_sizes = (*C.size_t)(unsafe.Pointer(&b.set_keys_sizes[0]))
		set_vals = (**C.char)(unsafe.Pointer(&b.set_vals[0]))
		set_vals_sizes = (*C.size_t)(unsafe.Pointer(&b.set_vals_sizes[0]))
	}

	if b.num_deletes > 0 {
		num_deletes = (C.int)(b.num_deletes)
		delete_keys = (**C.char)(unsafe.Pointer(&b.delete_keys[0]))
		delete_keys_sizes = (*C.size_t)(unsafe.Pointer(&b.delete_keys_sizes[0]))
	}

	errNo := C.blevex_forestdb_execute_direct_batch(
		(*C.fdb_kvs_handle)(b.w.kvstore.Handle()),
		num_sets,
		set_keys,
		set_keys_sizes,
		set_vals,
		set_vals_sizes,
		num_deletes,
		delete_keys,
		delete_keys_sizes)
	if int(errNo) != 0 {
		return goforestdb.Error(errNo)
	}

	if mergeBytes != nil { // Ok to let GC have mergeBytes now.
		mergeBytes = nil
	}

	return nil
}