MCPcopy
hub / github.com/etcd-io/bbolt / ClearPageElements

Function ClearPageElements

internal/surgeon/surgeon.go:36–113  ·  view source on GitHub ↗

ClearPageElements supports clearing elements in both branch and leaf pages. Note if the ${abandonFreelist} is true, the freelist may be cleaned in the meta pages in the following two cases, and bbolt needs to scan the db to reconstruct free list. It may cause some delay on next startup, depending on

(path string, pgId common.Pgid, start, end int, abandonFreelist bool)

Source from the content-addressed store, hash-verified

34// afterwards; the first return parameter will be true in such case. But if
35// the freelist isn't synced at all, no warning message will be displayed.
36func ClearPageElements(path string, pgId common.Pgid, start, end int, abandonFreelist bool) (bool, error) {
37 // Read the page
38 p, buf, err := guts_cli.ReadPage(path, uint64(pgId))
39 if err != nil {
40 return false, fmt.Errorf("ReadPage failed: %w", err)
41 }
42
43 if !p.IsLeafPage() && !p.IsBranchPage() {
44 return false, fmt.Errorf("can't clear elements in %q page", p.Typ())
45 }
46
47 elementCnt := int(p.Count())
48
49 if elementCnt == 0 {
50 return false, nil
51 }
52
53 if start < 0 || start >= elementCnt {
54 return false, fmt.Errorf("the start index (%d) is out of range [0, %d)", start, elementCnt)
55 }
56
57 if (end < 0 || end > elementCnt) && end != -1 {
58 return false, fmt.Errorf("the end index (%d) is out of range [0, %d]", end, elementCnt)
59 }
60
61 if start > end && end != -1 {
62 return false, fmt.Errorf("the start index (%d) is bigger than the end index (%d)", start, end)
63 }
64
65 if start == end {
66 return false, fmt.Errorf("invalid: the start index (%d) is equal to the end index (%d)", start, end)
67 }
68
69 preOverflow := p.Overflow()
70
71 var (
72 dataWritten uint32
73 )
74 if end == int(p.Count()) || end == -1 {
75 inodes := common.ReadInodeFromPage(p)
76 inodes = inodes[:start]
77
78 p.SetCount(uint16(start))
79 // no need to write inode & data again, we just need to get
80 // the data size which will be kept.
81 dataWritten = common.UsedSpaceInPage(inodes, p)
82 } else {
83 inodes := common.ReadInodeFromPage(p)
84 inodes = append(inodes[:start], inodes[end:]...)
85
86 p.SetCount(uint16(len(inodes)))
87 dataWritten = common.WriteInodeToPage(inodes, p)
88 }
89
90 pageSize, _, err := guts_cli.ReadPageAndHWMSize(path)
91 if err != nil {
92 return false, fmt.Errorf("ReadPageAndHWMSize failed: %w", err)
93 }

Callers 2

ClearPageFunction · 0.85

Calls 15

ReadPageFunction · 0.92
ReadInodeFromPageFunction · 0.92
UsedSpaceInPageFunction · 0.92
WriteInodeToPageFunction · 0.92
ReadPageAndHWMSizeFunction · 0.92
WritePageFunction · 0.92
ClearFreelistFunction · 0.85
IsLeafPageMethod · 0.80
IsBranchPageMethod · 0.80
TypMethod · 0.80
OverflowMethod · 0.80
SetCountMethod · 0.80

Tested by

no test coverage detected