Skip to content
This repository has been archived by the owner on Jun 19, 2023. It is now read-only.

wire a context in most of the Blockstore/Datastore methods #55

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions arc_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ func newARCCachedBS(ctx context.Context, bs Blockstore, lruSize int) (*arccache,
return c, nil
}

func (b *arccache) DeleteBlock(k cid.Cid) error {
func (b *arccache) DeleteBlock(ctx context.Context, k cid.Cid) error {
if has, _, ok := b.hasCached(k); ok && !has {
return nil
}

b.arc.Remove(k) // Invalidate cache before deleting.
err := b.blockstore.DeleteBlock(k)
err := b.blockstore.DeleteBlock(ctx, k)
if err == nil {
b.cacheHave(k, false)
}
Expand Down Expand Up @@ -72,19 +72,19 @@ func (b *arccache) hasCached(k cid.Cid) (has bool, size int, ok bool) {
return false, -1, false
}

func (b *arccache) Has(k cid.Cid) (bool, error) {
func (b *arccache) Has(ctx context.Context, k cid.Cid) (bool, error) {
if has, _, ok := b.hasCached(k); ok {
return has, nil
}
has, err := b.blockstore.Has(k)
has, err := b.blockstore.Has(ctx, k)
if err != nil {
return false, err
}
b.cacheHave(k, has)
return has, nil
}

func (b *arccache) GetSize(k cid.Cid) (int, error) {
func (b *arccache) GetSize(ctx context.Context, k cid.Cid) (int, error) {
if has, blockSize, ok := b.hasCached(k); ok {
if !has {
// don't have it, return
Expand All @@ -96,7 +96,7 @@ func (b *arccache) GetSize(k cid.Cid) (int, error) {
}
// we have it but don't know the size, ask the datastore.
}
blockSize, err := b.blockstore.GetSize(k)
blockSize, err := b.blockstore.GetSize(ctx, k)
if err == ErrNotFound {
b.cacheHave(k, false)
} else if err == nil {
Expand All @@ -105,7 +105,7 @@ func (b *arccache) GetSize(k cid.Cid) (int, error) {
return blockSize, err
}

func (b *arccache) Get(k cid.Cid) (blocks.Block, error) {
func (b *arccache) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
if !k.Defined() {
log.Error("undefined cid in arc cache")
return nil, ErrNotFound
Expand All @@ -115,7 +115,7 @@ func (b *arccache) Get(k cid.Cid) (blocks.Block, error) {
return nil, ErrNotFound
}

bl, err := b.blockstore.Get(k)
bl, err := b.blockstore.Get(ctx, k)
if bl == nil && err == ErrNotFound {
b.cacheHave(k, false)
} else if bl != nil {
Expand All @@ -124,19 +124,19 @@ func (b *arccache) Get(k cid.Cid) (blocks.Block, error) {
return bl, err
}

func (b *arccache) Put(bl blocks.Block) error {
func (b *arccache) Put(ctx context.Context, bl blocks.Block) error {
if has, _, ok := b.hasCached(bl.Cid()); ok && has {
return nil
}

err := b.blockstore.Put(bl)
err := b.blockstore.Put(ctx, bl)
if err == nil {
b.cacheSize(bl.Cid(), len(bl.RawData()))
}
return err
}

func (b *arccache) PutMany(bs []blocks.Block) error {
func (b *arccache) PutMany(ctx context.Context, bs []blocks.Block) error {
var good []blocks.Block
for _, block := range bs {
// call put on block if result is inconclusive or we are sure that
Expand All @@ -145,7 +145,7 @@ func (b *arccache) PutMany(bs []blocks.Block) error {
good = append(good, block)
}
}
err := b.blockstore.PutMany(good)
err := b.blockstore.PutMany(ctx, good)
if err != nil {
return err
}
Expand Down
110 changes: 67 additions & 43 deletions arc_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ func untrap(cd *callbackDatastore) {
}

func TestRemoveCacheEntryOnDelete(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)

arc.Put(exampleBlock)
arc.Put(ctx, exampleBlock)

cd.Lock()
writeHitTheDatastore := false
Expand All @@ -58,88 +60,96 @@ func TestRemoveCacheEntryOnDelete(t *testing.T) {
writeHitTheDatastore = true
})

arc.DeleteBlock(exampleBlock.Cid())
arc.Put(exampleBlock)
arc.DeleteBlock(ctx, exampleBlock.Cid())
arc.Put(ctx, exampleBlock)
if !writeHitTheDatastore {
t.Fail()
}
}

func TestElideDuplicateWrite(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)

arc.Put(exampleBlock)
arc.Put(ctx, exampleBlock)
trap("write hit datastore", cd, t)
arc.Put(exampleBlock)
arc.Put(ctx, exampleBlock)
}

func TestHasRequestTriggersCache(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)

arc.Has(exampleBlock.Cid())
arc.Has(ctx, exampleBlock.Cid())
trap("has hit datastore", cd, t)
if has, err := arc.Has(exampleBlock.Cid()); has || err != nil {
if has, err := arc.Has(ctx, exampleBlock.Cid()); has || err != nil {
t.Fatal("has was true but there is no such block")
}

untrap(cd)
err := arc.Put(exampleBlock)
err := arc.Put(ctx, exampleBlock)
if err != nil {
t.Fatal(err)
}

trap("has hit datastore", cd, t)

if has, err := arc.Has(exampleBlock.Cid()); !has || err != nil {
if has, err := arc.Has(ctx, exampleBlock.Cid()); !has || err != nil {
t.Fatal("has returned invalid result")
}
}

func TestGetFillsCache(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)

if bl, err := arc.Get(exampleBlock.Cid()); bl != nil || err == nil {
if bl, err := arc.Get(ctx, exampleBlock.Cid()); bl != nil || err == nil {
t.Fatal("block was found or there was no error")
}

trap("has hit datastore", cd, t)

if has, err := arc.Has(exampleBlock.Cid()); has || err != nil {
if has, err := arc.Has(ctx, exampleBlock.Cid()); has || err != nil {
t.Fatal("has was true but there is no such block")
}
if _, err := arc.GetSize(exampleBlock.Cid()); err != ErrNotFound {
if _, err := arc.GetSize(ctx, exampleBlock.Cid()); err != ErrNotFound {
t.Fatal("getsize was true but there is no such block")
}

untrap(cd)

if err := arc.Put(exampleBlock); err != nil {
if err := arc.Put(ctx, exampleBlock); err != nil {
t.Fatal(err)
}

trap("has hit datastore", cd, t)

if has, err := arc.Has(exampleBlock.Cid()); !has || err != nil {
if has, err := arc.Has(ctx, exampleBlock.Cid()); !has || err != nil {
t.Fatal("has returned invalid result")
}
if blockSize, err := arc.GetSize(exampleBlock.Cid()); blockSize == -1 || err != nil {
if blockSize, err := arc.GetSize(ctx, exampleBlock.Cid()); blockSize == -1 || err != nil {
t.Fatal("getsize returned invalid result", blockSize, err)
}
}

func TestGetAndDeleteFalseShortCircuit(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)

arc.Has(exampleBlock.Cid())
arc.GetSize(exampleBlock.Cid())
arc.Has(ctx, exampleBlock.Cid())
arc.GetSize(ctx, exampleBlock.Cid())

trap("get hit datastore", cd, t)

if bl, err := arc.Get(exampleBlock.Cid()); bl != nil || err != ErrNotFound {
if bl, err := arc.Get(ctx, exampleBlock.Cid()); bl != nil || err != ErrNotFound {
t.Fatal("get returned invalid result")
}

if arc.DeleteBlock(exampleBlock.Cid()) != nil {
if arc.DeleteBlock(ctx, exampleBlock.Cid()) != nil {
t.Fatal("expected deletes to be idempotent")
}
}
Expand All @@ -151,9 +161,11 @@ func TestArcCreationFailure(t *testing.T) {
}

func TestInvalidKey(t *testing.T) {
ctx := context.Background()

arc, _, _ := createStores(t)

bl, err := arc.Get(cid.Cid{})
bl, err := arc.Get(ctx, cid.Cid{})

if bl != nil {
t.Fatal("blocks should be nil")
Expand All @@ -164,75 +176,85 @@ func TestInvalidKey(t *testing.T) {
}

func TestHasAfterSucessfulGetIsCached(t *testing.T) {
ctx := context.Background()

arc, bs, cd := createStores(t)

bs.Put(exampleBlock)
bs.Put(ctx, exampleBlock)

arc.Get(exampleBlock.Cid())
arc.Get(ctx, exampleBlock.Cid())

trap("has hit datastore", cd, t)
arc.Has(exampleBlock.Cid())
arc.Has(ctx, exampleBlock.Cid())
}

func TestGetSizeAfterSucessfulGetIsCached(t *testing.T) {
ctx := context.Background()

arc, bs, cd := createStores(t)

bs.Put(exampleBlock)
bs.Put(ctx, exampleBlock)

arc.Get(exampleBlock.Cid())
arc.Get(ctx, exampleBlock.Cid())

trap("has hit datastore", cd, t)
arc.GetSize(exampleBlock.Cid())
arc.GetSize(ctx, exampleBlock.Cid())
}

func TestGetSizeAfterSucessfulHas(t *testing.T) {
ctx := context.Background()

arc, bs, _ := createStores(t)

bs.Put(exampleBlock)
has, err := arc.Has(exampleBlock.Cid())
bs.Put(ctx, exampleBlock)
has, err := arc.Has(ctx, exampleBlock.Cid())
if err != nil {
t.Fatal(err)
}
if !has {
t.Fatal("expected to have block")
}

if size, err := arc.GetSize(exampleBlock.Cid()); err != nil {
if size, err := arc.GetSize(ctx, exampleBlock.Cid()); err != nil {
t.Fatal(err)
} else if size != len(exampleBlock.RawData()) {
t.Fatalf("expected size %d, got %d", len(exampleBlock.RawData()), size)
}
}

func TestGetSizeMissingZeroSizeBlock(t *testing.T) {
ctx := context.Background()

arc, bs, cd := createStores(t)
emptyBlock := blocks.NewBlock([]byte{})
missingBlock := blocks.NewBlock([]byte("missingBlock"))

bs.Put(emptyBlock)
bs.Put(ctx, emptyBlock)

arc.Get(emptyBlock.Cid())
arc.Get(ctx, emptyBlock.Cid())

trap("has hit datastore", cd, t)
if blockSize, err := arc.GetSize(emptyBlock.Cid()); blockSize != 0 || err != nil {
if blockSize, err := arc.GetSize(ctx, emptyBlock.Cid()); blockSize != 0 || err != nil {
t.Fatal("getsize returned invalid result")
}
untrap(cd)

arc.Get(missingBlock.Cid())
arc.Get(ctx, missingBlock.Cid())

trap("has hit datastore", cd, t)
if _, err := arc.GetSize(missingBlock.Cid()); err != ErrNotFound {
if _, err := arc.GetSize(ctx, missingBlock.Cid()); err != ErrNotFound {
t.Fatal("getsize returned invalid result")
}
}

func TestDifferentKeyObjectsWork(t *testing.T) {
ctx := context.Background()

arc, bs, cd := createStores(t)

bs.Put(exampleBlock)
bs.Put(ctx, exampleBlock)

arc.Get(exampleBlock.Cid())
arc.Get(ctx, exampleBlock.Cid())

trap("has hit datastore", cd, t)
cidstr := exampleBlock.Cid().String()
Expand All @@ -242,20 +264,22 @@ func TestDifferentKeyObjectsWork(t *testing.T) {
t.Fatal(err)
}

arc.Has(ncid)
arc.Has(ctx, ncid)
}

func TestPutManyCaches(t *testing.T) {
ctx := context.Background()

arc, _, cd := createStores(t)
arc.PutMany([]blocks.Block{exampleBlock})
arc.PutMany(ctx, []blocks.Block{exampleBlock})

trap("has hit datastore", cd, t)
arc.Has(exampleBlock.Cid())
arc.GetSize(exampleBlock.Cid())
arc.Has(ctx, exampleBlock.Cid())
arc.GetSize(ctx, exampleBlock.Cid())
untrap(cd)
arc.DeleteBlock(exampleBlock.Cid())
arc.DeleteBlock(ctx, exampleBlock.Cid())

arc.Put(exampleBlock)
arc.Put(ctx, exampleBlock)
trap("PunMany has hit datastore", cd, t)
arc.PutMany([]blocks.Block{exampleBlock})
arc.PutMany(ctx, []blocks.Block{exampleBlock})
}
Loading