Add RBF index/field usage stats

This commit is contained in:
Ben Johnson 2021-01-14 13:09:57 -07:00 committed by Alan Bernstein
parent e397d35ed5
commit 32a35805a4
4 changed files with 48 additions and 36 deletions

2
rbf.go
View file

@ -436,7 +436,7 @@ func (tx *RBFTx) GetSortedFieldViewList(idx *Index, shard uint64) (fvs []txkey.F
}
func (tx *RBFTx) GetFieldSizeBytes(index, field string) (uint64, error) {
return 0, nil
return tx.tx.GetSizeBytesWithPrefix(string(txkey.FieldPrefix(index, field)))
}
// rbfName returns a NULL-separated key used for identifying bitmap maps in RBF.

View file

@ -839,23 +839,31 @@ func (tx *Tx) inusePageSet() (map[uint32]struct{}, error) {
return m, nil
}
func (tx *Tx) GetFieldSizeBytes(index, field string) (uint64, error) {
fmt.Printf("getting RBF field size %s/%s\n", index, field)
var pgno uint32
var parent uint32
var pageCount uint64
if err := tx.walkTree(pgno, parent, func(pgno, parent, typ uint32) error {
pageCount++
return nil
}); err != nil {
// GetSizeBytesWithPrefix returns the size of bitmaps with a given key prefix.
func (tx *Tx) GetSizeBytesWithPrefix(prefix string) (n uint64, err error) {
records, err := tx.RootRecords()
if err != nil {
return 0, err
}
return uint64(pageCount * PageSize), nil
// Loop over each bitmap in the database.
for itr := records.Iterator(); !itr.Done(); {
name, pgno := itr.Next()
// Skip over any bitmaps that don't have a matching prefix.
if !strings.HasPrefix(name.(string), prefix) {
continue
}
// Traverse the bitmap's b-tree and count the bytes for each page.
if err := tx.walkTree(pgno.(uint32), 0, func(pgno, parent, typ uint32) error {
n += PageSize
return nil
}); err != nil {
return 0, err
}
}
return n, nil
}
// walkTree recursively iterates over a page and all its children.

View file

@ -185,7 +185,7 @@ func (m *Command) Start() (err error) {
return errors.Wrap(err, "opening server")
}
m.logger.Printf("listening as %s\n", m.listenURI)
m.logger.Printf("listening! as %s\n", m.listenURI)
go func() {
if err := m.grpcServer.Serve(); err != nil {
m.logger.Printf("grpc server error: %v", err)

View file

@ -602,15 +602,7 @@ func (f *TxFactory) IndexUsageDetails() (map[string]IndexUsage, error) {
idxs := f.holder.Indexes()
/*
qcx := f.NewQcx()
tx, finisher, err := qcx.GetTx(Txo{Write: !writable})
if err != nil {
return indexUsage, errors.Wrap(err, "qcx.GetTx")
}
defer finisher(nil)
*/
qcx := f.NewQcx()
for _, idx := range idxs {
index := idx.name
println(" i:" + index)
@ -632,18 +624,30 @@ func (f *TxFactory) IndexUsageDetails() (map[string]IndexUsage, error) {
fieldKeysTotal += keysBytes
fragmentsTotal += fieldUsages[field].Fragments
// non-roaring field usage
/*
fieldBytes, err := tx.GetFieldSizeBytes(index, field)
if err != nil {
return indexUsage, errors.Wrapf(err, "getting disk usage for non-roaring fragments (%s)", field)
fieldUsage := FieldUsage{Keys: keysBytes}
for _, shard := range fld.AvailableShards(true).Slice() {
if err := func() error {
tx, finisher, err := qcx.GetTx(Txo{Write: !writable, Index: idx, Shard: shard})
if err != nil {
return errors.Wrap(err, "qcx.GetTx")
}
defer finisher(nil)
// non-roaring field usage
fieldBytes, err := tx.GetFieldSizeBytes(index, field)
if err != nil {
return errors.Wrapf(err, "getting disk usage for non-roaring fragments (%s)", field)
}
fieldUsage.Total += fieldBytes
return nil
}(); err != nil {
return indexUsage, err
}
fieldUsages[field] = FieldUsage{
Total: fieldBytes,
Fragments: fieldBytes - keysBytes,
Keys: keysBytes,
}
*/
}
fieldUsage.Fragments = fieldUsage.Total - keysBytes
fieldUsages[field] = fieldUsage
}
// index keys usage