diff --git a/mount.go b/mount.go index 95973ad..451b24e 100644 --- a/mount.go +++ b/mount.go @@ -377,6 +377,8 @@ type lazyByIDNode struct { client *DocspellClient query string limit int + mu sync.Mutex + shards map[string]*lazyByIDShardNode } type lazyByIDShardNode struct { @@ -511,11 +513,21 @@ func (d *lazyByIDNode) Lookup(ctx context.Context, name string) (fs.Node, error) if !isDocspellIDPrefix(name) { return nil, fuse.ENOENT } - return &lazyByIDShardNode{ - query: combineItemQueries(d.query, "id:"+name+"*"), - client: d.client, - limit: d.limit, - }, nil + d.mu.Lock() + defer d.mu.Unlock() + if d.shards == nil { + d.shards = map[string]*lazyByIDShardNode{} + } + shard, ok := d.shards[name] + if !ok { + shard = &lazyByIDShardNode{ + query: combineItemQueries(d.query, "id:"+name+"*"), + client: d.client, + limit: d.limit, + } + d.shards[name] = shard + } + return shard, nil } func (d *lazyByIDNode) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { diff --git a/mount_test.go b/mount_test.go index 6780d47..7ac2e1a 100644 --- a/mount_test.go +++ b/mount_test.go @@ -104,6 +104,16 @@ func TestLazyByIDShardFetchesMatchingPrefix(t *testing.T) { if _, err := shard.(*lazyByIDShardNode).Lookup(context.Background(), "it-item-1.pdf"); err != nil { t.Fatal(err) } + lookupAgain, err := byID.(*lazyByIDNode).Lookup(context.Background(), "it") + if err != nil { + t.Fatal(err) + } + if lookupAgain != shard { + t.Fatal("expected repeated shard lookup to return its cached node") + } + if _, err := lookupAgain.(*lazyByIDShardNode).Lookup(context.Background(), "it-item-1.pdf"); err != nil { + t.Fatal(err) + } if len(queries) != 2 || queries[0] != "id:it*" || queries[1] != "id:it*" { t.Fatalf("unexpected queries: %v", queries) }