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

     1  //go:build generics
     2  
     3  package tree
     4  
     5  import "C"
     6  import (
     7  	"github.com/moontrade/nogc"
     8  	"unsafe"
     9  )
    10  
    11  //////////////////////////////////////////////////////////////////////////////////////////
    12  // Pointer -> Pointer
    13  //////////////////////////////////////////////////////////////////////////////////////////
    14  
    15  type ARTPointerToPointer[K any, V any] struct {
    16  	art    *ART
    17  	toFP   func(key *K) nogc.FatPointer
    18  	fromFP func(key nogc.FatPointer) K
    19  }
    20  
    21  func NewARTPointerToPointer[K any, V any](
    22  	toFP func(key *K) nogc.FatPointer,
    23  	fromFP func(key nogc.FatPointer) K,
    24  	lock LockKind, ownership Ownership, calcMemory bool,
    25  ) ARTPointerToPointer[K, V] {
    26  	t, _ := NewART(lock, ownership, calcMemory)
    27  	return ARTPointerToPointer[K, V]{
    28  		art:    t,
    29  		toFP:   toFP,
    30  		fromFP: fromFP,
    31  	}
    32  }
    33  
    34  func (g *ARTPointerToPointer[K, V]) Size() int64 {
    35  	return g.art.Size()
    36  }
    37  
    38  func (g *ARTPointerToPointer[K, V]) Memory() int64 {
    39  	return g.art.Memory()
    40  }
    41  
    42  func (g *ARTPointerToPointer[K, V]) Free() {
    43  	if g.art == nil {
    44  		return
    45  	}
    46  	_ = g.art.Close()
    47  	g.art = nil
    48  }
    49  
    50  func (g *ARTPointerToPointer[K, V]) Close() error {
    51  	g.Free()
    52  	return nil
    53  }
    54  
    55  func (g *ARTPointerToPointer[K, V]) Get(key K) (nogc.Dangling[V], bool) {
    56  	fp := g.toFP(&key)
    57  	p, found := g.art.Get(fp)
    58  	if !found {
    59  		return nogc.DanglingOf[V](0), false
    60  	}
    61  	return nogc.DanglingOf[V](p), true
    62  }
    63  
    64  func (g *ARTPointerToPointer[K, V]) Put(key K, value nogc.PointerOf[V]) (nogc.PointerOf[V], bool) {
    65  	fp := g.toFP(&key)
    66  	p, found := g.art.PutValue(fp, uint64(value.Pointer()))
    67  	if !found {
    68  		return nogc.PointerToOf[V](0), false
    69  	}
    70  	return nogc.PointerToOf[V](nogc.Pointer(p)), true
    71  }
    72  
    73  func (g *ARTPointerToPointer[K, V]) PutNoReplace(key K, value nogc.PointerOf[V]) (nogc.Dangling[V], bool) {
    74  	fp := g.toFP(&key)
    75  	p, found := g.art.PutNoReplaceValue(fp, uint64(value.Pointer()))
    76  	if !found {
    77  		return nogc.DanglingOf[V](0), false
    78  	}
    79  	return nogc.DanglingOf[V](nogc.Pointer(p)), true
    80  }
    81  
    82  func (g *ARTPointerToPointer[K, V]) SetReplaceAndFree(key K, value nogc.PointerOf[V]) bool {
    83  	fp := g.toFP(&key)
    84  	p := g.art.Put(fp, value.Pointer())
    85  	if p == 0 {
    86  		return false
    87  	}
    88  	p.Free()
    89  	return true
    90  }
    91  
    92  func (g *ARTPointerToPointer[K, V]) Delete(key K) (nogc.PointerOf[V], bool) {
    93  	fp := g.toFP(&key)
    94  	p, found := g.art.DeleteValue(fp)
    95  	if !found {
    96  		return nogc.PointerToOf[V](0), false
    97  	}
    98  	return nogc.PointerToOf[V](nogc.Pointer(p)), true
    99  }
   100  
   101  func (g *ARTPointerToPointer[K, V]) DeleteAndFree(key K) bool {
   102  	fp := g.toFP(&key)
   103  	p := g.art.Delete(fp)
   104  	if p == 0 {
   105  		return false
   106  	}
   107  	nogc.Free(p)
   108  	return true
   109  }
   110  
   111  // ValueType is any type that fits in 64bits
   112  type ValueType interface {
   113  	~int | ~int8 | ~int16 | ~int32 | ~int64 |
   114  		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
   115  		~float32 | ~float64 |
   116  		~struct{ nogc.Pointer } | ~unsafe.Pointer |
   117  		~struct{ int8 } | ~struct{ int16 } | ~struct{ int32 } | ~struct{ int64 } |
   118  		~struct{ byte } | ~struct{ uint8 } | ~struct{ uint16 } | ~struct{ uint32 } | ~struct{ uint64 } |
   119  		~struct{ uintptr } | ~struct{ float32 } | ~struct{ float64 } |
   120  		~[1]byte | ~[2]byte | ~[3]byte | ~[4]byte | ~[5]byte | ~[6]byte | ~[7]byte | ~[8]byte |
   121  		~struct{ v [1]byte } | ~struct{ v [2]byte } | ~struct{ v [3]byte } | ~struct{ v [4]byte } |
   122  		~struct{ v [5]byte } | ~struct{ v [6]byte } | ~struct{ v [7]byte } | ~struct{ v [8]byte }
   123  }
   124  
   125  func prepareKey[K ValueType](key K, to *uint64) {
   126  	*(*K)(unsafe.Pointer(to)) = key
   127  	*to = toBE(*to)
   128  }
   129  
   130  //////////////////////////////////////////////////////////////////////////////////////////
   131  // ValueType -> Pointer
   132  //////////////////////////////////////////////////////////////////////////////////////////
   133  
   134  type ARTValueToPointer[K ValueType, V any] struct {
   135  	art *ART
   136  }
   137  
   138  func (g *ARTValueToPointer[K, V]) Size() int64 {
   139  	return g.art.Size()
   140  }
   141  
   142  func (g *ARTValueToPointer[K, V]) Memory() int64 {
   143  	return g.art.Memory()
   144  }
   145  
   146  func NewARTValueToPointer[K ValueType, V any](lock LockKind, ownership Ownership, calcMemory bool) ARTValueToPointer[K, V] {
   147  	t, _ := NewART(lock, ownership, calcMemory)
   148  	return ARTValueToPointer[K, V]{art: t}
   149  }
   150  
   151  func (g *ARTValueToPointer[K, V]) Free() {
   152  	if g.art == nil {
   153  		return
   154  	}
   155  	_ = g.art.Close()
   156  	g.art = nil
   157  }
   158  
   159  func (g *ARTValueToPointer[K, V]) Close() error {
   160  	g.Free()
   161  	return nil
   162  }
   163  
   164  func (g *ARTValueToPointer[K, V]) Get(key K) (nogc.Dangling[V], bool) {
   165  	var k uint64
   166  	*(*K)(unsafe.Pointer(&k)) = key
   167  	k = toBE(k)
   168  	fp := nogc.FatPointerOfUInt64(&k)
   169  	p, found := g.art.Get(fp)
   170  	if !found {
   171  		return nogc.DanglingOf[V](0), false
   172  	}
   173  	return nogc.DanglingOf[V](p), true
   174  }
   175  
   176  func (g *ARTValueToPointer[K, V]) Put(key K, value nogc.PointerOf[V]) (nogc.PointerOf[V], bool) {
   177  	var k uint64
   178  	*(*K)(unsafe.Pointer(&k)) = key
   179  	k = toBE(k)
   180  	fp := nogc.FatPointerOfUInt64(&k)
   181  	p, found := g.art.PutValue(fp, uint64(value.Pointer()))
   182  	if !found {
   183  		return nogc.PointerToOf[V](0), false
   184  	}
   185  	return nogc.PointerToOf[V](nogc.Pointer(p)), true
   186  }
   187  
   188  func (g *ARTValueToPointer[K, V]) PutNoReplace(key K, value nogc.PointerOf[V]) (nogc.PointerOf[V], bool) {
   189  	var k uint64
   190  	*(*K)(unsafe.Pointer(&k)) = key
   191  	k = toBE(k)
   192  	fp := nogc.FatPointerOfUInt64(&k)
   193  	p, found := g.art.PutNoReplaceValue(fp, uint64(value.Pointer()))
   194  	if !found {
   195  		return nogc.PointerToOf[V](0), false
   196  	}
   197  	return nogc.PointerToOf[V](nogc.Pointer(p)), true
   198  }
   199  
   200  func (g *ARTValueToPointer[K, V]) Delete(key K) (nogc.PointerOf[V], bool) {
   201  	var k uint64
   202  	*(*K)(unsafe.Pointer(&k)) = key
   203  	k = toBE(k)
   204  	fp := nogc.FatPointerOfUInt64(&k)
   205  	p, found := g.art.DeleteValue(fp)
   206  	if !found {
   207  		return nogc.PointerToOf[V](0), false
   208  	}
   209  	return nogc.PointerToOf[V](nogc.Pointer(p)), true
   210  }
   211  
   212  func (g *ARTValueToPointer[K, V]) DeleteAndFree(key K) bool {
   213  	var k uint64
   214  	*(*K)(unsafe.Pointer(&k)) = key
   215  	k = toBE(k)
   216  	fp := nogc.FatPointerOfUInt64(&k)
   217  	p := g.art.Delete(fp)
   218  	if p == 0 {
   219  		return false
   220  	}
   221  	nogc.Free(p)
   222  	return true
   223  }
   224  
   225  //////////////////////////////////////////////////////////////////////////////////////////
   226  // ValueType -> ValueType
   227  //////////////////////////////////////////////////////////////////////////////////////////
   228  
   229  type ARTValueToValue[K ValueType, V ValueType] struct {
   230  	art *ART
   231  }
   232  
   233  func SizeofSizeT() int {
   234  	return int(unsafe.Sizeof(C.size_t(0)))
   235  }
   236  
   237  func NewARTValueToValue[K ValueType, V ValueType](lock LockKind, calcMemory bool) ARTValueToValue[K, V] {
   238  	t, _ := NewART(lock, OwnershipNotOwned, calcMemory)
   239  	return ARTValueToValue[K, V]{art: t}
   240  }
   241  
   242  func (g *ARTValueToValue[K, V]) Size() int64 {
   243  	return g.art.Size()
   244  }
   245  
   246  func (g *ARTValueToValue[K, V]) Memory() int64 {
   247  	return g.art.Memory()
   248  }
   249  
   250  func (g *ARTValueToValue[K, V]) Free() {
   251  	if g.art == nil {
   252  		return
   253  	}
   254  	_ = g.art.Close()
   255  	g.art = nil
   256  }
   257  
   258  func (g *ARTValueToValue[K, V]) Close() error {
   259  	_ = g.art.Close()
   260  	return nil
   261  }
   262  
   263  func (g *ARTValueToValue[K, V]) Get(key K) (V, bool) {
   264  	var k uint64
   265  	*(*K)(unsafe.Pointer(&k)) = key
   266  	k = toBE(k)
   267  	fp := nogc.FatPointerOfUInt64(&k)
   268  	p, found := g.art.GetValue(fp)
   269  	if !found {
   270  		var v V
   271  		return v, false
   272  	}
   273  	return *(*V)(unsafe.Pointer(&p)), true
   274  }
   275  
   276  func (g *ARTValueToValue[K, V]) Put(key K, value V) (V, bool) {
   277  	var k uint64
   278  	*(*K)(unsafe.Pointer(&k)) = key
   279  	k = toBE(k)
   280  	fp := nogc.FatPointerOfUInt64(&k)
   281  	var v uint64
   282  	*(*V)(unsafe.Pointer(&v)) = value
   283  	p, found := g.art.PutValue(fp, v)
   284  	if !found {
   285  		var v V
   286  		return v, false
   287  	}
   288  	return *(*V)(unsafe.Pointer(&p)), true
   289  }
   290  
   291  func (g *ARTValueToValue[K, V]) PutNoReplace(key K, value V) (V, bool) {
   292  	var k uint64
   293  	*(*K)(unsafe.Pointer(&k)) = key
   294  	k = toBE(k)
   295  	fp := nogc.FatPointerOfUInt64(&k)
   296  	var v uint64
   297  	*(*V)(unsafe.Pointer(&v)) = value
   298  	p, found := g.art.PutNoReplaceValue(fp, v)
   299  	if !found {
   300  		var v V
   301  		return v, false
   302  	}
   303  	return *(*V)(unsafe.Pointer(&p)), true
   304  }
   305  
   306  //////////////////////////////////////////////////////////////////////////////////////////
   307  // Pointer -> ValueType
   308  //////////////////////////////////////////////////////////////////////////////////////////
   309  
   310  type ARTPointerToValue[K any, V ValueType] struct {
   311  	art    *ART
   312  	toFP   func(key *K) nogc.FatPointer
   313  	fromFP func(key nogc.FatPointer) K
   314  }
   315  
   316  func NewARTPointerToValue[K any, V ValueType](
   317  	toFP func(key *K) nogc.FatPointer,
   318  	fromFP func(key nogc.FatPointer) K,
   319  	lock LockKind,
   320  	calcMemory bool,
   321  ) ARTPointerToValue[K, V] {
   322  	t, _ := NewART(lock, OwnershipNotOwned, calcMemory)
   323  	return ARTPointerToValue[K, V]{
   324  		art:    t,
   325  		toFP:   toFP,
   326  		fromFP: fromFP,
   327  	}
   328  }
   329  
   330  func (g *ARTPointerToValue[K, V]) Size() int64 {
   331  	return g.art.Size()
   332  }
   333  
   334  func (g *ARTPointerToValue[K, V]) Memory() int64 {
   335  	return g.art.Memory()
   336  }
   337  
   338  func (g *ARTPointerToValue[K, V]) Free() {
   339  	if g.art == nil {
   340  		return
   341  	}
   342  	_ = g.art.Close()
   343  	g.art = nil
   344  }
   345  
   346  func (g *ARTPointerToValue[K, V]) Close() error {
   347  	g.Free()
   348  	return nil
   349  }
   350  
   351  func (g *ARTPointerToValue[K, V]) Get(key K) (V, bool) {
   352  	fp := g.toFP(&key)
   353  	p, found := g.art.GetValue(fp)
   354  	if !found {
   355  		var v V
   356  		return v, false
   357  	}
   358  	return *(*V)(unsafe.Pointer(&p)), true
   359  }
   360  
   361  func (g *ARTPointerToValue[K, V]) Put(key K, value V) (V, bool) {
   362  	fp := g.toFP(&key)
   363  	var vv uint64
   364  	*(*V)(unsafe.Pointer(&vv)) = value
   365  	p, found := g.art.PutValue(fp, vv)
   366  	if !found {
   367  		var v V
   368  		return v, false
   369  	}
   370  	return *(*V)(unsafe.Pointer(&p)), true
   371  }
   372  
   373  func (g *ARTPointerToValue[K, V]) PutNoReplace(key K, value V) (V, bool) {
   374  	fp := g.toFP(&key)
   375  	var vv uint64
   376  	*(*V)(unsafe.Pointer(&vv)) = value
   377  	p, found := g.art.PutNoReplaceValue(fp, vv)
   378  	if !found {
   379  		var v V
   380  		return v, false
   381  	}
   382  	return *(*V)(unsafe.Pointer(&p)), true
   383  }
   384  
   385  func (g *ARTPointerToValue[K, V]) Delete(key K, value V) (V, bool) {
   386  	fp := g.toFP(&key)
   387  	var vv nogc.Pointer
   388  	*(*V)(unsafe.Pointer(&vv)) = value
   389  	p, found := g.art.DeleteValue(fp)
   390  	if !found {
   391  		var v V
   392  		return v, false
   393  	}
   394  	return *(*V)(unsafe.Pointer(&p)), true
   395  }
   396  
   397  func fpToString(fp nogc.FatPointer) string {
   398  	return fp.String()
   399  }
   400  func fpToByteSlice(fp nogc.FatPointer) []byte {
   401  	return fp.Bytes()
   402  }
   403  
   404  func NewARTStringToPointer[V any](lock LockKind, ownership Ownership, calcMemory bool) ARTPointerToPointer[string, V] {
   405  	return NewARTPointerToPointer[string, V](
   406  		nogc.FatPointerOfStringRef,
   407  		fpToString,
   408  		lock, ownership, calcMemory)
   409  }
   410  
   411  func NewARTStringToValue[V ValueType](lock LockKind, calcMemory bool) ARTPointerToValue[string, V] {
   412  	return NewARTPointerToValue[string, V](
   413  		nogc.FatPointerOfStringRef,
   414  		fpToString,
   415  		lock, calcMemory)
   416  }
   417  
   418  func NewARTByteSliceToPointer[V any](lock LockKind, ownership Ownership, calcMemory bool) ARTPointerToPointer[[]byte, V] {
   419  	return NewARTPointerToPointer[[]byte, V](
   420  		nogc.FatPointerOfBytesRef,
   421  		fpToByteSlice,
   422  		lock, ownership, calcMemory)
   423  }
   424  
   425  func NewARTByteSliceToValue[V ValueType](lock LockKind, calcMemory bool) ARTPointerToValue[[]byte, V] {
   426  	return NewARTPointerToValue[[]byte, V](
   427  		nogc.FatPointerOfBytesRef,
   428  		fpToByteSlice,
   429  		lock, calcMemory)
   430  }