splitTwo breaks up a node into two smaller nodes, if appropriate. This should only be called from the split() function.
(pageSize uintptr)
| 227 | // splitTwo breaks up a node into two smaller nodes, if appropriate. |
| 228 | // This should only be called from the split() function. |
| 229 | func (n *node) splitTwo(pageSize uintptr) (*node, *node) { |
| 230 | // Ignore the split if the page doesn't have at least enough nodes for |
| 231 | // two pages or if the nodes can fit in a single page. |
| 232 | if len(n.inodes) <= (common.MinKeysPerPage*2) || n.sizeLessThan(pageSize) { |
| 233 | return n, nil |
| 234 | } |
| 235 | |
| 236 | // Determine the threshold before starting a new node. |
| 237 | var fillPercent = n.bucket.FillPercent |
| 238 | if fillPercent < minFillPercent { |
| 239 | fillPercent = minFillPercent |
| 240 | } else if fillPercent > maxFillPercent { |
| 241 | fillPercent = maxFillPercent |
| 242 | } |
| 243 | threshold := int(float64(pageSize) * fillPercent) |
| 244 | |
| 245 | // Determine split position and sizes of the two pages. |
| 246 | splitIndex, _ := n.splitIndex(threshold) |
| 247 | |
| 248 | // Split node into two separate nodes. |
| 249 | // If there's no parent then we'll need to create one. |
| 250 | if n.parent == nil { |
| 251 | n.parent = &node{bucket: n.bucket, children: []*node{n}} |
| 252 | } |
| 253 | |
| 254 | // Create a new node and add it to the parent. |
| 255 | next := &node{bucket: n.bucket, isLeaf: n.isLeaf, parent: n.parent} |
| 256 | n.parent.children = append(n.parent.children, next) |
| 257 | |
| 258 | // Split inodes across two nodes. |
| 259 | next.inodes = n.inodes[splitIndex:] |
| 260 | n.inodes = n.inodes[:splitIndex] |
| 261 | |
| 262 | // Update the statistics. |
| 263 | n.bucket.tx.stats.IncSplit(1) |
| 264 | |
| 265 | return n, next |
| 266 | } |
| 267 | |
| 268 | // splitIndex finds the position where a page will fill a given threshold. |
| 269 | // It returns the index as well as the size of the first page. |
no test coverage detected