github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/nbs/cache.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package nbs 23 24 import ( 25 "context" 26 "errors" 27 "io/ioutil" 28 "os" 29 30 "github.com/dolthub/dolt/go/store/chunks" 31 "github.com/dolthub/dolt/go/store/hash" 32 "github.com/dolthub/dolt/go/store/types" 33 ) 34 35 const ( 36 defaultCacheMemTableSize uint64 = 1 << 27 // 128MiB 37 ) 38 39 func NewCache(ctx context.Context) (*NomsBlockCache, error) { 40 dir, err := ioutil.TempDir("", "") 41 42 if err != nil { 43 return nil, err 44 } 45 46 store, err := NewLocalStore(ctx, types.Format_Default.VersionString(), dir, defaultCacheMemTableSize) 47 48 if err != nil { 49 return nil, err 50 } 51 52 return &NomsBlockCache{store, dir}, nil 53 } 54 55 // NomsBlockCache holds Chunks, allowing them to be retrieved by hash or enumerated in hash order. 56 type NomsBlockCache struct { 57 chunks *NomsBlockStore 58 dbDir string 59 } 60 61 // Insert stores c in the cache. 62 func (nbc *NomsBlockCache) Insert(ctx context.Context, c chunks.Chunk) error { 63 success := nbc.chunks.addChunk(ctx, addr(c.Hash()), c.Data()) 64 65 if !success { 66 return errors.New("failed to add chunk") 67 } 68 69 return nil 70 } 71 72 // Has checks if the chunk referenced by hash is in the cache. 73 func (nbc *NomsBlockCache) Has(ctx context.Context, hash hash.Hash) (bool, error) { 74 return nbc.chunks.Has(ctx, hash) 75 } 76 77 // HasMany returns a set containing the members of hashes present in the 78 // cache. 79 func (nbc *NomsBlockCache) HasMany(ctx context.Context, hashes hash.HashSet) (hash.HashSet, error) { 80 return nbc.chunks.HasMany(ctx, hashes) 81 } 82 83 // Get retrieves the chunk referenced by hash. If the chunk is not present, 84 // Get returns the empty Chunk. 85 func (nbc *NomsBlockCache) Get(ctx context.Context, hash hash.Hash) (chunks.Chunk, error) { 86 return nbc.chunks.Get(ctx, hash) 87 } 88 89 // GetMany gets the Chunks with |hashes| from the store. On return, 90 // |foundChunks| will have been fully sent all chunks which have been 91 // found. Any non-present chunks will silently be ignored. 92 func (nbc *NomsBlockCache) GetMany(ctx context.Context, hashes hash.HashSet, found func(*chunks.Chunk)) error { 93 return nbc.chunks.GetMany(ctx, hashes, found) 94 } 95 96 // Count returns the number of items in the cache. 97 func (nbc *NomsBlockCache) Count() (uint32, error) { 98 return nbc.chunks.Count() 99 } 100 101 // Destroy drops the cache and deletes any backing storage. 102 func (nbc *NomsBlockCache) Destroy() error { 103 chunkErr := nbc.chunks.Close() 104 remErr := os.RemoveAll(nbc.dbDir) 105 106 if chunkErr != nil { 107 return chunkErr 108 } 109 110 return remErr 111 }