github.com/moontrade/nogc@v0.1.7/collections/tree/art_cgo_unsafe.go (about)

     1  //go:build !tinygo && (amd64 || arm64)
     2  // +build !tinygo
     3  // +build amd64 arm64
     4  
     5  package tree
     6  
     7  /*
     8  #cgo LDFLAGS: -L. -lstdc++
     9  #cgo CXXFLAGS: -std=c++20 -I.
    10  #include <stdlib.h>
    11  #include <pthread.h>
    12  #include "art.h"
    13  
    14  //static const struct art_lock_api * moontrade_ordered_lock_api_fair = &moontrade_ordered_lock_fair_api;
    15  //static const struct art_lock_api * art_lock_api = &moontrade_ordered_lock_unfair_api;
    16  
    17  typedef struct {
    18  	size_t lock;
    19  	size_t ownership;
    20  	size_t calc_memory;
    21  	size_t ptr;
    22  	size_t code;
    23  } art_new_t;
    24  
    25  void do_art_new(size_t arg0, size_t arg1) {
    26  	art_new_t* args = (art_new_t*)(void*)arg0;
    27  	art_tree* tree = (art_tree*)malloc(sizeof(art_tree));
    28  	if (args->ownership == 1) {
    29  		tree->free = 1;
    30  	}
    31  	args->code = (size_t)art_tree_init(tree);
    32  	args->calc_memory = args->calc_memory ? 1 : 0;
    33  	if (args->lock > 0) {
    34  		tree->fair = args->lock == 1 ? 1 : 0;
    35  		art_tree_init_lock(tree); // Enable RWSpinLock
    36  	}
    37  	args->ptr = (size_t)(void*)tree;
    38  }
    39  
    40  void do_art_destroy(size_t arg0, size_t arg1) {
    41  	art_tree* tree = (art_tree*)(void*)arg0;
    42  	art_tree_destroy(tree);
    43  	free((void*)tree);
    44  }
    45  
    46  //typedef struct {
    47  //	size_t tree;
    48  //	size_t size;
    49  //} art_size_t;
    50  //
    51  //void do_art_size(size_t arg0, size_t arg1) {
    52  //	art_size_t* args = (art_size_t*)(void*)arg0;
    53  //	args->size = (size_t)art_size((art_tree*)(void*)args->tree);
    54  //}
    55  
    56  typedef struct {
    57  	size_t tree;
    58  	size_t key;
    59  	size_t len;
    60  	art_value data;
    61  	art_value old;
    62  } art_insert_t;
    63  
    64  void do_art_insert(size_t arg0, size_t arg1) {
    65  	art_insert_t* args = (art_insert_t*)(void*)arg0;
    66  	args->old = art_insert((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len, args->data);
    67  }
    68  
    69  typedef struct {
    70  	size_t tree;
    71  	size_t key;
    72  	size_t len;
    73  	size_t found;
    74  	art_value data;
    75  	art_value old;
    76  } art_insert_value_t;
    77  
    78  void do_art_insert_value(size_t arg0, size_t arg1) {
    79  	art_insert_value_t* args = (art_insert_value_t*)(void*)arg0;
    80  	art_search_result result = art_insert_value((art_tree*)(void*)args->tree, (const unsigned char*)args->key, (int)args->len, args->data);
    81  	args->found = result.found;
    82  	args->old = result.value;
    83  }
    84  
    85  void do_art_insert_no_replace(size_t arg0, size_t arg1) {
    86  	art_insert_t* args = (art_insert_t*)(void*)arg0;
    87  	args->old = art_insert_no_replace((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len, args->data);
    88  }
    89  
    90  void do_art_insert_no_replace_value(size_t arg0, size_t arg1) {
    91  	art_insert_value_t* args = (art_insert_value_t*)(void*)arg0;
    92  	art_search_result result = art_insert_no_replace_value((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len, args->data);
    93  	args->found = result.found;
    94  	args->old = result.value;
    95  }
    96  
    97  typedef struct {
    98  	size_t tree;
    99  	size_t key;
   100  	size_t len;
   101  	art_value value;
   102  } art_delete_t;
   103  
   104  void do_art_delete(size_t arg0, size_t arg1) {
   105  	art_delete_t* args = (art_delete_t*)(void*)arg0;
   106  	args->value = art_delete((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len);
   107  }
   108  
   109  typedef struct {
   110  	size_t tree;
   111  	size_t key;
   112  	size_t len;
   113  	size_t found;
   114  	art_value value;
   115  } art_delete_value_t;
   116  
   117  void do_art_delete_value(size_t arg0, size_t arg1) {
   118  	art_delete_value_t* args = (art_delete_value_t*)(void*)arg0;
   119  	art_search_result result = art_delete_value((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len);
   120  	args->found = result.found;
   121  	args->value = result.value;
   122  }
   123  
   124  typedef struct {
   125  	size_t tree;
   126  	size_t key;
   127  	size_t len;
   128  	size_t found;
   129  	art_value result;
   130  } art_search_t;
   131  
   132  void do_art_search(size_t arg0, size_t arg1) {
   133  	art_search_t* args = (art_search_t*)(void*)arg0;
   134  	art_tree* tree = (art_tree*)(void*)args->tree;
   135  	art_search_result result = art_search((art_tree*)(void*)args->tree, (unsigned char*)args->key, (int)args->len);
   136  	args->found = result.found;
   137  	args->result = result.value;
   138  }
   139  
   140  typedef struct {
   141  	size_t tree;
   142  	size_t result;
   143  	size_t result2;
   144  } art_minmax_t;
   145  
   146  void do_art_minimum(size_t arg0, size_t arg1) {
   147  	art_minmax_t* args = (art_minmax_t*)(void*)arg0;
   148  	args->result = (size_t)art_minimum((art_tree*)(void*)args->tree);
   149  }
   150  
   151  void do_art_maximum(size_t arg0, size_t arg1) {
   152  	art_minmax_t* args = (art_minmax_t*)(void*)arg0;
   153  	args->result = (size_t)art_maximum((art_tree*)(void*)args->tree);
   154  }
   155  
   156  void do_art_minmax(size_t arg0, size_t arg1) {
   157  	art_minmax_t* args = (art_minmax_t*)(void*)arg0;
   158  	args->result = (size_t)art_minimum((art_tree*)(void*)args->tree);
   159  	args->result2 = (size_t)art_maximum((art_tree*)(void*)args->tree);
   160  }
   161  
   162  */
   163  import "C"
   164  import (
   165  	"github.com/moontrade/nogc"
   166  	"github.com/moontrade/nogc/unsafecgo"
   167  	"unsafe"
   168  )
   169  
   170  //// RWLock is a C++ based Read/Write spinlock tuned for performance. It performs slightly better than
   171  //// a Go sync.RWMutex, however both native code and Go code can use it. If staying in Go, use sync.RWMutex.
   172  //// It will lock a Go scheduler thread up so use it intelligently.
   173  //type RWLock struct {
   174  //	ptr uintptr
   175  //}
   176  //
   177  //func NewLock() RWLock {
   178  //	args := struct {
   179  //		result uintptr
   180  //	}{}
   181  //	ptr := uintptr(unsafe.Pointer(&args))
   182  //	unsafecgo.NonBlocking((*byte)(C.do_moontrade_rwlock_new), ptr, 0)
   183  //	return RWLock{ptr: args.result}
   184  //	//return (*RWLock)(unsafe.Pointer(C.moontrade_rwlock_new()))
   185  //}
   186  //
   187  //func Sleep(nanos time.Duration) {
   188  //	C.art_sleep(C.uint64_t(nanos))
   189  //}
   190  //
   191  //func SleepUnsafe(nanos time.Duration) {
   192  //	unsafecgo.NonBlocking((*byte)(C.art_sleep), uintptr(nanos), 0)
   193  //}
   194  //
   195  //func (rw RWLock) Close() error {
   196  //	rw.Free()
   197  //	return nil
   198  //}
   199  //
   200  //func (rw *RWLock) Free() {
   201  //	args := struct {
   202  //		lock uintptr
   203  //	}{
   204  //		lock: uintptr(unsafe.Pointer(rw)),
   205  //	}
   206  //	ptr := uintptr(unsafe.Pointer(&args))
   207  //	unsafecgo.NonBlocking((*byte)(C.moontrade_rwlock_destroy), ptr, 0)
   208  //	//C.moontrade_rwlock_destroy(unsafe.Pointer(rw))
   209  //}
   210  //
   211  //func (rw RWLock) Lock() {
   212  //	C.moontrade_rwlock_lock(C.size_t(rw.ptr), 0)
   213  //}
   214  //
   215  //func (rw RWLock) LockUnsafe() {
   216  //	unsafecgo.NonBlocking((*byte)(C.moontrade_rwlock_lock), rw.ptr, 0)
   217  //}
   218  //
   219  //func (rw RWLock) Unlock() {
   220  //	C.moontrade_rwlock_unlock(C.size_t(rw.ptr), 0)
   221  //}
   222  //
   223  //func (rw RWLock) UnlockUnsafe() {
   224  //	unsafecgo.NonBlocking((*byte)(C.moontrade_rwlock_unlock), rw.ptr, 0)
   225  //}
   226  //
   227  //func (rw RWLock) LockShared() {
   228  //	C.moontrade_rwlock_lock_shared(C.size_t(rw.ptr), 0)
   229  //}
   230  //
   231  //func (rw RWLock) LockSharedUnsafe() {
   232  //	unsafecgo.NonBlocking((*byte)(C.moontrade_rwlock_lock_shared), rw.ptr, 0)
   233  //}
   234  //
   235  //func (rw RWLock) UnlockShared() {
   236  //	C.moontrade_rwlock_unlock_shared(C.size_t(rw.ptr), 0)
   237  //}
   238  //
   239  //func (rw RWLock) UnlockSharedUnsafe() {
   240  //	unsafecgo.NonBlocking((*byte)(C.moontrade_rwlock_unlock_shared), rw.ptr, 0)
   241  //}
   242  
   243  type ART C.art_tree
   244  
   245  //func (art *ART) Lock() *RWLock {
   246  //	tree := (*C.art_tree)(unsafe.Pointer(art))
   247  //	return (*RWLock)(nogc.Pointer(tree.lock).Unsafe())
   248  //}
   249  
   250  func (art *ART) Size() int64 {
   251  	return int64((*C.art_tree)(unsafe.Pointer(art)).size)
   252  }
   253  
   254  func (art *ART) Memory() int64 {
   255  	return int64((*C.art_tree)(unsafe.Pointer(art)).memory)
   256  }
   257  
   258  type Leaf C.art_leaf
   259  
   260  func (l *Leaf) Data() Value {
   261  	return *(*Value)(unsafe.Pointer(l))
   262  }
   263  func (l *Leaf) Key() nogc.FatPointer {
   264  	return nogc.FatPointerOf(
   265  		nogc.Pointer(uintptr(unsafe.Pointer(l))+unsafe.Sizeof(uintptr(0))+4),
   266  		uintptr(*(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(l)) + unsafe.Sizeof(uintptr(0))))))
   267  }
   268  
   269  type LockKind uintptr
   270  
   271  const (
   272  	LockKindNone   LockKind = 0
   273  	LockKindFair   LockKind = 1
   274  	LockKindUnfair LockKind = 2
   275  )
   276  
   277  type Ownership uintptr
   278  
   279  const (
   280  	OwnershipNotOwned Ownership = 0
   281  	OwnershipOwned    Ownership = 1
   282  )
   283  
   284  func NewART(lock LockKind, ownership Ownership, calcMemory bool) (*ART, int) {
   285  	args := struct {
   286  		lock       uintptr
   287  		ownership  uintptr
   288  		calcMemory uintptr
   289  		ptr        uintptr
   290  		code       uintptr
   291  	}{
   292  		lock:      uintptr(lock),
   293  		ownership: uintptr(ownership),
   294  	}
   295  	if calcMemory {
   296  		args.calcMemory = 1
   297  	}
   298  	ptr := uintptr(unsafe.Pointer(&args))
   299  	unsafecgo.NonBlocking((*byte)(C.do_art_new), ptr, 0)
   300  	return (*ART)(nogc.Pointer(args.ptr).Unsafe()), int(args.code)
   301  }
   302  
   303  func (art *ART) Close() error {
   304  	art.Free()
   305  	return nil
   306  }
   307  
   308  func (art *ART) Free() {
   309  	ptr := uintptr(unsafe.Pointer(art))
   310  	unsafecgo.NonBlocking((*byte)(C.do_art_destroy), ptr, 0)
   311  }
   312  
   313  //type artSizeT struct {
   314  //	ptr  uintptr
   315  //	size uintptr
   316  //}
   317  //
   318  //func (r *ART) Size() int {
   319  //	args := artSizeT{ptr: uintptr(unsafe.Pointer(r))}
   320  //	ptr := uintptr(unsafe.Pointer(&args))
   321  //	unsafecgo.NonBlocking((*byte)(C.do_art_size), ptr, 0)
   322  //	return int(args.size)
   323  //}
   324  
   325  //func (t *ART) Size() int {
   326  //	return int(*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) + unsafe.Sizeof(uintptr(0)))))
   327  //}
   328  
   329  type Value struct {
   330  	Data uint64
   331  }
   332  
   333  func (art *ART) Put(key nogc.FatPointer, value nogc.Pointer) nogc.Pointer {
   334  	args := struct {
   335  		tree  uintptr
   336  		key   uintptr
   337  		len   uintptr
   338  		value Value
   339  		old   Value
   340  	}{
   341  		tree:  uintptr(unsafe.Pointer(art)),
   342  		key:   uintptr(key.Pointer),
   343  		len:   key.Len(),
   344  		value: Value{Data: uint64(value)},
   345  	}
   346  	ptr := uintptr(unsafe.Pointer(&args))
   347  	unsafecgo.NonBlocking((*byte)(C.do_art_insert), ptr, 0)
   348  	return nogc.Pointer(args.old.Data)
   349  }
   350  
   351  func (art *ART) PutValue(key nogc.FatPointer, value uint64) (uint64, bool) {
   352  	/*
   353  		typedef struct {
   354  			size_t tree;
   355  			size_t key;
   356  			size_t len;
   357  			size_t found;
   358  			art_value data;
   359  			art_value old;
   360  		} art_insert_value_t;
   361  	*/
   362  	args := struct {
   363  		tree  uintptr
   364  		key   uintptr
   365  		len   uintptr
   366  		found uintptr
   367  		value Value
   368  		old   Value
   369  	}{
   370  		tree:  uintptr(unsafe.Pointer(art)),
   371  		key:   uintptr(key.Pointer),
   372  		len:   key.Len(),
   373  		value: Value{Data: value},
   374  	}
   375  	ptr := uintptr(unsafe.Pointer(&args))
   376  	unsafecgo.NonBlocking((*byte)(C.do_art_insert_value), ptr, 0)
   377  	if args.found == 0 {
   378  		return 0, false
   379  	}
   380  	return args.old.Data, true
   381  }
   382  
   383  func (art *ART) PutNoReplace(key nogc.FatPointer, value nogc.Pointer) nogc.Pointer {
   384  	args := struct {
   385  		tree  uintptr
   386  		key   uintptr
   387  		len   uintptr
   388  		value Value
   389  		old   Value
   390  	}{
   391  		tree:  uintptr(unsafe.Pointer(art)),
   392  		key:   uintptr(key.Pointer),
   393  		len:   key.Len(),
   394  		value: Value{Data: uint64(value)},
   395  	}
   396  	ptr := uintptr(unsafe.Pointer(&args))
   397  	unsafecgo.NonBlocking((*byte)(C.do_art_insert_no_replace), ptr, 0)
   398  	return nogc.Pointer(args.old.Data)
   399  }
   400  
   401  func (art *ART) PutNoReplaceValue(key nogc.FatPointer, value uint64) (uint64, bool) {
   402  	args := struct {
   403  		tree  uintptr
   404  		key   uintptr
   405  		len   uintptr
   406  		found uintptr
   407  		value Value
   408  		old   Value
   409  	}{
   410  		tree:  uintptr(unsafe.Pointer(art)),
   411  		key:   uintptr(key.Pointer),
   412  		len:   key.Len(),
   413  		value: Value{Data: value},
   414  	}
   415  	ptr := uintptr(unsafe.Pointer(&args))
   416  	unsafecgo.NonBlocking((*byte)(C.do_art_insert_no_replace_value), ptr, 0)
   417  	if args.found == 0 {
   418  		return 0, false
   419  	}
   420  	return args.old.Data, true
   421  }
   422  
   423  func (art *ART) Delete(key nogc.FatPointer) nogc.Pointer {
   424  	args := struct {
   425  		tree uintptr
   426  		key  uintptr
   427  		len  uintptr
   428  		item Value
   429  	}{
   430  		tree: uintptr(unsafe.Pointer(art)),
   431  		key:  uintptr(key.Pointer),
   432  		len:  key.Len(),
   433  	}
   434  	ptr := uintptr(unsafe.Pointer(&args))
   435  	unsafecgo.NonBlocking((*byte)(C.do_art_delete), ptr, 0)
   436  	return nogc.Pointer(args.item.Data)
   437  }
   438  
   439  func (art *ART) DeleteValue(key nogc.FatPointer) (uint64, bool) {
   440  	args := struct {
   441  		tree  uintptr
   442  		key   uintptr
   443  		len   uintptr
   444  		found uintptr
   445  		item  Value
   446  	}{
   447  		tree: uintptr(unsafe.Pointer(art)),
   448  		key:  uintptr(key.Pointer),
   449  		len:  key.Len(),
   450  	}
   451  	ptr := uintptr(unsafe.Pointer(&args))
   452  	unsafecgo.NonBlocking((*byte)(C.do_art_delete_value), ptr, 0)
   453  	if args.found == 0 {
   454  		return 0, false
   455  	}
   456  	return args.item.Data, true
   457  }
   458  
   459  func (art *ART) Get(key nogc.FatPointer) (nogc.Pointer, bool) {
   460  	args := struct {
   461  		tree   uintptr
   462  		s      uintptr
   463  		len    uintptr
   464  		found  uintptr
   465  		result Value
   466  	}{
   467  		tree: uintptr(unsafe.Pointer(art)),
   468  		s:    uintptr(key.Pointer),
   469  		len:  key.Len(),
   470  	}
   471  	ptr := uintptr(unsafe.Pointer(&args))
   472  	unsafecgo.NonBlocking((*byte)(C.do_art_search), ptr, 0)
   473  	if args.found == 0 {
   474  		return 0, false
   475  	}
   476  	return nogc.Pointer(args.result.Data), true
   477  }
   478  
   479  func (art *ART) GetValue(key nogc.FatPointer) (uint64, bool) {
   480  	args := struct {
   481  		tree   uintptr
   482  		s      uintptr
   483  		len    uintptr
   484  		found  uintptr
   485  		result Value
   486  	}{
   487  		tree: uintptr(unsafe.Pointer(art)),
   488  		s:    uintptr(key.Pointer),
   489  		len:  key.Len(),
   490  	}
   491  	ptr := uintptr(unsafe.Pointer(&args))
   492  	unsafecgo.NonBlocking((*byte)(C.do_art_search), ptr, 0)
   493  	if args.found == 0 {
   494  		return 0, false
   495  	}
   496  	return args.result.Data, true
   497  }
   498  
   499  func (art *ART) Minimum() *Leaf {
   500  	args := struct {
   501  		tree    uintptr
   502  		result  uintptr
   503  		result2 uintptr
   504  	}{
   505  		tree: uintptr(unsafe.Pointer(art)),
   506  	}
   507  	ptr := uintptr(unsafe.Pointer(&args))
   508  	unsafecgo.NonBlocking((*byte)(C.do_art_minimum), ptr, 0)
   509  	return (*Leaf)(nogc.Pointer(args.result).Unsafe())
   510  }
   511  
   512  // Maximum Returns the maximum valued leaf
   513  // @return The maximum leaf or NULL
   514  func (art *ART) Maximum() *Leaf {
   515  	args := struct {
   516  		tree    uintptr
   517  		result  uintptr
   518  		result2 uintptr
   519  	}{
   520  		tree: uintptr(unsafe.Pointer(art)),
   521  	}
   522  	ptr := uintptr(unsafe.Pointer(&args))
   523  	unsafecgo.NonBlocking((*byte)(C.do_art_maximum), ptr, 0)
   524  	return (*Leaf)(nogc.Pointer(args.result).Unsafe())
   525  }
   526  
   527  // MinMax Returns the minimum and maximum valued leaf
   528  // @return The minimum and maximum leaf or NULL, NULL
   529  func (art *ART) MinMax() (*Leaf, *Leaf) {
   530  	args := struct {
   531  		tree    uintptr
   532  		result  uintptr
   533  		result2 uintptr
   534  	}{
   535  		tree: uintptr(unsafe.Pointer(art)),
   536  	}
   537  	ptr := uintptr(unsafe.Pointer(&args))
   538  	unsafecgo.NonBlocking((*byte)(C.do_art_minmax), ptr, 0)
   539  	return (*Leaf)(nogc.Pointer(args.result).Unsafe()), (*Leaf)(nogc.Pointer(args.result2).Unsafe())
   540  }