Directory removal leaves stuff in database

I’m trying stuff to see what happens. It seems like removing a directory leaves some keys in place.

This is my test program (in Go):

package main

import (
	"fmt"
	"log"

	"github.com/apple/foundationdb/bindings/go/src/fdb"
	"github.com/apple/foundationdb/bindings/go/src/fdb/directory"
	"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
)

func main() {
	// Different API versions may expose different runtime behaviors.
	// Don't set this above the maximum for the FoundationDB version in use.
	fdb.MustAPIVersion(630)

	// Open the default database from the system cluster
	db := fdb.MustOpenDefault()

	ds, e := directory.CreateOrOpen(db, []string{"testdir"}, nil)
	if e != nil {
		log.Fatalf("Unable to create/open directory: %s\n", e)
	}

	tup := []tuple.TupleElement{[]byte("one")}
	begin := []tuple.TupleElement{[]byte("")}
	end := []tuple.TupleElement{[]byte("\xFF")}

	// Database reads and writes happen inside transactions
	_, e = db.Transact(func(tr fdb.Transaction) (interface{}, error) {
		packed := ds.Pack(tup)
		fmt.Printf("Packed: %s\n", packed)
		tr.Set(packed, []byte("loneliest number"))
		return nil, nil
	})
	if e != nil {
		log.Fatalf("Unable to perform FDB transaction (%v)", e)
	}

	_, e = db.Transact(func(tr fdb.Transaction) (interface{}, error) {
		rangeResult := tr.GetRange(fdb.KeyRange{ds.Pack(begin), ds.Pack(end)}, fdb.RangeOptions{})
		rangeIterator := rangeResult.Iterator()

		// Advance will return true until the iterator is exhausted
		for rangeIterator.Advance() {
			if kv, e := rangeIterator.Get(); e != nil {
				return nil, fmt.Errorf("read next value: %w", e)
			} else {
				fmt.Printf("Key:  %s => %s\n", string(kv.Key), string(kv.Value))
			}
		}

		return nil, nil
	})
	if e != nil {
		log.Fatalf("Unable to perform FDB range iteration (%v)", e)
	}

	// Clear keys.
	_, e = db.Transact(func(tr fdb.Transaction) (interface{}, error) {
		done, err := ds.Remove(db, nil)
		if err != nil {
			log.Fatalf("Removing diretory: %s\n", err)
		}
		if !done {
			fmt.Printf("Not done?\n")
		}
		return nil, nil
	})
	if e != nil {
		log.Fatalf("Unable to perform FDB clear transaction (%v)", e)
	}
}

This is what’s left after removing the directory:

fdb> getrange "" "\xFF"

Range limited to 25 keys
`\xfe\x01\xfe\x00\x01hca\x00\x14\x14' is `\x01\x00\x00\x00\x00\x00\x00\x00'
`\xfe\x01\xfe\x00\x01hca\x00\x15\x01\x15\x12' is `'
`\xfe\x01\xfe\x00\x01version\x00' is `\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

For comparison, commenting out the directory close statement shows the intermediate value:

fdb> getrange "" "\xFF"

Range limited to 25 keys
`\x15\x12\x01one\x00' is `loneliest number'
`\xfe\x01\x15\x12\x00\x01layer\x00' is `'
`\xfe\x01\xfe\x00\x01hca\x00\x14\x14' is `\x01\x00\x00\x00\x00\x00\x00\x00'
`\xfe\x01\xfe\x00\x01hca\x00\x15\x01\x15\x12' is `'
`\xfe\x01\xfe\x00\x01version\x00' is `\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
`\xfe\x01\xfe\x00\x14\x02testdir\x00' is `\x15\x12'

The keys left are state associated with the directory layer, and they aren’t connected with any particular directory. They will be present even if you delete all of your directories, but if you are done with the directory layer they can be deleted. Note that if you then try to recreate the directory layer after that, it may then reuse directory prefixes.