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  }