idstore.go 1.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package blockstore

import (
	"context"

	blocks "github.com/ipfs/go-block-format"
	cid "github.com/ipfs/go-cid"
	mh "github.com/multiformats/go-multihash"
)

// idstore wraps a BlockStore to add support for identity hashes
type idstore struct {
	bs Blockstore
}

Kevin Atkinson's avatar
Kevin Atkinson committed
16
func NewIdStore(bs Blockstore) Blockstore {
17 18 19
	return &idstore{bs}
}

20
func extractContents(k cid.Cid) (bool, []byte) {
Steven Allen's avatar
Steven Allen committed
21 22 23 24 25
	// Pre-check by calling Prefix(), this much faster than extracting the hash.
	if k.Prefix().MhType != mh.IDENTITY {
		return false, nil
	}

26 27 28 29 30 31 32
	dmh, err := mh.Decode(k.Hash())
	if err != nil || dmh.Code != mh.ID {
		return false, nil
	}
	return true, dmh.Digest
}

33
func (b *idstore) DeleteBlock(k cid.Cid) error {
34 35 36 37 38 39 40
	isId, _ := extractContents(k)
	if isId {
		return nil
	}
	return b.bs.DeleteBlock(k)
}

41
func (b *idstore) Has(k cid.Cid) (bool, error) {
42 43 44 45 46 47 48
	isId, _ := extractContents(k)
	if isId {
		return true, nil
	}
	return b.bs.Has(k)
}

49
func (b *idstore) GetSize(k cid.Cid) (int, error) {
50 51 52 53 54 55 56
	isId, bdata := extractContents(k)
	if isId {
		return len(bdata), nil
	}
	return b.bs.GetSize(k)
}

57
func (b *idstore) Get(k cid.Cid) (blocks.Block, error) {
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
	isId, bdata := extractContents(k)
	if isId {
		return blocks.NewBlockWithCid(bdata, k)
	}
	return b.bs.Get(k)
}

func (b *idstore) Put(bl blocks.Block) error {
	isId, _ := extractContents(bl.Cid())
	if isId {
		return nil
	}
	return b.bs.Put(bl)
}

func (b *idstore) PutMany(bs []blocks.Block) error {
	toPut := make([]blocks.Block, 0, len(bs))
	for _, bl := range bs {
		isId, _ := extractContents(bl.Cid())
		if isId {
			continue
		}
		toPut = append(toPut, bl)
	}
	return b.bs.PutMany(toPut)
}

func (b *idstore) HashOnRead(enabled bool) {
	b.bs.HashOnRead(enabled)
}

89
func (b *idstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
90 91
	return b.bs.AllKeysChan(ctx)
}