mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-25 11:39:32 -05:00
de76d37f09
* Add HasMany() to the ChunkStore interface We'll need this as a part of #3180 * Rip out hinting The hinting mechanism used to assist in server-side validation of values served us well, but now it's in the way of building a more suitable validation strategy. Tear it out and go without validation for a hot minute until #3180 gets done. Fixes #3178 * Implement server-side lazy ref validation The server, when handling writeValue, now just keeps track of all the refs it sees in the novel chunks coming from the client. Once it's processed all the incoming chunks, it just does a big bulk HasMany to determine if any of them aren't present in the storage backend. Fixes #3180 * Remove chunk-write-order requirements With our old validation strategy, it was critical that chunk graphs be written bottom-up, during both novel value creation and sync. With the strategy implemented in #3180, this is no longer required, which lets us get rid of a bunch of machinery: 1) The reverse-order hack in httpBatchStore 2) the EnumerationOrder stuff in NomsBlockCache 3) the orderedPutCache in datas/ 4) the refHeight arg on SchedulePut() Fixes #2982
118 lines
2.2 KiB
Go
118 lines
2.2 KiB
Go
// Copyright 2016 Attic Labs, Inc. All rights reserved.
|
|
// Licensed under the Apache License, version 2.0:
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package chunks
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/attic-labs/noms/go/constants"
|
|
"github.com/attic-labs/noms/go/d"
|
|
"github.com/attic-labs/noms/go/hash"
|
|
)
|
|
|
|
// An in-memory implementation of store.ChunkStore. Useful mainly for tests.
|
|
type MemoryStore struct {
|
|
data map[hash.Hash]Chunk
|
|
memoryRootTracker
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func NewMemoryStore() *MemoryStore {
|
|
return &MemoryStore{}
|
|
}
|
|
|
|
func (ms *MemoryStore) Get(h hash.Hash) Chunk {
|
|
ms.mu.RLock()
|
|
defer ms.mu.RUnlock()
|
|
if c, ok := ms.data[h]; ok {
|
|
return c
|
|
}
|
|
return EmptyChunk
|
|
}
|
|
|
|
func (ms *MemoryStore) GetMany(hashes hash.HashSet, foundChunks chan *Chunk) {
|
|
for h := range hashes {
|
|
c := ms.Get(h)
|
|
if !c.IsEmpty() {
|
|
foundChunks <- &c
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (ms *MemoryStore) Has(r hash.Hash) bool {
|
|
ms.mu.RLock()
|
|
defer ms.mu.RUnlock()
|
|
if ms.data == nil {
|
|
return false
|
|
}
|
|
_, ok := ms.data[r]
|
|
return ok
|
|
}
|
|
|
|
func (ms *MemoryStore) HasMany(hashes hash.HashSet) hash.HashSet {
|
|
present := hash.HashSet{}
|
|
for h := range hashes {
|
|
if ms.Has(h) {
|
|
present.Insert(h)
|
|
}
|
|
}
|
|
return present
|
|
}
|
|
|
|
func (ms *MemoryStore) Version() string {
|
|
return constants.NomsVersion
|
|
}
|
|
|
|
func (ms *MemoryStore) Put(c Chunk) {
|
|
ms.mu.Lock()
|
|
defer ms.mu.Unlock()
|
|
if ms.data == nil {
|
|
ms.data = map[hash.Hash]Chunk{}
|
|
}
|
|
ms.data[c.Hash()] = c
|
|
}
|
|
|
|
func (ms *MemoryStore) PutMany(chunks []Chunk) {
|
|
for _, c := range chunks {
|
|
ms.Put(c)
|
|
}
|
|
}
|
|
|
|
func (ms *MemoryStore) Len() int {
|
|
ms.mu.RLock()
|
|
defer ms.mu.RUnlock()
|
|
return len(ms.data)
|
|
}
|
|
|
|
func (ms *MemoryStore) Flush() {}
|
|
|
|
func (ms *MemoryStore) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func NewMemoryStoreFactory() Factory {
|
|
return &MemoryStoreFactory{map[string]*MemoryStore{}}
|
|
}
|
|
|
|
type MemoryStoreFactory struct {
|
|
stores map[string]*MemoryStore
|
|
}
|
|
|
|
func (f *MemoryStoreFactory) CreateStore(ns string) ChunkStore {
|
|
if f.stores == nil {
|
|
d.Panic("Cannot use MemoryStore after Shutter().")
|
|
}
|
|
if cs, present := f.stores[ns]; present {
|
|
return cs
|
|
}
|
|
f.stores[ns] = NewMemoryStore()
|
|
return f.stores[ns]
|
|
}
|
|
|
|
func (f *MemoryStoreFactory) Shutter() {
|
|
f.stores = map[string]*MemoryStore{}
|
|
}
|