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

This commit is contained in:
Paul Frazee 2015-06-25 13:42:10 -05:00
parent 93184f5b69
commit e64cf9e059
2 changed files with 35 additions and 10 deletions

View File

@ -1,6 +1,9 @@
var path = require('path') var path = require('path')
var multicb = require('multicb') var multicb = require('multicb')
var toPath = require('multiblob/util').toPath var toPath = require('multiblob/util').toPath
var createHash = require('multiblob/util').createHash
var pull = require('pull-stream')
var toPull = require('stream-to-pull-stream')
var querystring = require('querystring') var querystring = require('querystring')
var fs = require('fs') var fs = require('fs')
@ -43,16 +46,21 @@ module.exports = function (blobs_dir, checkout_dir) {
var filename = parsed.qs.name || parsed.qs.filename || parsed.hash var filename = parsed.qs.name || parsed.qs.filename || parsed.hash
// check if we have the blob, at the same time find an available filename // check if we have the blob, at the same time find an available filename
var done = multicb({ pluck: 1 }) var done = multicb()
fs.stat(toPath(blobs_dir, parsed.hash), done()) fs.stat(toPath(blobs_dir, parsed.hash), done())
findFreeCheckoutPath(filename, done()) findCheckoutDst(filename, parsed.hash, done())
done(function (err, res) { done(function (err, res) {
if (!res[0]) if (!res[0][1])
return cb({ notFound: true }) return cb({ notFound: true })
// do we need to copy?
var dst = res[1][1]
var nocopy = res[1][2]
if (nocopy)
return cb(null, dst)
// copy the file // copy the file
var src = toPath(blobs_dir, parsed.hash) var src = toPath(blobs_dir, parsed.hash)
var dst = res[1]
var read = fs.createReadStream(src) var read = fs.createReadStream(src)
var write = fs.createWriteStream(dst) var write = fs.createWriteStream(dst)
read.on('error', done) read.on('error', done)
@ -68,7 +76,8 @@ module.exports = function (blobs_dir, checkout_dir) {
} }
// helper to create a filename in checkout_dir that isnt already in use // helper to create a filename in checkout_dir that isnt already in use
function findFreeCheckoutPath (filename, cb) { // - cb(err, filepath, nocopy) - if nocopy==true, no need to do the copy operation
function findCheckoutDst (filename, hash, cb) {
var n = 1 var n = 1
var parsed = path.parse(filename) var parsed = path.parse(filename)
next() next()
@ -82,11 +91,25 @@ module.exports = function (blobs_dir, checkout_dir) {
} }
function next () { function next () {
var filepath = gen() var dst = gen()
fs.stat(filepath, function (err, stat) { // exists?
fs.stat(dst, function (err, stat) {
if (!stat) if (!stat)
return cb(null, filepath) return cb(null, dst, false)
next()
// yes, check its hash
var hasher = createHash()
pull(
toPull.source(fs.createReadStream(dst)),
hasher,
pull.onEnd(function () {
// if the hash matches, we're set
if (hasher.digest == hash)
return cb(null, dst, true)
// try next
next()
})
)
}) })
} }
} }

View File

@ -27,7 +27,9 @@
"dependencies": { "dependencies": {
"multiblob": "^1.4.3", "multiblob": "^1.4.3",
"multicb": "^1.1.0", "multicb": "^1.1.0",
"pull-stream": "^2.27.0",
"scuttlebot": "^4.2.3", "scuttlebot": "^4.2.3",
"ssb-config": "^1.0.3" "ssb-config": "^1.0.3",
"stream-to-pull-stream": "^1.6.1"
} }
} }