package index

import (
	
	
	

	
)

type SentinelType int

const (
	L0 SentinelType = iota
	L1
	L2
)

func ( SentinelType) () string {
	return fmt.Sprintf("L%v", int())
}

// Node is a Part that is a part of a linked-list.
type Node struct {
	next atomic.Pointer[Node]
	part parts.Part

	sentinel SentinelType // sentinel nodes contain no parts, and are to indicate the start of a new sub list
}

func ( *Node) () parts.Part {
	return .part
}

func ( *Node) () string {
	if .part == nil {
		if .next.Load() == nil {
			return fmt.Sprintf("[%v]", .sentinel)
		}
		return fmt.Sprintf("[%v]->%v", .sentinel, .next.Load().())
	}

	if .part.Record() != nil {
		if .next.Load() == nil {
			return fmt.Sprintf("[%v]", .part.Record().NumRows())
		}
		return fmt.Sprintf("[%v]->%v", .part.Record().NumRows(), .next.Load().())
	}

	,  := .part.AsSerializedBuffer(nil)
	if .next.Load() == nil {
		return fmt.Sprintf("[%v]", .NumRows())
	}
	return fmt.Sprintf("[%v]->%v", .NumRows(), .next.Load().())
}

// NewList creates a new part list using atomic constructs.
func ( SentinelType) *Node {
	 := &Node{
		sentinel: ,
	}
	return 
}

// Sentinel adds a new sentinel node to the list, and returns the sub list starting from that sentinel.
func ( *Node) ( SentinelType) *Node {
	return .prepend(&Node{
		sentinel: ,
	})
}

// Prepend a node onto the front of the list.
func ( *Node) ( parts.Part) *Node {
	return .prepend(&Node{
		part: ,
	})
}

// Insert a Node into the list, in order by Tx.
func ( *Node) ( parts.Part) {
	 := &Node{
		part: ,
	}
	 := .part.TX()
	 := func() bool {
		 := 
		 := .next.Load()
		for {
			if  == nil {
				return .next.CompareAndSwap(, )
			}
			if .part == nil || .part.TX() <  {
				.next.Store()
				return .next.CompareAndSwap(, )
			}
			 = 
			 = .next.Load()
		}
	}
	for !() {
		runtime.Gosched()
	}
}

func ( *Node) ( *Node) *Node {
	for { // continue until a successful compare and swap occurs
		 := .next.Load()
		.next.Store()
		if .next.CompareAndSwap(, ) {
			return 
		}
	}
}

// Iterate accesses every node in the list.
func ( *Node) ( func(*Node) bool) {
	if !() {
		return
	}

	 := .next.Load()
	for {
		if  == nil {
			return
		}
		if !() {
			return
		}
		 = .next.Load()
	}
}