diff options
Diffstat (limited to 'object/store/memory')
| -rw-r--r-- | object/store/memory/algorithm.go | 8 | ||||
| -rw-r--r-- | object/store/memory/doc.go | 2 | ||||
| -rw-r--r-- | object/store/memory/object.go | 9 | ||||
| -rw-r--r-- | object/store/memory/read_bytes.go | 37 | ||||
| -rw-r--r-- | object/store/memory/read_header.go | 17 | ||||
| -rw-r--r-- | object/store/memory/read_reader.go | 29 | ||||
| -rw-r--r-- | object/store/memory/read_size.go | 13 | ||||
| -rw-r--r-- | object/store/memory/refresh.go | 6 | ||||
| -rw-r--r-- | object/store/memory/store.go | 28 | ||||
| -rw-r--r-- | object/store/memory/write_bytes.go | 35 | ||||
| -rw-r--r-- | object/store/memory/write_reader.go | 55 | ||||
| -rw-r--r-- | object/store/memory/write_test.go | 192 |
12 files changed, 0 insertions, 431 deletions
diff --git a/object/store/memory/algorithm.go b/object/store/memory/algorithm.go deleted file mode 100644 index bf7f3a82..00000000 --- a/object/store/memory/algorithm.go +++ /dev/null @@ -1,8 +0,0 @@ -package memory - -import objectid "codeberg.org/lindenii/furgit/object/id" - -// Algorithm returns the object ID algorithm used by the store. -func (store *Store) Algorithm() objectid.Algorithm { - return store.algo -} diff --git a/object/store/memory/doc.go b/object/store/memory/doc.go deleted file mode 100644 index cb40d466..00000000 --- a/object/store/memory/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package memory provides one in-memory object store. -package memory diff --git a/object/store/memory/object.go b/object/store/memory/object.go deleted file mode 100644 index a85175c7..00000000 --- a/object/store/memory/object.go +++ /dev/null @@ -1,9 +0,0 @@ -package memory - -import objecttype "codeberg.org/lindenii/furgit/object/type" - -// storedObject is one in-memory object entry. -type storedObject struct { - ty objecttype.Type - content []byte -} diff --git a/object/store/memory/read_bytes.go b/object/store/memory/read_bytes.go deleted file mode 100644 index 48d3694a..00000000 --- a/object/store/memory/read_bytes.go +++ /dev/null @@ -1,37 +0,0 @@ -package memory - -import ( - objectheader "codeberg.org/lindenii/furgit/object/header" - objectid "codeberg.org/lindenii/furgit/object/id" - objectstore "codeberg.org/lindenii/furgit/object/store" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -// ReadBytesFull reads one full object, including the object header. -func (store *Store) ReadBytesFull(id objectid.ObjectID) ([]byte, error) { - obj, ok := store.objects[id] - if !ok { - return nil, objectstore.ErrObjectNotFound - } - - header, ok := objectheader.Encode(obj.ty, int64(len(obj.content))) - if !ok { - panic("failed to encode object header") - } - - raw := make([]byte, len(header)+len(obj.content)) - copy(raw, header) - copy(raw[len(header):], obj.content) - - return raw, nil -} - -// ReadBytesContent reads one object body. -func (store *Store) ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []byte, error) { - obj, ok := store.objects[id] - if !ok { - return objecttype.TypeInvalid, nil, objectstore.ErrObjectNotFound - } - - return obj.ty, append([]byte(nil), obj.content...), nil -} diff --git a/object/store/memory/read_header.go b/object/store/memory/read_header.go deleted file mode 100644 index da3acd1c..00000000 --- a/object/store/memory/read_header.go +++ /dev/null @@ -1,17 +0,0 @@ -package memory - -import ( - objectid "codeberg.org/lindenii/furgit/object/id" - objectstore "codeberg.org/lindenii/furgit/object/store" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -// ReadHeader reads one object header. -func (store *Store) ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, error) { - obj, ok := store.objects[id] - if !ok { - return objecttype.TypeInvalid, 0, objectstore.ErrObjectNotFound - } - - return obj.ty, int64(len(obj.content)), nil -} diff --git a/object/store/memory/read_reader.go b/object/store/memory/read_reader.go deleted file mode 100644 index 425c3034..00000000 --- a/object/store/memory/read_reader.go +++ /dev/null @@ -1,29 +0,0 @@ -package memory - -import ( - "bytes" - "io" - - objectid "codeberg.org/lindenii/furgit/object/id" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -// ReadReaderFull reads one full object through a reader. -func (store *Store) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) { - raw, err := store.ReadBytesFull(id) - if err != nil { - return nil, err - } - - return io.NopCloser(bytes.NewReader(raw)), nil -} - -// ReadReaderContent reads one object body through a reader. -func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, int64, io.ReadCloser, error) { - ty, content, err := store.ReadBytesContent(id) - if err != nil { - return objecttype.TypeInvalid, 0, nil, err - } - - return ty, int64(len(content)), io.NopCloser(bytes.NewReader(content)), nil -} diff --git a/object/store/memory/read_size.go b/object/store/memory/read_size.go deleted file mode 100644 index 7045bd61..00000000 --- a/object/store/memory/read_size.go +++ /dev/null @@ -1,13 +0,0 @@ -package memory - -import objectid "codeberg.org/lindenii/furgit/object/id" - -// ReadSize reads one object size. -func (store *Store) ReadSize(id objectid.ObjectID) (int64, error) { - _, size, err := store.ReadHeader(id) - if err != nil { - return 0, err - } - - return size, nil -} diff --git a/object/store/memory/refresh.go b/object/store/memory/refresh.go deleted file mode 100644 index 1e18eef3..00000000 --- a/object/store/memory/refresh.go +++ /dev/null @@ -1,6 +0,0 @@ -package memory - -// Refresh is a no-op for in-memory object stores. -func (store *Store) Refresh() error { - return nil -} diff --git a/object/store/memory/store.go b/object/store/memory/store.go deleted file mode 100644 index ff66da50..00000000 --- a/object/store/memory/store.go +++ /dev/null @@ -1,28 +0,0 @@ -package memory - -import ( - objectid "codeberg.org/lindenii/furgit/object/id" -) - -// Store is one in-memory object store. -// -// Labels: Close-Caller. -type Store struct { - algo objectid.Algorithm - objects map[objectid.ObjectID]storedObject -} - -// New builds one empty in-memory store for one object format. -func New(algo objectid.Algorithm) *Store { - return &Store{ - algo: algo, - objects: make(map[objectid.ObjectID]storedObject), - } -} - -// Close closes the in-memory store. -// -// Labels: MT-Unsafe. -func (store *Store) Close() error { - return nil -} diff --git a/object/store/memory/write_bytes.go b/object/store/memory/write_bytes.go deleted file mode 100644 index 241169d9..00000000 --- a/object/store/memory/write_bytes.go +++ /dev/null @@ -1,35 +0,0 @@ -package memory - -import ( - "bytes" - - objectheader "codeberg.org/lindenii/furgit/object/header" - objectid "codeberg.org/lindenii/furgit/object/id" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -// WriteBytesContent writes one typed object content byte slice. -func (store *Store) WriteBytesContent(ty objecttype.Type, content []byte) (objectid.ObjectID, error) { - id := store.algo.Sum(buildRawObject(ty, content)) - store.objects[id] = storedObject{ty: ty, content: append([]byte(nil), content...)} - - return id, nil -} - -// WriteBytesFull writes one full serialized object byte slice as "type size\0content". -func (store *Store) WriteBytesFull(raw []byte) (objectid.ObjectID, error) { - return store.WriteReaderFull(bytes.NewReader(raw)) -} - -func buildRawObject(ty objecttype.Type, body []byte) []byte { - header, ok := objectheader.Encode(ty, int64(len(body))) - if !ok { - panic("failed to encode object header") - } - - raw := make([]byte, len(header)+len(body)) - copy(raw, header) - copy(raw[len(header):], body) - - return raw -} diff --git a/object/store/memory/write_reader.go b/object/store/memory/write_reader.go deleted file mode 100644 index 0fa6a13f..00000000 --- a/object/store/memory/write_reader.go +++ /dev/null @@ -1,55 +0,0 @@ -package memory - -import ( - "errors" - "fmt" - "io" - - objectheader "codeberg.org/lindenii/furgit/object/header" - objectid "codeberg.org/lindenii/furgit/object/id" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -// WriteReaderContent writes one typed object content stream. -func (store *Store) WriteReaderContent(ty objecttype.Type, size int64, src io.Reader) (objectid.ObjectID, error) { - if size < 0 { - return objectid.ObjectID{}, fmt.Errorf("objectstore/memory: negative content size: %d", size) - } - - content, err := io.ReadAll(io.LimitReader(src, size+1)) - if err != nil { - return objectid.ObjectID{}, err - } - - switch { - case int64(len(content)) > size: - return objectid.ObjectID{}, errors.New("objectstore/memory: object content longer than declared size") - case int64(len(content)) < size: - return objectid.ObjectID{}, errors.New("objectstore/memory: object content shorter than declared size") - } - - return store.WriteBytesContent(ty, content) -} - -// WriteReaderFull writes one full serialized object stream as "type size\0content". -func (store *Store) WriteReaderFull(src io.Reader) (objectid.ObjectID, error) { - raw, err := io.ReadAll(src) - if err != nil { - return objectid.ObjectID{}, err - } - - ty, size, headerLen, ok := objectheader.Parse(raw) - if !ok { - return objectid.ObjectID{}, errors.New("objectstore/memory: malformed object header") - } - - content := raw[headerLen:] - if int64(len(content)) != size { - return objectid.ObjectID{}, errors.New("objectstore/memory: object header size/content mismatch") - } - - id := store.algo.Sum(raw) - store.objects[id] = storedObject{ty: ty, content: append([]byte(nil), content...)} - - return id, nil -} diff --git a/object/store/memory/write_test.go b/object/store/memory/write_test.go deleted file mode 100644 index 9f38a14b..00000000 --- a/object/store/memory/write_test.go +++ /dev/null @@ -1,192 +0,0 @@ -package memory_test - -import ( - "bytes" - "testing" - - "codeberg.org/lindenii/furgit/internal/testgit" - objectheader "codeberg.org/lindenii/furgit/object/header" - objectid "codeberg.org/lindenii/furgit/object/id" - "codeberg.org/lindenii/furgit/object/store/memory" - objecttype "codeberg.org/lindenii/furgit/object/type" -) - -func TestStoreWriteReaderContent(t *testing.T) { - t.Parallel() - testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper - store := memory.New(algo) - content := []byte("memory-content\n") - - gotID, err := store.WriteReaderContent(objecttype.TypeBlob, int64(len(content)), bytes.NewReader(content)) - if err != nil { - t.Fatalf("WriteReaderContent: %v", err) - } - - wantID := algo.Sum(buildRawObject(t, objecttype.TypeBlob, content)) - if gotID != wantID { - t.Fatalf("WriteReaderContent id = %s, want %s", gotID, wantID) - } - - gotType, gotContent, err := store.ReadBytesContent(gotID) - if err != nil { - t.Fatalf("ReadBytesContent: %v", err) - } - - if gotType != objecttype.TypeBlob { - t.Fatalf("ReadBytesContent type = %v, want %v", gotType, objecttype.TypeBlob) - } - - if !bytes.Equal(gotContent, content) { - t.Fatalf("ReadBytesContent content mismatch") - } - }) -} - -func TestStoreWriteReaderFull(t *testing.T) { - t.Parallel() - testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper - store := memory.New(algo) - content := []byte("memory-full\n") - raw := buildRawObject(t, objecttype.TypeBlob, content) - - gotID, err := store.WriteReaderFull(bytes.NewReader(raw)) - if err != nil { - t.Fatalf("WriteReaderFull: %v", err) - } - - wantID := algo.Sum(raw) - if gotID != wantID { - t.Fatalf("WriteReaderFull id = %s, want %s", gotID, wantID) - } - - gotRaw, err := store.ReadBytesFull(gotID) - if err != nil { - t.Fatalf("ReadBytesFull: %v", err) - } - - if !bytes.Equal(gotRaw, raw) { - t.Fatalf("ReadBytesFull mismatch") - } - }) -} - -func TestStoreWriteBytes(t *testing.T) { - t.Parallel() - testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper - store := memory.New(algo) - content := []byte("memory-bytes\n") - - gotID, err := store.WriteBytesContent(objecttype.TypeBlob, content) - if err != nil { - t.Fatalf("WriteBytesContent: %v", err) - } - - wantID := algo.Sum(buildRawObject(t, objecttype.TypeBlob, content)) - if gotID != wantID { - t.Fatalf("WriteBytesContent id = %s, want %s", gotID, wantID) - } - - raw := buildRawObject(t, objecttype.TypeBlob, content) - - gotID2, err := store.WriteBytesFull(raw) - if err != nil { - t.Fatalf("WriteBytesFull: %v", err) - } - - if gotID2 != wantID { - t.Fatalf("WriteBytesFull id = %s, want %s", gotID2, wantID) - } - }) -} - -func TestStoreWriteReaderValidationErrors(t *testing.T) { - t.Parallel() - testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper - t.Run("content overflow", func(t *testing.T) { - t.Parallel() - - store := memory.New(algo) - - _, err := store.WriteReaderContent(objecttype.TypeBlob, 1, bytes.NewReader([]byte("hello"))) - if err == nil { - t.Fatalf("expected error after overflow") - } - }) - - t.Run("content short", func(t *testing.T) { - t.Parallel() - - store := memory.New(algo) - - _, err := store.WriteReaderContent(objecttype.TypeBlob, 5, bytes.NewReader([]byte("x"))) - if err == nil { - t.Fatalf("expected error for short content") - } - }) - - t.Run("full malformed header", func(t *testing.T) { - t.Parallel() - - store := memory.New(algo) - - _, err := store.WriteReaderFull(bytes.NewReader([]byte("not-a-header"))) - if err == nil { - t.Fatalf("expected error for malformed header") - } - }) - - t.Run("full size mismatch", func(t *testing.T) { - t.Parallel() - - store := memory.New(algo) - - _, err := store.WriteReaderFull(bytes.NewReader([]byte("blob 1\x00hello"))) - if err == nil { - t.Fatalf("expected error after mismatch") - } - }) - - t.Run("bytes malformed header", func(t *testing.T) { - t.Parallel() - - store := memory.New(algo) - - _, err := store.WriteBytesFull([]byte("not-a-header")) - if err == nil { - t.Fatalf("expected error for malformed byte header") - } - }) - }) -} - -func TestBuildRawObjectMatchesObjectHeaderEncode(t *testing.T) { - t.Parallel() - - content := []byte("body") - raw := buildRawObject(t, objecttype.TypeBlob, content) - - header, ok := objectheader.Encode(objecttype.TypeBlob, int64(len(content))) - if !ok { - t.Fatalf("objectheader.Encode failed") - } - - want := append(append([]byte(nil), header...), content...) - if !bytes.Equal(raw, want) { - t.Fatalf("buildRawObject mismatch") - } -} - -func buildRawObject(tb testing.TB, ty objecttype.Type, body []byte) []byte { //nolint:unparam - tb.Helper() - - header, ok := objectheader.Encode(ty, int64(len(body))) - if !ok { - tb.Fatalf("objectheader.Encode(%v, %d) failed", ty, len(body)) - } - - raw := make([]byte, len(header)+len(body)) - copy(raw, header) - copy(raw[len(header):], body) - - return raw -} |
