+// addIndex adds the node line at place to both indexes.
+func (t *Tree) addIndex(node NodeKey, place Position) error {
+ record := make([]byte, treeRecordBytes)
+ encodePosition(record, place)
+ binary.LittleEndian.PutUint64(record[positionBytes:], uint64(node.index))
+ binary.LittleEndian.PutUint32(record[positionBytes+8:], uint32(node.level))
+
+ err := t.order.Append(record)
+ if err != nil {
+ return fmt.Errorf("append node order: %w", err)
+ }
+
+ return t.writeLevel(node, place)
+}
+
+// level returns the index of level, and opens it at first use.
+func (t *Tree) level(level int) (*Records, error) {
+ index, open := t.levels[level]
+ if open {
+ return index, nil
+ }
+
+ index, err := openRecords(filepath.Join(t.dir, fmt.Sprintf("tree-%d.idx", level)), positionBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ t.levels[level] = index
+
+ return index, nil
+}
+
+// Built tells if the node (l, i) is built.
+func (t *Tree) Built(level, index int) (bool, error) {
+ _, built, err := t.place(level, index)
+ return built, err
+}
+
+// place returns the position of the node (l, i) if it is built.
+func (t *Tree) place(level, index int) (Position, bool, error) {
+ if level < 0 || level >= bits.UintSize-2 || index < 0 {
+ return Position{}, false, nil
+ }
+
+ records, err := t.level(level)
+ if err != nil {
+ return Position{}, false, fmt.Errorf("open node level index: %w", err)
+ }
+
+ record, found, err := records.Read(index)
+ if err != nil || !found {
+ if err != nil {
+ return Position{}, false, fmt.Errorf("read node level record: %w", err)
+ }
+
+ return Position{}, false, nil
+ }
+
+ place := decodePosition(record)
+
+ return place, place.length > 0, nil