Files
kopia/internal/hashcache/hashcache_reader.go
Jarek Kowalski ce4d59d8bb added support for cancelling upload with Ctrl-C which marks the snapshot as incomplete
added --include-incomplete to 'backups' command
improved upload API, added support for better cancellation and upload limits
changed hashcache Reader and Writer to use interfaces
2017-08-10 20:27:31 -07:00

104 lines
1.8 KiB
Go

package hashcache
import (
"bufio"
"io"
"github.com/kopia/kopia/internal/jsonstream"
)
// Reader supports reading a stream of hash cache entries.
type Reader interface {
FindEntry(relativeName string) *Entry
CopyTo(w Writer) error
}
type reader struct {
reader *jsonstream.Reader
nextEntry *Entry
entry0 Entry
entry1 Entry
odd bool
first bool
}
// FindEntry looks for an entry with a given name in hash cache stream and returns it or nil if not found.
func (hcr *reader) FindEntry(relativeName string) *Entry {
for hcr.nextEntry != nil && isLess(hcr.nextEntry.Name, relativeName) {
hcr.readahead()
}
if hcr.nextEntry != nil && relativeName == hcr.nextEntry.Name {
e := hcr.nextEntry
hcr.nextEntry = nil
hcr.readahead()
return e
}
return nil
}
func (hcr *reader) CopyTo(w Writer) error {
for hcr.nextEntry != nil {
if err := w.WriteEntry(*hcr.nextEntry); err != nil {
return err
}
hcr.readahead()
}
return nil
}
func (hcr *reader) readahead() {
if hcr.reader != nil {
hcr.nextEntry = nil
e := hcr.nextManifestEntry()
*e = Entry{}
if err := hcr.reader.Read(e); err == nil {
hcr.nextEntry = e
}
}
if hcr.nextEntry == nil {
hcr.reader = nil
}
}
func (hcr *reader) nextManifestEntry() *Entry {
hcr.odd = !hcr.odd
if hcr.odd {
return &hcr.entry1
}
return &hcr.entry0
}
type nullReader struct {
}
func (*nullReader) FindEntry(relativeName string) *Entry {
return nil
}
func (*nullReader) CopyTo(w Writer) error {
return nil
}
// Open starts reading hash cache content.
func Open(r io.Reader) Reader {
if r == nil {
return &nullReader{}
}
jsr, err := jsonstream.NewReader(bufio.NewReader(r), hashCacheStreamType)
if err != nil {
return &nullReader{}
}
var hcr reader
hcr.reader = jsr
hcr.nextEntry = nil
hcr.first = true
hcr.readahead()
return &hcr
}