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 }