all repos

rss-tools @ a5ac527

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/go.etcd.io/bbolt/internal/common/inode.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
package common
2
3
import "unsafe"
4
5
// Inode represents an internal node inside of a node.
6
// It can be used to point to elements in a page or point
7
// to an element which hasn't been added to a page yet.
8
type Inode struct {
9
	flags uint32
10
	pgid  Pgid
11
	key   []byte
12
	value []byte
13
}
14
15
type Inodes []Inode
16
17
func (in *Inode) Flags() uint32 {
18
	return in.flags
19
}
20
21
func (in *Inode) SetFlags(flags uint32) {
22
	in.flags = flags
23
}
24
25
func (in *Inode) Pgid() Pgid {
26
	return in.pgid
27
}
28
29
func (in *Inode) SetPgid(id Pgid) {
30
	in.pgid = id
31
}
32
33
func (in *Inode) Key() []byte {
34
	return in.key
35
}
36
37
func (in *Inode) SetKey(key []byte) {
38
	in.key = key
39
}
40
41
func (in *Inode) Value() []byte {
42
	return in.value
43
}
44
45
func (in *Inode) SetValue(value []byte) {
46
	in.value = value
47
}
48
49
func ReadInodeFromPage(p *Page) Inodes {
50
	inodes := make(Inodes, int(p.Count()))
51
	isLeaf := p.IsLeafPage()
52
	for i := 0; i < int(p.Count()); i++ {
53
		inode := &inodes[i]
54
		if isLeaf {
55
			elem := p.LeafPageElement(uint16(i))
56
			inode.SetFlags(elem.Flags())
57
			inode.SetKey(elem.Key())
58
			inode.SetValue(elem.Value())
59
		} else {
60
			elem := p.BranchPageElement(uint16(i))
61
			inode.SetPgid(elem.Pgid())
62
			inode.SetKey(elem.Key())
63
		}
64
		Assert(len(inode.Key()) > 0, "read: zero-length inode key")
65
	}
66
67
	return inodes
68
}
69
70
func WriteInodeToPage(inodes Inodes, p *Page) uint32 {
71
	// Loop over each item and write it to the page.
72
	// off tracks the offset into p of the start of the next data.
73
	off := unsafe.Sizeof(*p) + p.PageElementSize()*uintptr(len(inodes))
74
	isLeaf := p.IsLeafPage()
75
	for i, item := range inodes {
76
		Assert(len(item.Key()) > 0, "write: zero-length inode key")
77
78
		// Create a slice to write into of needed size and advance
79
		// byte pointer for next iteration.
80
		sz := len(item.Key()) + len(item.Value())
81
		b := UnsafeByteSlice(unsafe.Pointer(p), off, 0, sz)
82
		off += uintptr(sz)
83
84
		// Write the page element.
85
		if isLeaf {
86
			elem := p.LeafPageElement(uint16(i))
87
			elem.SetPos(uint32(uintptr(unsafe.Pointer(&b[0])) - uintptr(unsafe.Pointer(elem))))
88
			elem.SetFlags(item.Flags())
89
			elem.SetKsize(uint32(len(item.Key())))
90
			elem.SetVsize(uint32(len(item.Value())))
91
		} else {
92
			elem := p.BranchPageElement(uint16(i))
93
			elem.SetPos(uint32(uintptr(unsafe.Pointer(&b[0])) - uintptr(unsafe.Pointer(elem))))
94
			elem.SetKsize(uint32(len(item.Key())))
95
			elem.SetPgid(item.Pgid())
96
			Assert(elem.Pgid() != p.Id(), "write: circular dependency occurred")
97
		}
98
99
		// Write data for the element to the end of the page.
100
		l := copy(b, item.Key())
101
		copy(b[l:], item.Value())
102
	}
103
104
	return uint32(off)
105
}
106
107
func UsedSpaceInPage(inodes Inodes, p *Page) uint32 {
108
	off := unsafe.Sizeof(*p) + p.PageElementSize()*uintptr(len(inodes))
109
	for _, item := range inodes {
110
		sz := len(item.Key()) + len(item.Value())
111
		off += uintptr(sz)
112
	}
113
114
	return uint32(off)
115
}