Skip to content

Commit

Permalink
simplify the Get()/GetMultiple() re-use GetRaw() for both (minio#179)
Browse files Browse the repository at this point in the history
Remember GetMultiple() must be used if your target is calling
PutMultiple(), without that the multiple events will not be
replayed.
  • Loading branch information
harshavardhana committed Nov 7, 2024
1 parent 25e34fd commit cefc43e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 45 deletions.
50 changes: 5 additions & 45 deletions internal/store/queuestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,61 +251,21 @@ func (store *QueueStore[I]) GetRaw(key Key) (raw []byte, err error) {

// Get - gets an item from the store.
func (store *QueueStore[I]) Get(key Key) (item I, err error) {
store.RLock()

defer func(store *QueueStore[I]) {
store.RUnlock()
if err != nil && !os.IsNotExist(err) {
// Upon error we remove the entry.
store.Del(key)
}
}(store)

var eventData []byte
eventData, err = os.ReadFile(filepath.Join(store.directory, key.String()))
items, err := store.GetMultiple(key)
if err != nil {
return item, err
}

if len(eventData) == 0 {
return item, os.ErrNotExist
}

if err = json.Unmarshal(eventData, &item); err != nil {
return item, err
}

return item, nil
return items[0], nil
}

// GetMultiple will read the multi payload file and fetch the items
func (store *QueueStore[I]) GetMultiple(key Key) (items []I, err error) {
store.RLock()

defer func(store *QueueStore[I]) {
store.RUnlock()
if err != nil && !os.IsNotExist(err) {
// Upon error we remove the entry.
store.Del(key)
}
}(store)

raw, err := os.ReadFile(filepath.Join(store.directory, key.String()))
raw, err := store.GetRaw(key)
if err != nil {
return
}

var decoder *jsoniter.Decoder
if key.Compress {
decodedBytes, err := s2.Decode(nil, raw)
if err != nil {
return nil, err
}
decoder = jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewReader(decodedBytes))
} else {
decoder = jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewReader(raw))
return nil, err
}

decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewReader(raw))
for decoder.More() {
var item I
if err := decoder.Decode(&item); err != nil {
Expand Down
70 changes: 70 additions & 0 deletions internal/store/queuestore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
package store

import (
"bytes"
"fmt"
"os"
"path/filepath"
"reflect"
"testing"

jsoniter "github.com/json-iterator/go"
"github.com/valyala/bytebufferpool"
)

type TestItem struct {
Expand Down Expand Up @@ -221,6 +225,72 @@ func TestQueueStoreListN(t *testing.T) {
}
}

func TestMultiplePutGetRaw(t *testing.T) {
defer func() {
if err := tearDownQueueStore(); err != nil {
t.Fatalf("Failed to tear down store; %v", err)
}
}()
store, err := setUpQueueStore(queueDir, 10)
if err != nil {
t.Fatalf("Failed to create a queue store; %v", err)
}
// TestItem{Name: "test-item", Property: "property"}
var items []TestItem
for i := 0; i < 10; i++ {
items = append(items, TestItem{
Name: fmt.Sprintf("test-item-%d", i),
Property: "property",
})
}

buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)

enc := jsoniter.ConfigCompatibleWithStandardLibrary.NewEncoder(buf)
for i := range items {
if err = enc.Encode(items[i]); err != nil {
t.Fatal(err)
}
}

if _, err := store.PutMultiple(items); err != nil {
t.Fatalf("failed to put multiple; %v", err)
}

keys := store.List()
if len(keys) != 1 {
t.Fatalf("expected len(keys)=1, but found %d", len(keys))
}

key := keys[0]
if !key.Compress {
t.Fatal("expected the item to be compressed")
}
if key.ItemCount != 10 {
t.Fatalf("expected itemcount=10 but found %v", key.ItemCount)
}

raw, err := store.GetRaw(key)
if err != nil {
t.Fatalf("unable to get multiple items; %v", err)
}

if !bytes.Equal(buf.Bytes(), raw) {
t.Fatalf("expected bytes: %d vs read bytes is wrong %d", len(buf.Bytes()), len(raw))
}

if err := store.Del(key); err != nil {
t.Fatalf("unable to Del; %v", err)
}

// Re-list
keys = store.List()
if len(keys) > 0 || err != nil {
t.Fatalf("Expected List() to return empty list and no error, got %v err: %v", keys, err)
}
}

func TestMultiplePutGets(t *testing.T) {
defer func() {
if err := tearDownQueueStore(); err != nil {
Expand Down

0 comments on commit cefc43e

Please sign in to comment.