aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorn-peugnet <n.peugnet@free.fr>2021-09-29 16:04:16 +0200
committern-peugnet <n.peugnet@free.fr>2021-09-29 16:04:16 +0200
commit5dad27953b9050f097b53227cfc29e3d3373fd97 (patch)
tree414a42e0cb6eaa47297b5e7824725e7415a823fe
parent575aa72ece3532fe264f126b023a775a14127cc1 (diff)
downloaddna-backup-5dad27953b9050f097b53227cfc29e3d3373fd97.tar.gz
dna-backup-5dad27953b9050f097b53227cfc29e3d3373fd97.zip
merge tryDeltaEncodeChunk and encodeTempChunk
to reuse the sketch calculation
-rw-r--r--README.md4
-rw-r--r--TODO.md2
-rw-r--r--repo.go34
3 files changed, 18 insertions, 22 deletions
diff --git a/README.md b/README.md
index dccbdce..7a13ded 100644
--- a/README.md
+++ b/README.md
@@ -93,10 +93,10 @@ On imagine le _DNA-Drive_ comme un segment de _pools_ :
1. Calculer sa _fingerprint_ (hash classique), si elle est présente dans la
_map_ : le stocker de manière dédupliquée (sous la forme d'identifiant
faisant référence au _chunk_ trouvé dans la map).
- 2. Si elle n'était pas présente, calculer son _sketch_ (hash de ressemblance),
+ 2. Sinon, calculer son _sketch_ (hash de ressemblance),
si il est présent dans la _map_, le stocker sous la forme de delta (calcul
de sa différence par rapport au _chunk_ trouvé dans la map).
- 3. Si il n'était pas présent, le stocker sous la forme de nouveau bloc (ajout
+ 3. Sinon, le stocker sous la forme de nouveau bloc (ajout
de sa _fingerprint_ et de son _sketch_ dans les _maps_ et stockage du
contenu complet dans un nouveau _chunk_).
6. Calcul des différences entre la nouvele version et la précédente pour les
diff --git a/TODO.md b/TODO.md
index 6402e18..6ace07e 100644
--- a/TODO.md
+++ b/TODO.md
@@ -50,7 +50,7 @@ priority 2
- [ ] use a symlink aware Walk function (easy enough)
- [ ] add quick progress bar to CLI
- [ ] `list` command to list versions
-- [ ] optional arg for `restore` to select the version to restore.
+- [ ] optional argument for `restore` to select the version to restore.
reunion 7/09
------------
diff --git a/repo.go b/repo.go
index d781b16..b9407fc 100644
--- a/repo.go
+++ b/repo.go
@@ -542,11 +542,10 @@ func contains(s []*ChunkId, id *ChunkId) bool {
return false
}
-func (r *Repo) findSimilarChunk(chunk Chunk) (*ChunkId, bool) {
+func (r *Repo) findSimilarChunk(sketch []uint64) (*ChunkId, bool) {
var similarChunks = make(map[ChunkId]int)
var max int
var similarChunk *ChunkId
- sketch, _ := sketch.SketchChunk(chunk.Reader(), r.pol, r.chunkSize, r.sketchWSize, r.sketchSfCount, r.sketchFCount)
for _, s := range sketch {
chunkIds, exists := r.sketches[s]
if !exists {
@@ -566,13 +565,17 @@ func (r *Repo) findSimilarChunk(chunk Chunk) (*ChunkId, bool) {
return similarChunk, max > 0
}
-func (r *Repo) tryDeltaEncodeChunk(temp BufferedChunk) (Chunk, bool) {
- id, found := r.findSimilarChunk(temp)
+// encodeTempChunk first tries to delta-encode the given chunk before attributing
+// it an Id and saving it into the fingerprints and sketches maps.
+func (r *Repo) encodeTempChunk(temp BufferedChunk, version int, last *uint64, storeQueue chan<- chunkData) (Chunk, bool) {
+ sk, _ := sketch.SketchChunk(temp.Reader(), r.pol, r.chunkSize, r.sketchWSize, r.sketchSfCount, r.sketchFCount)
+ id, found := r.findSimilarChunk(sk)
if found {
var buff bytes.Buffer
if err := r.differ.Diff(r.LoadChunkContent(id), temp.Reader(), &buff); err != nil {
logger.Error("trying delta encode chunk:", temp, "with source:", id, ":", err)
} else {
+ logger.Debugf("add new delta chunk of size %d", len(buff.Bytes()))
return &DeltaChunk{
repo: r,
Source: id,
@@ -581,21 +584,14 @@ func (r *Repo) tryDeltaEncodeChunk(temp BufferedChunk) (Chunk, bool) {
}, true
}
}
- return temp, false
-}
-
-// encodeTempChunk first tries to delta-encode the given chunk before attributing
-// it an Id and saving it into the fingerprints and sketches maps.
-func (r *Repo) encodeTempChunk(temp BufferedChunk, version int, last *uint64, storeQueue chan<- chunkData) (chunk Chunk, isDelta bool) {
- chunk, isDelta = r.tryDeltaEncodeChunk(temp)
- if isDelta {
- logger.Debug("add new delta chunk")
- return
- }
- if chunk.Len() == r.chunkSize {
+ if temp.Len() == r.chunkSize {
id := &ChunkId{Ver: version, Idx: *last}
*last++
- fp, sk := r.hashChunk(id, temp.Reader())
+ hasher := rabinkarp64.NewFromPol(r.pol)
+ io.Copy(hasher, temp.Reader())
+ fp := hasher.Sum64()
+ r.fingerprints[fp] = id
+ r.sketches.Set(sk, id)
storeQueue <- chunkData{
hashes: chunkHashes{fp, sk},
content: temp.Bytes(),
@@ -605,8 +601,8 @@ func (r *Repo) encodeTempChunk(temp BufferedChunk, version int, last *uint64, st
logger.Debug("add new chunk ", id)
return NewStoredChunk(r, id), false
}
- logger.Debug("add new partial chunk of size: ", chunk.Len())
- return
+ logger.Debug("add new partial chunk of size: ", temp.Len())
+ return temp, false
}
// encodeTempChunks encodes the current temporary chunks based on the value of the previous one.