mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-12 10:32:27 -06:00
Using ChunkStore.PutMany() means that the DataStore server code can detect when the ChunkStore it's writing to can't handle the amount of data being pushed. This patch reports that status back across the wire to the client that's attempting to write a Value graph. Due to Issue #1259, the only thing the client can currently do is retry the entire batch, but we hope to do better in the future.
73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package chunks
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
|
|
"github.com/attic-labs/noms/d"
|
|
"github.com/attic-labs/noms/ref"
|
|
)
|
|
|
|
// ReadThroughStore is a store that consists of two other stores. A caching and
|
|
// a backing store. All reads check the caching store first and if the ref is
|
|
// present there the caching store is used. If not present the backing store is
|
|
// used and the value gets cached in the caching store. All writes go directly
|
|
// to the backing store.
|
|
type ReadThroughStore struct {
|
|
io.Closer
|
|
cachingStore ChunkStore
|
|
backingStore ChunkStore
|
|
putCount int
|
|
}
|
|
|
|
func NewReadThroughStore(cachingStore ChunkStore, backingStore ChunkStore) ReadThroughStore {
|
|
return ReadThroughStore{ioutil.NopCloser(nil), cachingStore, backingStore, 0}
|
|
}
|
|
|
|
func (rts ReadThroughStore) Get(ref ref.Ref) Chunk {
|
|
c := rts.cachingStore.Get(ref)
|
|
if !c.IsEmpty() {
|
|
return c
|
|
}
|
|
c = rts.backingStore.Get(ref)
|
|
if c.IsEmpty() {
|
|
return c
|
|
}
|
|
|
|
rts.cachingStore.Put(c)
|
|
return c
|
|
}
|
|
|
|
func (rts ReadThroughStore) Has(ref ref.Ref) bool {
|
|
return rts.cachingStore.Has(ref) || rts.backingStore.Has(ref)
|
|
}
|
|
|
|
func (rts ReadThroughStore) Put(c Chunk) {
|
|
rts.backingStore.Put(c)
|
|
rts.cachingStore.Put(c)
|
|
}
|
|
|
|
func (rts ReadThroughStore) PutMany(chunks []Chunk) BackpressureError {
|
|
bpe := rts.backingStore.PutMany(chunks)
|
|
lookup := make(map[ref.Ref]bool, len(bpe))
|
|
for _, r := range bpe {
|
|
lookup[r] = true
|
|
}
|
|
toPut := make([]Chunk, 0, len(chunks)-len(bpe))
|
|
for _, c := range chunks {
|
|
if lookup[c.Ref()] {
|
|
toPut = append(toPut, c)
|
|
}
|
|
}
|
|
d.Chk.NoError(rts.cachingStore.PutMany(toPut))
|
|
return bpe
|
|
}
|
|
|
|
func (rts ReadThroughStore) Root() ref.Ref {
|
|
return rts.backingStore.Root()
|
|
}
|
|
|
|
func (rts ReadThroughStore) UpdateRoot(current, last ref.Ref) bool {
|
|
return rts.backingStore.UpdateRoot(current, last)
|
|
}
|