Documentation ¶
Overview ¶
- Author: Markus Stenberg <fingon@iki.fi> *
- Copyright (c) 2017 Markus Stenberg *
- Created: Wed Dec 27 17:19:12 2017 mstenber
- Last modified: Tue Jan 9 19:59:56 2018 mstenber
- Edit time: 175 min *
ibtree package provides a functional b+ tree that consists of nodes, with N children each, that are either leaves or other nodes.
It has built-in persistence, and Merkle tree-style hash tree behavior; root is defined by simply root node's hash, and similarly also all the children.
ONLY root and dirty Nodes are kept in memory; the rest count on (caching) storage backend + persistence layer being 'fast enough'.
Index ¶
- type BlockDataType
- type BlockId
- type DeltaCallback
- type DummyBackend
- type Key
- func (z *Key) DecodeMsg(dc *msgp.Reader) (err error)
- func (z Key) EncodeMsg(en *msgp.Writer) (err error)
- func (z Key) MarshalMsg(b []byte) (o []byte, err error)
- func (z Key) Msgsize() (s int)
- func (z *Key) UnmarshalMsg(bts []byte) (o []byte, err error)
- func (z *Key) UnmarshalMsgWithCfg(bts []byte, cfg *msgp.RuntimeConfig) (o []byte, err error)
- type Node
- func (self *Node) Commit() (*Node, BlockId)
- func (self *Node) CommitTo(backend TreeSaver) (*Node, BlockId)
- func (self *Node) Delete(key Key, st *Stack) *Node
- func (self *Node) DeleteRange(key1, key2 Key, st2 *Stack) *Node
- func (self *Node) Get(key Key, st *Stack) *string
- func (self *Node) IterateDelta(original *Node, deltacb DeltaCallback)
- func (self *Node) NextKey(key Key, st *Stack) *Key
- func (self *Node) PrevKey(key Key, st *Stack) *Key
- func (self *Node) PrintToMLogAll()
- func (self *Node) PrintToMLogDirty()
- func (self *Node) Set(key Key, value string, st *Stack) *Node
- func (self *Node) String() string
- type NodeData
- func (self *NodeData) CheckNodeStructure()
- func (z *NodeData) DecodeMsg(dc *msgp.Reader) (err error)
- func (z *NodeData) EncodeMsg(en *msgp.Writer) (err error)
- func (z *NodeData) MarshalMsg(b []byte) (o []byte, err error)
- func (z *NodeData) Msgsize() (s int)
- func (self *NodeData) String() string
- func (self *NodeData) ToBytes() []byte
- func (z *NodeData) UnmarshalMsg(bts []byte) (o []byte, err error)
- func (z *NodeData) UnmarshalMsgWithCfg(bts []byte, cfg *msgp.RuntimeConfig) (o []byte, err error)
- type NodeDataCart
- func (self *NodeDataCart) Get(key BlockId) (value *NodeData, found bool)
- func (self *NodeDataCart) GetOrCreate(key BlockId, factory func(key BlockId) *NodeData) (value *NodeData, created bool)
- func (self *NodeDataCart) Init(maximumSize int) *NodeDataCart
- func (self *NodeDataCart) Set(key BlockId, value *NodeData)
- type NodeDataCartEntry
- type NodeDataCartEntryList
- func (self *NodeDataCartEntryList) Iterate(cb func(v *NodeDataCartEntry))
- func (self *NodeDataCartEntryList) PushBack(v *NodeDataCartEntry) *NodeDataCartEntryListElement
- func (self *NodeDataCartEntryList) PushBackElement(e *NodeDataCartEntryListElement)
- func (self *NodeDataCartEntryList) PushFront(v *NodeDataCartEntry) *NodeDataCartEntryListElement
- func (self *NodeDataCartEntryList) PushFrontElement(e *NodeDataCartEntryListElement)
- func (self *NodeDataCartEntryList) Remove(e *NodeDataCartEntryListElement)
- func (self *NodeDataCartEntryList) RemoveElement(e *NodeDataCartEntryListElement)
- func (self *NodeDataCartEntryList) String() string
- type NodeDataCartEntryListElement
- type NodeDataChild
- func (z *NodeDataChild) DecodeMsg(dc *msgp.Reader) (err error)
- func (z NodeDataChild) EncodeMsg(en *msgp.Writer) (err error)
- func (z NodeDataChild) MarshalMsg(b []byte) (o []byte, err error)
- func (z NodeDataChild) Msgsize() (s int)
- func (self *NodeDataChild) String() string
- func (z *NodeDataChild) UnmarshalMsg(bts []byte) (o []byte, err error)
- func (z *NodeDataChild) UnmarshalMsgWithCfg(bts []byte, cfg *msgp.RuntimeConfig) (o []byte, err error)
- type Stack
- type SubTree
- type Transaction
- func (self *Transaction) Commit() (*Node, BlockId)
- func (self *Transaction) CommitTo(backend TreeSaver) (*Node, BlockId)
- func (self *Transaction) Delete(key Key)
- func (self *Transaction) DeleteRange(key1, key2 Key)
- func (self *Transaction) Get(key Key) *string
- func (self *Transaction) NewSubTree(treePrefix Key) *SubTree
- func (self *Transaction) NextKey(key Key) *Key
- func (self *Transaction) PrevKey(key Key) *Key
- func (self *Transaction) Root() *Node
- func (self *Transaction) Set(key Key, value string)
- type Tree
- type TreeBackend
- type TreeLoader
- type TreeSaver
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DeltaCallback ¶
type DeltaCallback func(old, new *NodeDataChild)
type DummyBackend ¶
type DummyBackend struct {
// contains filtered or unexported fields
}
DummyBackend is minimal in-memory backend that can be used for testing purposes.
func (DummyBackend) Init ¶
func (self DummyBackend) Init() *DummyBackend
func (*DummyBackend) LoadNode ¶
func (self *DummyBackend) LoadNode(id BlockId) *NodeData
func (*DummyBackend) SaveNode ¶
func (self *DummyBackend) SaveNode(nd *NodeData) BlockId
type Key ¶
type Key string
func (*Key) DecodeMsg ¶
DecodeMsg implements msgp.Decodable We treat empty fields as if we read a Nil from the wire.
func (Key) MarshalMsg ¶
MarshalMsg implements msgp.Marshaler
func (Key) Msgsize ¶
Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (*Key) UnmarshalMsg ¶
UnmarshalMsg implements msgp.Unmarshaler
func (*Key) UnmarshalMsgWithCfg ¶
type Node ¶
type Node struct { NodeData // contains filtered or unexported fields }
Node represents single node in single tree.
func (*Node) CommitTo ¶
CommitTo pushes dirty Node to the specified backend, returning the new root.
func (*Node) IterateDelta ¶
func (self *Node) IterateDelta(original *Node, deltacb DeltaCallback)
IterateDelta produces callback for every difference in the leaves local tree as opposed to 'other'.
Some clever things are done to avoid pointless subtree iteration. Still, this is pretty expensive operation and should be done only in background.
func (*Node) PrintToMLogAll ¶
func (self *Node) PrintToMLogAll()
func (*Node) PrintToMLogDirty ¶
func (self *Node) PrintToMLogDirty()
type NodeData ¶
type NodeData struct { Leafy bool `zid:"0"` Children []*NodeDataChild `zid:"1"` }
func NewNodeDataFromBytes ¶
func (*NodeData) CheckNodeStructure ¶
func (self *NodeData) CheckNodeStructure()
CheckNodeStructure allows sanity checking a node's content (should not be really used except for debugging)
func (*NodeData) DecodeMsg ¶
DecodeMsg implements msgp.Decodable We treat empty fields as if we read a Nil from the wire.
func (*NodeData) MarshalMsg ¶
MarshalMsg implements msgp.Marshaler
func (*NodeData) Msgsize ¶
Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (*NodeData) UnmarshalMsg ¶
UnmarshalMsg implements msgp.Unmarshaler
func (*NodeData) UnmarshalMsgWithCfg ¶
type NodeDataCart ¶
type NodeDataCart struct {
// contains filtered or unexported fields
}
NodeDataCart provides CART (Clock with Adaptive Replacement and Temporal filtering) cache map of string-ish BlockId to *NodeData.
For details about CART, see: Bansal & Modha 2004, CAR: Clock with Adaptive Replacement paper.
The type is not threadsafe, and requires also YYYList to be available for NodeDataCartEntryList.
variables are as close as possible to ones in paper
func (*NodeDataCart) Get ¶
func (self *NodeDataCart) Get(key BlockId) (value *NodeData, found bool)
Get retrieves the key, and returns the value if found, and indicates in found if it was found or not.
func (*NodeDataCart) GetOrCreate ¶
func (self *NodeDataCart) GetOrCreate(key BlockId, factory func(key BlockId) *NodeData) (value *NodeData, created bool)
GetOrCreate uses Get first, and then calls factory if Get fails. The value is returned, as well as whether or not it was created.
func (*NodeDataCart) Init ¶
func (self *NodeDataCart) Init(maximumSize int) *NodeDataCart
func (*NodeDataCart) Set ¶
func (self *NodeDataCart) Set(key BlockId, value *NodeData)
Set sets the key to value. If value is nil, the key is cleared instead.
type NodeDataCartEntry ¶
type NodeDataCartEntry struct {
// contains filtered or unexported fields
}
NodeDataCartEntry represents a single cache entry; maps point at it under key
func (*NodeDataCartEntry) String ¶
func (self *NodeDataCartEntry) String() string
type NodeDataCartEntryList ¶
type NodeDataCartEntryList struct {
Back, Front *NodeDataCartEntryListElement
Length int
// contains filtered or unexported fields
}
NodeDataCartEntryList provides doubly linked list which does not have inefficient operations, is typesafe, and does minimum amount of extra allocations needed. This is accomplished by sticking the freed items to a freelist instead of freeing them directly. The list is obviously not threadsafe.
func (*NodeDataCartEntryList) Iterate ¶
func (self *NodeDataCartEntryList) Iterate(cb func(v *NodeDataCartEntry))
func (*NodeDataCartEntryList) PushBack ¶
func (self *NodeDataCartEntryList) PushBack(v *NodeDataCartEntry) *NodeDataCartEntryListElement
func (*NodeDataCartEntryList) PushBackElement ¶
func (self *NodeDataCartEntryList) PushBackElement(e *NodeDataCartEntryListElement)
func (*NodeDataCartEntryList) PushFront ¶
func (self *NodeDataCartEntryList) PushFront(v *NodeDataCartEntry) *NodeDataCartEntryListElement
func (*NodeDataCartEntryList) PushFrontElement ¶
func (self *NodeDataCartEntryList) PushFrontElement(e *NodeDataCartEntryListElement)
func (*NodeDataCartEntryList) Remove ¶
func (self *NodeDataCartEntryList) Remove(e *NodeDataCartEntryListElement)
func (*NodeDataCartEntryList) RemoveElement ¶
func (self *NodeDataCartEntryList) RemoveElement(e *NodeDataCartEntryListElement)
func (*NodeDataCartEntryList) String ¶
func (self *NodeDataCartEntryList) String() string
type NodeDataCartEntryListElement ¶
type NodeDataCartEntryListElement struct {
Prev, Next *NodeDataCartEntryListElement
Value *NodeDataCartEntry
}
type NodeDataChild ¶
type NodeDataChild struct { Key Key `zid:"0"` Value string `zid:"1"` // contains filtered or unexported fields }
func (*NodeDataChild) DecodeMsg ¶
func (z *NodeDataChild) DecodeMsg(dc *msgp.Reader) (err error)
DecodeMsg implements msgp.Decodable We treat empty fields as if we read a Nil from the wire.
func (NodeDataChild) EncodeMsg ¶
func (z NodeDataChild) EncodeMsg(en *msgp.Writer) (err error)
EncodeMsg implements msgp.Encodable
func (NodeDataChild) MarshalMsg ¶
func (z NodeDataChild) MarshalMsg(b []byte) (o []byte, err error)
MarshalMsg implements msgp.Marshaler
func (NodeDataChild) Msgsize ¶
func (z NodeDataChild) Msgsize() (s int)
Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (*NodeDataChild) String ¶
func (self *NodeDataChild) String() string
func (*NodeDataChild) UnmarshalMsg ¶
func (z *NodeDataChild) UnmarshalMsg(bts []byte) (o []byte, err error)
UnmarshalMsg implements msgp.Unmarshaler
func (*NodeDataChild) UnmarshalMsgWithCfg ¶
func (z *NodeDataChild) UnmarshalMsgWithCfg(bts []byte, cfg *msgp.RuntimeConfig) (o []byte, err error)
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
Stack is internal utility class which is used to keep trace about stack of nodes on the current immutable tree path (parents mainly).
If using lowlevel API (= direct calls to Node), passing empty one may be necessary. Otherwise Transaction should be used.
type SubTree ¶
type SubTree struct {
// contains filtered or unexported fields
}
SubTree is convenience API for handling subtree of entries with common key prefix. Using the object, the tree behaves just like normal transaction (modulo few API calls that root transaction has to be used for).
func (*SubTree) DeleteRange ¶
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction is convenience API for dealing with the chaining of things in the ibtree. While API wise it is same as dealing with Nodes (and manual Stack allocation), there is no need to track the most recent access, and it is slightly more efficient as it maintains its own cache of most recent accesses within the built-in Stack.
func NewTransaction ¶
func NewTransaction(root *Node) *Transaction
func (*Transaction) Commit ¶
func (self *Transaction) Commit() (*Node, BlockId)
func (*Transaction) CommitTo ¶
func (self *Transaction) CommitTo(backend TreeSaver) (*Node, BlockId)
func (*Transaction) Delete ¶
func (self *Transaction) Delete(key Key)
func (*Transaction) DeleteRange ¶
func (self *Transaction) DeleteRange(key1, key2 Key)
func (*Transaction) Get ¶
func (self *Transaction) Get(key Key) *string
func (*Transaction) NewSubTree ¶
func (self *Transaction) NewSubTree(treePrefix Key) *SubTree
func (*Transaction) NextKey ¶
func (self *Transaction) NextKey(key Key) *Key
func (*Transaction) PrevKey ¶
func (self *Transaction) PrevKey(key Key) *Key
func (*Transaction) Root ¶
func (self *Transaction) Root() *Node
func (*Transaction) Set ¶
func (self *Transaction) Set(key Key, value string)
type Tree ¶
type Tree struct { // Can be provided externally NodeMaximumSize int // contains filtered or unexported fields }
Tree represents static configuration that can be used over multiple B+ trees. If this is changed with existing trees, bad things WILL happen.
func (Tree) Init ¶
func (self Tree) Init(backend TreeBackend) *Tree
type TreeBackend ¶
type TreeBackend interface { TreeLoader TreeSaver }