diff --git a/Collection.go b/Collection.go index 43de64b..42b7076 100644 --- a/Collection.go +++ b/Collection.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "sync" ) @@ -133,18 +134,19 @@ func (c *collection[T]) Clear() { // keyFile returns the file path for the given key. func (c *collection[T]) keyFile(key string) string { - return filepath.Join(c.directory, key) + return filepath.Join(c.directory, key+".json") } // loadFromDisk loads the collection data from the disk. func (c *collection[T]) loadFromDisk() error { - file, err := os.Open(c.directory) + dir, err := os.Open(c.directory) if err != nil { return err } - files, err := file.Readdirnames(0) + defer dir.Close() + files, err := dir.Readdirnames(0) for _, key := range files { fileError := c.loadFileFromDisk(key) @@ -154,16 +156,12 @@ func (c *collection[T]) loadFromDisk() error { } } - if err != nil { - return err - } - - return file.Close() + return err } // loadFileFromDisk loads a single file from the disk. -func (c *collection[T]) loadFileFromDisk(key string) error { - file, err := os.Open(filepath.Join(c.directory, key)) +func (c *collection[T]) loadFileFromDisk(fileName string) error { + file, err := os.Open(filepath.Join(c.directory, fileName)) if err != nil { return err @@ -178,6 +176,7 @@ func (c *collection[T]) loadFileFromDisk(key string) error { return err } + key := strings.TrimSuffix(fileName, ".json") c.data.Store(key, value) return file.Close() } @@ -185,7 +184,7 @@ func (c *collection[T]) loadFileFromDisk(key string) error { // writeFileToDisk writes the value for the key to disk as a JSON file. func (c *collection[T]) writeFileToDisk(key string, value *T) error { fileName := c.keyFile(key) - file, err := os.Create(fileName) + file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) if err != nil { return err diff --git a/Collection_test.go b/Collection_test.go index 4474dd8..ecc8269 100644 --- a/Collection_test.go +++ b/Collection_test.go @@ -1,6 +1,8 @@ package ocean_test import ( + "fmt" + "strconv" "sync" "testing" @@ -196,3 +198,24 @@ func BenchmarkDelete(b *testing.B) { b.StopTimer() } + +func BenchmarkColdStart100Files(b *testing.B) { + users, err := ocean.New[User]("test") + assert.Nil(b, err) + defer users.Clear() + + for i := 0; i < 100; i++ { + users.Set(strconv.Itoa(i), &User{Name: fmt.Sprintf("User %d", i)}) + } + + b.ReportAllocs() + b.ResetTimer() + + for n := 0; n < b.N; n++ { + again, err := ocean.New[User]("test") + assert.Nil(b, err) + assert.NotNil(b, again) + } + + b.StopTimer() +}