Browse Source

blob checkouts no longer create another copy if an existing copy exists with the same content

Paul Frazee 5 years ago
parent
commit
e64cf9e059
2 changed files with 35 additions and 10 deletions
  1. 32
    9
      app/lib/blobs.js
  2. 3
    1
      package.json

+ 32
- 9
app/lib/blobs.js View File

@@ -1,6 +1,9 @@
1 1
 var path = require('path')
2 2
 var multicb = require('multicb')
3 3
 var toPath = require('multiblob/util').toPath
4
+var createHash = require('multiblob/util').createHash
5
+var pull = require('pull-stream')
6
+var toPull = require('stream-to-pull-stream')
4 7
 var querystring = require('querystring')
5 8
 var fs = require('fs')
6 9
 
@@ -43,16 +46,21 @@ module.exports = function (blobs_dir, checkout_dir) {
43 46
       var filename = parsed.qs.name || parsed.qs.filename || parsed.hash
44 47
 
45 48
       // check if we have the blob, at the same time find an available filename
46
-      var done = multicb({ pluck: 1 })
49
+      var done = multicb()
47 50
       fs.stat(toPath(blobs_dir, parsed.hash), done())
48
-      findFreeCheckoutPath(filename, done())
51
+      findCheckoutDst(filename, parsed.hash, done())
49 52
       done(function (err, res) {
50
-        if (!res[0])
53
+        if (!res[0][1])
51 54
           return cb({ notFound: true })
52 55
 
56
+        // do we need to copy?
57
+        var dst = res[1][1]
58
+        var nocopy = res[1][2]
59
+        if (nocopy)
60
+          return cb(null, dst)
61
+
53 62
         // copy the file
54 63
         var src = toPath(blobs_dir, parsed.hash)
55
-        var dst = res[1]
56 64
         var read = fs.createReadStream(src)
57 65
         var write = fs.createWriteStream(dst)
58 66
         read.on('error', done)
@@ -68,7 +76,8 @@ module.exports = function (blobs_dir, checkout_dir) {
68 76
   }
69 77
 
70 78
   // helper to create a filename in checkout_dir that isnt already in use
71
-  function findFreeCheckoutPath (filename, cb) {
79
+  // - cb(err, filepath, nocopy) - if nocopy==true, no need to do the copy operation
80
+  function findCheckoutDst (filename, hash, cb) {
72 81
     var n = 1
73 82
     var parsed = path.parse(filename)
74 83
     next()
@@ -82,11 +91,25 @@ module.exports = function (blobs_dir, checkout_dir) {
82 91
     }
83 92
 
84 93
     function next () {
85
-      var filepath = gen()
86
-      fs.stat(filepath, function (err, stat) {
94
+      var dst = gen()
95
+      // exists?
96
+      fs.stat(dst, function (err, stat) {
87 97
         if (!stat)
88
-          return cb(null, filepath)
89
-        next()
98
+          return cb(null, dst, false)
99
+
100
+        // yes, check its hash
101
+        var hasher = createHash()
102
+        pull(
103
+          toPull.source(fs.createReadStream(dst)),
104
+          hasher,
105
+          pull.onEnd(function () {
106
+            // if the hash matches, we're set
107
+            if (hasher.digest == hash)
108
+              return cb(null, dst, true)
109
+            // try next
110
+            next()
111
+          })
112
+        )
90 113
       })
91 114
     }
92 115
   }

+ 3
- 1
package.json View File

@@ -27,7 +27,9 @@
27 27
   "dependencies": {
28 28
     "multiblob": "^1.4.3",
29 29
     "multicb": "^1.1.0",
30
+    "pull-stream": "^2.27.0",
30 31
     "scuttlebot": "^4.2.3",
31
-    "ssb-config": "^1.0.3"
32
+    "ssb-config": "^1.0.3",
33
+    "stream-to-pull-stream": "^1.6.1"
32 34
   }
33 35
 }

Loading…
Cancel
Save