@@ -92,14 +92,38 @@ func (b *fastStatBucket) insertMultiple(objs []*gcs.Object) {
9292}
9393
9494// LOCKS_EXCLUDED(b.mu)
95- func (b * fastStatBucket ) insertMultipleMinObjects (minObjs [] * gcs.MinObject ) {
95+ func (b * fastStatBucket ) insertMultipleMinObjects (listing * gcs.Listing ) {
9696 b .mu .Lock ()
9797 defer b .mu .Unlock ()
9898
99+ minObjectNames := make (map [string ]struct {})
99100 expiration := b .clock .Now ().Add (b .primaryCacheTTL )
100- for _ , o := range minObjs {
101+
102+ for _ , o := range listing .MinObjects {
101103 b .cache .Insert (o , expiration )
104+ minObjectNames [o .Name ] = struct {}{}
102105 }
106+
107+ for _ , p := range listing .CollapsedRuns {
108+ // If a MinObject with the same name as the CollapsedRun already exists,
109+ // we don't need to insert it again as a Folder.
110+ if _ , ok := minObjectNames [p ]; ok {
111+ fmt .Println ("MinObjects" )
112+ continue
113+ }
114+ if ! strings .HasSuffix (p , "/" ) {
115+ // log the error for incorrect prefix but don't fail the operation
116+ logger .Errorf ("error in prefix name: %s" , p )
117+ } else {
118+ f := & gcs.MinObject {
119+ Name : p ,
120+ ImplicitDir : true ,
121+ }
122+ fmt .Println ("Cache implicit dir: " , f )
123+ b .cache .Insert (f , expiration )
124+ }
125+ }
126+
103127}
104128
105129// LOCKS_EXCLUDED(b.mu)
@@ -117,15 +141,20 @@ func (b *fastStatBucket) insertHierarchicalListing(listing *gcs.Listing) {
117141 b .mu .Lock ()
118142 defer b .mu .Unlock ()
119143
144+ minObjectNames := make (map [string ]struct {})
120145 expiration := b .clock .Now ().Add (b .primaryCacheTTL )
121146
122147 for _ , o := range listing .MinObjects {
123- if ! strings .HasSuffix (o .Name , "/" ) {
124- b .cache .Insert (o , expiration )
125- }
148+ b .cache .Insert (o , expiration )
149+ minObjectNames [o .Name ] = struct {}{}
126150 }
127151
128152 for _ , p := range listing .CollapsedRuns {
153+ // If a MinObject with the same name as the CollapsedRun already exists,
154+ // we don't need to insert it again as a Folder.
155+ if _ , ok := minObjectNames [p ]; ok {
156+ continue
157+ }
129158 if ! strings .HasSuffix (p , "/" ) {
130159 // log the error for incorrect prefix but don't fail the operation
131160 logger .Errorf ("error in prefix name: %s" , p )
@@ -145,7 +174,11 @@ func (b *fastStatBucket) insert(o *gcs.Object) {
145174}
146175
147176func (b * fastStatBucket ) insertMinObject (o * gcs.MinObject ) {
148- b .insertMultipleMinObjects ([]* gcs.MinObject {o })
177+ b .mu .Lock ()
178+ defer b .mu .Unlock ()
179+
180+ expiration := b .clock .Now ().Add (b .primaryCacheTTL )
181+ b .cache .Insert (o , expiration )
149182}
150183
151184// LOCKS_EXCLUDED(b.mu)
@@ -357,6 +390,18 @@ func (b *fastStatBucket) StatObject(
357390func (b * fastStatBucket ) ListObjects (
358391 ctx context.Context ,
359392 req * gcs.ListObjectsRequest ) (listing * gcs.Listing , err error ) {
393+ // If ForceFetchFromCache is true, we will try to serve listing from cache.
394+ if req .ForceFetchFromCache {
395+ fmt .Println ("In force fetch" , req .Prefix )
396+ if hit , entry := b .lookUp (req .Prefix ); hit {
397+ // Otherwise, return MinObject and nil ExtendedObjectAttributes.
398+ listing = & gcs.Listing {
399+ MinObjects : []* gcs.MinObject {entry },
400+ }
401+ return
402+ }
403+ }
404+
360405 // Fetch the listing.
361406 listing , err = b .wrapped .ListObjects (ctx , req )
362407 if err != nil {
@@ -369,7 +414,7 @@ func (b *fastStatBucket) ListObjects(
369414 }
370415
371416 // note anything we found.
372- b .insertMultipleMinObjects (listing . MinObjects )
417+ b .insertMultipleMinObjects (listing )
373418 return
374419}
375420
0 commit comments