From d82b5aa6ed512a40f8960a33c071e41574da1ac4 Mon Sep 17 00:00:00 2001 From: Vedant Das Date: Thu, 9 Jul 2026 09:33:39 +0000 Subject: [PATCH 1/3] perf: changed folder UpdateTime timestamp to int64 --- internal/storage/fake/bucket.go | 6 +++--- internal/storage/gcs/folder.go | 10 +++++++--- internal/storage/gcs/folder_test.go | 20 +++++++++++++++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/internal/storage/fake/bucket.go b/internal/storage/fake/bucket.go index f22e821dd7..7bbab6326e 100644 --- a/internal/storage/fake/bucket.go +++ b/internal/storage/fake/bucket.go @@ -271,7 +271,7 @@ func (b *bucket) mintObject( func (b *bucket) mintFolder(folderName string) (f gcs.Folder) { f = gcs.Folder{ Name: folderName, - UpdateTime: b.clock.Now(), + UpdateTime: b.clock.Now().UnixNano(), } return @@ -1224,7 +1224,7 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio for i := range b.folders { if strings.HasPrefix(b.folders[i].Name, folderName) { b.folders[i].Name = strings.Replace(b.folders[i].Name, folderName, destinationFolderId, 1) - b.folders[i].UpdateTime = time.Now() + b.folders[i].UpdateTime = time.Now().UnixNano() } } @@ -1245,7 +1245,7 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio // Return the updated folder. folder := &gcs.Folder{ Name: destinationFolderId, - UpdateTime: time.Now(), + UpdateTime: time.Now().UnixNano(), } return folder, nil diff --git a/internal/storage/gcs/folder.go b/internal/storage/gcs/folder.go index fbd3b488fe..22618d4dbf 100644 --- a/internal/storage/gcs/folder.go +++ b/internal/storage/gcs/folder.go @@ -16,21 +16,25 @@ package gcs import ( "strings" - "time" "cloud.google.com/go/storage/control/apiv2/controlpb" ) type Folder struct { Name string - UpdateTime time.Time + UpdateTime int64 } func GCSFolder(bucketName string, attrs *controlpb.Folder) *Folder { // Setting the parameters in Folder and doing conversions as necessary. + var updateTime int64 + t := attrs.GetUpdateTime().AsTime() + if !t.IsZero() { + updateTime = t.UnixNano() + } return &Folder{ Name: getFolderName(bucketName, attrs.Name), - UpdateTime: attrs.GetUpdateTime().AsTime(), + UpdateTime: updateTime, } } diff --git a/internal/storage/gcs/folder_test.go b/internal/storage/gcs/folder_test.go index 2c2a51b0a3..4385dd1b25 100644 --- a/internal/storage/gcs/folder_test.go +++ b/internal/storage/gcs/folder_test.go @@ -48,5 +48,23 @@ func TestGCSFolder(t *testing.T) { gcsFolder := GCSFolder(TestBucketName, &attrs) assert.Equal(t, attrs.Name, gcsFolder.Name) - assert.Equal(t, attrs.UpdateTime.AsTime(), gcsFolder.UpdateTime) + assert.Equal(t, attrs.UpdateTime.AsTime().UnixNano(), gcsFolder.UpdateTime) +} +func BenchmarkGCSFolder(b *testing.B) { + timestamp := ×tamppb.Timestamp{ + Seconds: 1234567890, + } + attrs := controlpb.Folder{ + Name: "projects/_/buckets/testBucket/folders/testFolder", + UpdateTime: timestamp, + } + + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + // this triggers 2 allocations + // the string creation inside getFolderName() + // and the &Folder{} heap allocation + _ = GCSFolder("testBucket", &attrs) + } } From 31444a66fb615558254fd7abb6b22570f406930b Mon Sep 17 00:00:00 2001 From: Vedant Das Date: Thu, 9 Jul 2026 10:46:53 +0000 Subject: [PATCH 2/3] added lock in RenameFolder --- internal/storage/fake/bucket.go | 7 +++++-- internal/storage/gcs/folder_test.go | 2 -- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/storage/fake/bucket.go b/internal/storage/fake/bucket.go index 7bbab6326e..6ff9d47f1f 100644 --- a/internal/storage/fake/bucket.go +++ b/internal/storage/fake/bucket.go @@ -1205,6 +1205,9 @@ func (b *bucket) CreateFolder(ctx context.Context, folderName string) (*gcs.Fold } func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinationFolderId string) (*gcs.Folder, error) { + b.mu.Lock() + defer b.mu.Unlock() + // Check that the destination name is legal. err := checkName(destinationFolderId) if err != nil { @@ -1224,7 +1227,7 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio for i := range b.folders { if strings.HasPrefix(b.folders[i].Name, folderName) { b.folders[i].Name = strings.Replace(b.folders[i].Name, folderName, destinationFolderId, 1) - b.folders[i].UpdateTime = time.Now().UnixNano() + b.folders[i].UpdateTime = b.clock.Now().UnixNano() } } @@ -1245,7 +1248,7 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio // Return the updated folder. folder := &gcs.Folder{ Name: destinationFolderId, - UpdateTime: time.Now().UnixNano(), + UpdateTime: b.clock.Now().UnixNano(), } return folder, nil diff --git a/internal/storage/gcs/folder_test.go b/internal/storage/gcs/folder_test.go index 4385dd1b25..5e0eb5767e 100644 --- a/internal/storage/gcs/folder_test.go +++ b/internal/storage/gcs/folder_test.go @@ -59,8 +59,6 @@ func BenchmarkGCSFolder(b *testing.B) { UpdateTime: timestamp, } - b.ReportAllocs() - b.ResetTimer() for b.Loop() { // this triggers 2 allocations // the string creation inside getFolderName() From c598bc3cc23ff6bec0ebcb70fda728bec88b5a88 Mon Sep 17 00:00:00 2001 From: Vedant Das Date: Thu, 9 Jul 2026 15:43:17 +0000 Subject: [PATCH 3/3] added test to check zero UpdatedTime --- internal/storage/gcs/folder_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/storage/gcs/folder_test.go b/internal/storage/gcs/folder_test.go index 5e0eb5767e..3024593e3b 100644 --- a/internal/storage/gcs/folder_test.go +++ b/internal/storage/gcs/folder_test.go @@ -50,6 +50,18 @@ func TestGCSFolder(t *testing.T) { assert.Equal(t, attrs.Name, gcsFolder.Name) assert.Equal(t, attrs.UpdateTime.AsTime().UnixNano(), gcsFolder.UpdateTime) } + +func TestGCSFolder_UninitializedTime(t *testing.T) { + attrs := controlpb.Folder{ + Name: TestFolderName, + Metageneration: 10, + } + + gcsFolder := GCSFolder(TestBucketName, &attrs) + + assert.Equal(t, int64(0), gcsFolder.UpdateTime) +} + func BenchmarkGCSFolder(b *testing.B) { timestamp := ×tamppb.Timestamp{ Seconds: 1234567890,