Skip to content

Commit 8e54435

Browse files
committed
Go: cache resolved futures for all types
Only a few futures are currently being cached; this change make all futures be cached and adds the missing check for fdb_future_get_error in the previously cached futures.
1 parent 3a6ccfd commit 8e54435

File tree

1 file changed

+145
-73
lines changed

1 file changed

+145
-73
lines changed

bindings/go/src/fdb/futures.go

Lines changed: 145 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -147,23 +147,26 @@ type FutureByteSlice interface {
147147

148148
type futureByteSlice struct {
149149
*future
150-
v []byte
151-
e error
152-
o sync.Once
150+
v []byte
151+
e error
152+
get sync.Once
153153
}
154154

155155
func (f *futureByteSlice) Get(ctx context.Context) ([]byte, error) {
156-
f.o.Do(func() {
157-
var present C.fdb_bool_t
158-
var value *C.uint8_t
159-
var length C.int
160-
156+
f.get.Do(func() {
161157
err := f.BlockUntilReady(ctx)
162158
if err != nil {
163159
f.e = err
164160
return
165161
}
162+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
163+
f.e = Error{int(err)}
164+
return
165+
}
166166

167+
var present C.fdb_bool_t
168+
var value *C.uint8_t
169+
var length C.int
167170
if err := C.fdb_future_get_value(f.ptr, &present, &value, &length); err != 0 {
168171
f.e = Error{int(err)}
169172
return
@@ -206,22 +209,25 @@ type FutureKey interface {
206209

207210
type futureKey struct {
208211
*future
209-
k Key
210-
e error
211-
o sync.Once
212+
k Key
213+
e error
214+
get sync.Once
212215
}
213216

214217
func (f *futureKey) Get(ctx context.Context) (Key, error) {
215-
f.o.Do(func() {
216-
var value *C.uint8_t
217-
var length C.int
218-
218+
f.get.Do(func() {
219219
err := f.BlockUntilReady(ctx)
220220
if err != nil {
221221
f.e = err
222222
return
223223
}
224+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
225+
f.e = Error{int(err)}
226+
return
227+
}
224228

229+
var value *C.uint8_t
230+
var length C.int
225231
if err := C.fdb_future_get_key(f.ptr, &value, &length); err != 0 {
226232
f.e = Error{int(err)}
227233
return
@@ -261,16 +267,24 @@ type FutureNil interface {
261267

262268
type futureNil struct {
263269
*future
270+
e error
271+
get sync.Once
264272
}
265273

266274
func (f *futureNil) Get(ctx context.Context) error {
267-
err := f.BlockUntilReady(ctx)
268-
if err != nil {
269-
return err
270-
}
271-
if err := C.fdb_future_get_error(f.ptr); err != 0 {
272-
return Error{int(err)}
273-
}
275+
f.get.Do(func() {
276+
err := f.BlockUntilReady(ctx)
277+
if err != nil {
278+
f.e = err
279+
return
280+
}
281+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
282+
f.e = Error{int(err)}
283+
return
284+
}
285+
286+
C.fdb_future_release_memory(f.ptr)
287+
})
274288

275289
return nil
276290
}
@@ -283,6 +297,10 @@ func (f *futureNil) MustGet(ctx context.Context) {
283297

284298
type futureKeyValueArray struct {
285299
*future
300+
v []KeyValue
301+
more bool
302+
e error
303+
o sync.Once
286304
}
287305

288306
//go:nocheckptr
@@ -299,28 +317,41 @@ func stringRefToSlice(ptr unsafe.Pointer) []byte {
299317
}
300318

301319
func (f *futureKeyValueArray) Get(ctx context.Context) ([]KeyValue, bool, error) {
302-
if err := f.BlockUntilReady(ctx); err != nil {
303-
return nil, false, err
304-
}
320+
f.o.Do(func() {
321+
err := f.BlockUntilReady(ctx)
322+
if err != nil {
323+
f.e = err
324+
return
325+
}
326+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
327+
f.e = Error{int(err)}
328+
return
329+
}
305330

306-
var kvs *C.FDBKeyValue
307-
var count C.int
308-
var more C.fdb_bool_t
331+
var kvs *C.FDBKeyValue
332+
var count C.int
333+
var more C.fdb_bool_t
334+
if err := C.fdb_future_get_keyvalue_array(f.ptr, &kvs, &count, &more); err != 0 {
335+
f.e = Error{int(err)}
336+
return
337+
}
309338

310-
if err := C.fdb_future_get_keyvalue_array(f.ptr, &kvs, &count, &more); err != 0 {
311-
return nil, false, Error{int(err)}
312-
}
339+
f.v = make([]KeyValue, int(count))
340+
if more != 0 {
341+
f.more = true
342+
}
313343

314-
ret := make([]KeyValue, int(count))
344+
for i := 0; i < int(count); i++ {
345+
kvptr := unsafe.Pointer(uintptr(unsafe.Pointer(kvs)) + uintptr(i*24))
315346

316-
for i := 0; i < int(count); i++ {
317-
kvptr := unsafe.Pointer(uintptr(unsafe.Pointer(kvs)) + uintptr(i*24))
347+
f.v[i].Key = stringRefToSlice(kvptr)
348+
f.v[i].Value = stringRefToSlice(unsafe.Pointer(uintptr(kvptr) + 12))
349+
}
318350

319-
ret[i].Key = stringRefToSlice(kvptr)
320-
ret[i].Value = stringRefToSlice(unsafe.Pointer(uintptr(kvptr) + 12))
321-
}
351+
C.fdb_future_release_memory(f.ptr)
352+
})
322353

323-
return ret, (more != 0), nil
354+
return f.v, f.more, f.e
324355
}
325356

326357
// FutureKeyArray represents the asynchronous result of a function
@@ -341,29 +372,42 @@ type FutureKeyArray interface {
341372

342373
type futureKeyArray struct {
343374
*future
375+
v []Key
376+
e error
377+
get sync.Once
344378
}
345379

346380
func (f *futureKeyArray) Get(ctx context.Context) ([]Key, error) {
347-
if err := f.BlockUntilReady(ctx); err != nil {
348-
return nil, err
349-
}
381+
f.get.Do(func() {
382+
err := f.BlockUntilReady(ctx)
383+
if err != nil {
384+
f.e = err
385+
return
386+
}
387+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
388+
f.e = Error{int(err)}
389+
return
390+
}
350391

351-
var ks *C.FDBKey
352-
var count C.int
392+
var ks *C.FDBKey
393+
var count C.int
394+
if err := C.fdb_future_get_key_array(f.ptr, &ks, &count); err != 0 {
395+
f.e = Error{int(err)}
396+
return
397+
}
353398

354-
if err := C.fdb_future_get_key_array(f.ptr, &ks, &count); err != 0 {
355-
return nil, Error{int(err)}
356-
}
399+
f.v = make([]Key, int(count))
357400

358-
ret := make([]Key, int(count))
401+
for i := 0; i < int(count); i++ {
402+
kptr := unsafe.Pointer(uintptr(unsafe.Pointer(ks)) + uintptr(i*12))
359403

360-
for i := 0; i < int(count); i++ {
361-
kptr := unsafe.Pointer(uintptr(unsafe.Pointer(ks)) + uintptr(i*12))
404+
f.v[i] = stringRefToSlice(kptr)
405+
}
362406

363-
ret[i] = stringRefToSlice(kptr)
364-
}
407+
C.fdb_future_release_memory(f.ptr)
408+
})
365409

366-
return ret, nil
410+
return f.v, f.e
367411
}
368412

369413
func (f *futureKeyArray) MustGet(ctx context.Context) []Key {
@@ -393,19 +437,34 @@ type FutureInt64 interface {
393437

394438
type futureInt64 struct {
395439
*future
440+
v int64
441+
e error
442+
get sync.Once
396443
}
397444

398445
func (f *futureInt64) Get(ctx context.Context) (int64, error) {
399-
if err := f.BlockUntilReady(ctx); err != nil {
400-
return 0, err
401-
}
446+
f.get.Do(func() {
447+
err := f.BlockUntilReady(ctx)
448+
if err != nil {
449+
f.e = err
450+
return
451+
}
452+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
453+
f.e = Error{int(err)}
454+
return
455+
}
402456

403-
var ver C.int64_t
404-
if err := C.fdb_future_get_int64(f.ptr, &ver); err != 0 {
405-
return 0, Error{int(err)}
406-
}
457+
var value C.int64_t
458+
if err := C.fdb_future_get_int64(f.ptr, &value); err != 0 {
459+
f.e = Error{int(err)}
460+
return
461+
}
462+
463+
f.v = int64(value)
464+
C.fdb_future_release_memory(f.ptr)
465+
})
407466

408-
return int64(ver), nil
467+
return f.v, f.e
409468
}
410469

411470
func (f *futureInt64) MustGet(ctx context.Context) int64 {
@@ -436,27 +495,40 @@ type FutureStringSlice interface {
436495

437496
type futureStringSlice struct {
438497
*future
498+
v []string
499+
e error
500+
get sync.Once
439501
}
440502

441503
func (f *futureStringSlice) Get(ctx context.Context) ([]string, error) {
442-
if err := f.BlockUntilReady(ctx); err != nil {
443-
return nil, err
444-
}
504+
f.get.Do(func() {
505+
err := f.BlockUntilReady(ctx)
506+
if err != nil {
507+
f.e = err
508+
return
509+
}
510+
if err := C.fdb_future_get_error(f.ptr); err != 0 {
511+
f.e = Error{int(err)}
512+
return
513+
}
445514

446-
var strings **C.char
447-
var count C.int
515+
var strings **C.char
516+
var count C.int
517+
if err := C.fdb_future_get_string_array(f.ptr, (***C.char)(unsafe.Pointer(&strings)), &count); err != 0 {
518+
f.e = Error{int(err)}
519+
return
520+
}
448521

449-
if err := C.fdb_future_get_string_array(f.ptr, (***C.char)(unsafe.Pointer(&strings)), &count); err != 0 {
450-
return nil, Error{int(err)}
451-
}
522+
f.v = make([]string, int(count))
452523

453-
ret := make([]string, int(count))
524+
for i := 0; i < int(count); i++ {
525+
f.v[i] = C.GoString((*C.char)(*(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(strings)) + uintptr(i*8)))))
526+
}
454527

455-
for i := 0; i < int(count); i++ {
456-
ret[i] = C.GoString((*C.char)(*(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(strings)) + uintptr(i*8)))))
457-
}
528+
C.fdb_future_release_memory(f.ptr)
529+
})
458530

459-
return ret, nil
531+
return f.v, f.e
460532
}
461533

462534
func (f *futureStringSlice) MustGet(ctx context.Context) []string {

0 commit comments

Comments
 (0)