package index
import (
"fmt"
"runtime"
"sync/atomic"
"github.com/polarsignals/frostdb/parts"
)
type SentinelType int
const (
L0 SentinelType = iota
L1
L2
)
func (s SentinelType ) String () string {
return fmt .Sprintf ("L%v" , int (s ))
}
type Node struct {
next atomic .Pointer [Node ]
part parts .Part
sentinel SentinelType
}
func (n *Node ) Part () parts .Part {
return n .part
}
func (n *Node ) String () string {
if n .part == nil {
if n .next .Load () == nil {
return fmt .Sprintf ("[%v]" , n .sentinel )
}
return fmt .Sprintf ("[%v]->%v" , n .sentinel , n .next .Load ().String ())
}
if n .part .Record () != nil {
if n .next .Load () == nil {
return fmt .Sprintf ("[%v]" , n .part .Record ().NumRows ())
}
return fmt .Sprintf ("[%v]->%v" , n .part .Record ().NumRows (), n .next .Load ().String ())
}
b , _ := n .part .AsSerializedBuffer (nil )
if n .next .Load () == nil {
return fmt .Sprintf ("[%v]" , b .NumRows ())
}
return fmt .Sprintf ("[%v]->%v" , b .NumRows (), n .next .Load ().String ())
}
func NewList (sentinel SentinelType ) *Node {
p := &Node {
sentinel : sentinel ,
}
return p
}
func (n *Node ) Sentinel (s SentinelType ) *Node {
return n .prepend (&Node {
sentinel : s ,
})
}
func (n *Node ) Prepend (part parts .Part ) *Node {
return n .prepend (&Node {
part : part ,
})
}
func (n *Node ) Insert (part parts .Part ) {
node := &Node {
part : part ,
}
tx := node .part .TX ()
tryInsert := func () bool {
prev := n
next := n .next .Load ()
for {
if next == nil {
return prev .next .CompareAndSwap (next , node )
}
if next .part == nil || next .part .TX () < tx {
node .next .Store (next )
return prev .next .CompareAndSwap (next , node )
}
prev = next
next = next .next .Load ()
}
}
for !tryInsert () {
runtime .Gosched ()
}
}
func (n *Node ) prepend (node *Node ) *Node {
for {
next := n .next .Load ()
node .next .Store (next )
if n .next .CompareAndSwap (next , node ) {
return node
}
}
}
func (n *Node ) Iterate (iterate func (*Node ) bool ) {
if !iterate (n ) {
return
}
node := n .next .Load ()
for {
if node == nil {
return
}
if !iterate (node ) {
return
}
node = node .next .Load ()
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .