Skip to content

Commit

Permalink
Merge pull request #56 from basenana/fix/list-object-slow
Browse files Browse the repository at this point in the history
improve: list object slow
  • Loading branch information
hyponet authored Sep 5, 2023
2 parents d5ffde4 + a1c2928 commit 7923a1d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 18 deletions.
45 changes: 41 additions & 4 deletions pkg/dentry/cachestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import (
)

type metaCache struct {
metastore metastore.ObjectStore
lfu *utils.LFUPool
metastore metastore.ObjectStore
lfu *utils.LFUPool
childCache *utils.LFUPool
}

func (c *metaCache) getEntry(ctx context.Context, entryID int64) (*types.Metadata, error) {
Expand All @@ -45,6 +46,25 @@ func (c *metaCache) getEntry(ctx context.Context, entryID int64) (*types.Metadat
return &md, nil
}

func (c *metaCache) lookupChild(ctx context.Context, parentID int64, name string) (*types.Metadata, error) {
childID := c.lfu.Get(c.entryChildKey(parentID, name))
if childID != nil {
return c.getEntry(ctx, childID.(int64))
}

objs, err := c.metastore.ListObjects(ctx, types.Filter{Name: name, ParentID: parentID})
if err != nil {
return nil, err
}
if len(objs) == 0 {
return nil, types.ErrNotFound
}

md := objs[0].Metadata
c.putChildId2Cache(parentID, md.ID, name)
return &md, nil
}

func (c *metaCache) createEntry(ctx context.Context, newObj *types.Object, parent *types.Metadata) error {
objects := make([]*types.Object, 1, 2)
objects[0] = newObj
Expand All @@ -69,6 +89,7 @@ func (c *metaCache) updateEntries(ctx context.Context, entries ...*types.Metadat
defer func() {
for _, en := range entries {
c.delEntryCache(en.ID)
c.delChildCache(en.ParentID, en.Name)
}
}()

Expand All @@ -95,10 +116,26 @@ func (c *metaCache) delEntryCache(eid int64) {
}

func (c *metaCache) entryKey(eid int64) string {
return fmt.Sprintf("entry_%d", eid)
return fmt.Sprintf("e_%d", eid)
}

func (c *metaCache) putChildId2Cache(parentID, childID int64, name string) {
c.lfu.Put(c.entryChildKey(parentID, name), childID)
}

func (c *metaCache) delChildCache(parentID int64, name string) {
c.lfu.Remove(c.entryChildKey(parentID, name))
}

func (c *metaCache) entryChildKey(eid int64, name string) string {
return fmt.Sprintf("e_%d_c_%s", eid, name)
}

func newCacheStore(metastore metastore.ObjectStore) *metaCache {
cacheStore := &metaCache{metastore: metastore, lfu: utils.NewLFUPool(8192)}
cacheStore := &metaCache{
metastore: metastore,
lfu: utils.NewLFUPool(8192),
childCache: utils.NewLFUPool(32768),
}
return cacheStore
}
17 changes: 16 additions & 1 deletion pkg/dentry/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ var _ Group = &stdGroup{}

func (g *stdGroup) FindEntry(ctx context.Context, name string) (*types.Metadata, error) {
defer trace.StartRegion(ctx, "dentry.stdGroup.FindEntry").End()

md, err := g.cacheStore.lookupChild(ctx, g.entryID, name)
if err == nil {
return md, nil
}

entryLifecycleLock.RLock()
defer entryLifecycleLock.RUnlock()
objects, err := g.store.ListObjects(ctx, types.Filter{Name: name, ParentID: g.entryID})
Expand Down Expand Up @@ -145,8 +151,14 @@ func (g *stdGroup) CreateEntry(ctx context.Context, attr EntryAttr) (*types.Meta

func (g *stdGroup) UpdateEntry(ctx context.Context, entryId int64, patch *types.Metadata) error {
defer trace.StartRegion(ctx, "dentry.stdGroup.UpdateEntry").End()
entry, err := g.cacheStore.getEntry(ctx, entryId)
if err != nil {
return err
}
defer g.cacheStore.delChildCache(entry.ParentID, entry.Name)

patch.ID = entryId
if err := g.cacheStore.updateEntries(ctx, patch); err != nil {
if err = g.cacheStore.updateEntries(ctx, patch); err != nil {
return err
}
return nil
Expand Down Expand Up @@ -185,6 +197,7 @@ func (g *stdGroup) RemoveEntry(ctx context.Context, entryId int64) error {
if err := g.cacheStore.updateEntries(ctx, entry, group); err != nil {
return err
}
g.cacheStore.delChildCache(g.entryID, entry.Name)
return nil
}

Expand All @@ -200,6 +213,7 @@ func (g *stdGroup) ListChildren(ctx context.Context) ([]*types.Metadata, error)
if next.ID == next.ParentID {
continue
}
g.cacheStore.putChildId2Cache(g.entryID, next.ID, next.Name)
result = append(result, &next.Metadata)
}
return result, nil
Expand Down Expand Up @@ -367,6 +381,7 @@ func (e *extGroup) syncEntry(ctx context.Context, mirrored *stub.Entry, crt *typ
_ = e.stdGroup.store.DestroyObject(ctx, &types.Object{Metadata: *grp}, &types.Object{Metadata: *crt})
e.stdGroup.cacheStore.delEntryCache(crt.ID)
e.stdGroup.cacheStore.delEntryCache(grp.ID)
e.stdGroup.cacheStore.delChildCache(grp.ID, crt.Name)
}
return nil, err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/dentry/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ func (m *manager) RemoveEntry(ctx context.Context, parentId, entryId int64) erro
m.logger.Errorw("destroy object from meta server error", "entry", entry.ID, "err", err)
return err
}
m.cache.delChildCache(parentId, entry.Name)
return nil
}

Expand All @@ -288,8 +289,10 @@ func (m *manager) DestroyEntry(ctx context.Context, entryID int64) error {
}
if srcObj != nil {
m.cache.delEntryCache(srcObj.ID)
m.cache.delChildCache(srcObj.ParentID, srcObj.Name)
}
m.cache.delEntryCache(entry.ID)
m.cache.delChildCache(entry.ParentID, entry.Name)
return nil
}

Expand Down Expand Up @@ -428,6 +431,7 @@ func (m *manager) ChangeEntryParent(ctx context.Context, targetEntryId int64, ov
m.cache.delEntryCache(oldParent.ID)
m.cache.delEntryCache(newParent.ID)
m.cache.delEntryCache(target.ID)
m.cache.delChildCache(oldParent.ID, target.Name)
return nil
}

Expand Down
21 changes: 8 additions & 13 deletions pkg/metastore/db/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,15 @@ func (e *Entity) ListObjectChildren(ctx context.Context, filter types.Filter) ([

objectList := make([]Object, 0)
var result []*types.Object
if err := e.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
res := queryFilter(tx, filter).Find(&objectList)
if res.Error != nil {
return res.Error
}
res := queryFilter(e.DB.WithContext(ctx), filter).Find(&objectList)
if res.Error != nil {
return nil, res.Error
}

result = make([]*types.Object, len(objectList))
for i, objMod := range objectList {
o := objMod.Object()
result[i] = o
}
return nil
}); err != nil {
return nil, err
result = make([]*types.Object, len(objectList))
for i, objMod := range objectList {
o := objMod.Object()
result[i] = o
}

return result, nil
Expand Down

0 comments on commit 7923a1d

Please sign in to comment.