Skip to content

Commit

Permalink
feat: implement .stat function
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jan 30, 2018
1 parent fc4cfb3 commit 3865142
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 2 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,20 @@ Sets the API address.

* `value` should be a [Multiaddr](https://github.com/multiformats/js-multiaddr) or a String representing a valid one.

### `repo.stat ([options], callback)`

Gets the repo status.

`options` is an object which might contain the key `human`, which is a boolean indicating whether or not the `repoSize` should be displayed in MiB or not.

`callback` is a function with the signature `function (err, stats)`, where `stats` is an Object with the following keys:

- `numObjects`
- `repoPath`
- `repoSize`
- `version`
- `storageMax`

## Notes

- [Explanation of how repo is structured](https://github.com/ipfs/js-ipfs-repo/pull/111#issuecomment-279948247)
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,22 @@
"dependencies": {
"async": "^2.6.0",
"base32.js": "~0.1.0",
"big.js": "^5.0.3",
"cids": "~0.5.2",
"interface-datastore": "~0.4.2",
"datastore-core": "~0.4.0",
"datastore-fs": "~0.4.2",
"datastore-level": "~0.7.0",
"debug": "^3.1.0",
"interface-datastore": "~0.4.2",
"ipfs-block": "~0.6.1",
"level-js": "timkuijsten/level.js#idbunwrapper",
"leveldown": "^1.7.2",
"lock-me": "^1.0.3",
"lodash.get": "^4.4.2",
"lodash.has": "^4.5.2",
"lodash.set": "^4.3.2",
"multiaddr": "^3.0.1"
"multiaddr": "^3.0.1",
"pull-stream": "^3.6.1"
},
"license": "MIT",
"contributors": [
Expand Down
14 changes: 14 additions & 0 deletions src/blockstore.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Block = require('ipfs-block')
const setImmediate = require('async/setImmediate')
const reject = require('async/reject')
const CID = require('cids')
const pull = require('pull-stream')

/**
* Transform a raw buffer to a base32 encoded key.
Expand Down Expand Up @@ -49,6 +50,19 @@ function maybeWithSharding (filestore, options, callback) {

function createBaseStore (store) {
return {
/**
* Query the store.
*
* @param {object} query
* @param {function(Error, Array)} callback
* @return {void}
*/
query (query, callback) {
pull(
store.query(query),
pull.collect(callback)
)
},
/**
* Get a single block by CID.
*
Expand Down
79 changes: 79 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const each = require('async/each')
const assert = require('assert')
const path = require('path')
const debug = require('debug')
const Big = require('big.js')
const pull = require('pull-stream')

const backends = require('./backends')
const version = require('./version')
Expand All @@ -17,6 +19,8 @@ const defaultOptions = require('./default-options')

const log = debug('repo')

const noLimit = Number.MAX_SAFE_INTEGER

const lockers = {
memory: require('./lock-memory'),
fs: require('./lock')
Expand Down Expand Up @@ -200,6 +204,81 @@ class IpfsRepo {
exists (callback) {
this.version.exists(callback)
}

/**
* Get repo status.
*
* @param {Object} options
* @param {Boolean} options.human
* @param {function(Error, Object)} callback
* @return {void}
*/
stat (options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
}

options = Object.assign({}, {human: false}, options)

parallel({
storageMax: (cb) => this.config.get('Datastore.StorageMax', (err, max) => {
if (err) {
cb(null, new Big(noLimit))
} else {
cb(null, new Big(max))
}
}),
version: (cb) => this.version.get(cb),
blocks: (cb) => this.blocks.query({}, (err, list) => {
list = list || []

const count = new Big(list.length)
let size = new Big(0)

list.forEach(block => {
size = size
.plus(block.value.byteLength)
.plus(block.key._buf.byteLength)
})

cb(err, {
count: count,
size: size
})
}),
datastore: (cb) => getSize(this.datastore, cb),
keys: (cb) => getSize(this.keys, cb)
}, (err, results) => {
if (err) return callback(err)

let size = results.blocks.size
.plus(results.datastore)
.plus(results.keys)

if (options.human) {
size = size.div(1048576)
}

callback(null, {
repoPath: this.path,
storageMax: results.storageMax,
version: results.version,
numObjects: results.blocks.count,
repoSize: size
})
})
}
}

function getSize (queryFn, callback) {
pull(
queryFn.query({}),
pull.reduce((sum, block) => {
return sum
.plus(block.value.byteLength)
.plus(block.key._buf.byteLength)
}, new Big(0), callback))
}

module.exports = IpfsRepo
Expand Down
1 change: 1 addition & 0 deletions test/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('IPFS Repo Tests onNode.js', () => {
require('./blockstore-test')(repo)
require('./datastore-test')(repo)
require('./keystore-test')(repo)
require('./stat-test')(repo)
if (!r.init) {
require('./interop-test')(repo)
}
Expand Down
46 changes: 46 additions & 0 deletions test/stat-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect

module.exports = (repo) => {
describe('stat', () => {
it('get stats', (done) => {
repo.stat((err, stats) => {
expect(err).to.not.exist()
expect(stats).to.exist()
expect(stats).to.have.property('numObjects')
expect(stats).to.have.property('version')
expect(stats).to.have.property('repoPath')
expect(stats).to.have.property('repoSize')
expect(stats).to.have.property('storageMax')

expect(stats.numObjects > '0').to.eql(true)
expect(stats.version > '0').to.eql(true)
expect(stats.repoSize > '0').to.eql(true)
expect(stats.storageMax > '0').to.eql(true)
done()
})
})

it('get human stats', (done) => {
repo.stat({human: true}, (err, stats) => {
expect(err).to.not.exist()
expect(stats).to.exist()
expect(stats).to.have.property('numObjects')
expect(stats).to.have.property('version')
expect(stats).to.have.property('repoPath')
expect(stats).to.have.property('repoSize')
expect(stats).to.have.property('storageMax')

expect(stats.numObjects > '0').to.eql(true)
expect(stats.version > '0').to.eql(true)
expect(stats.repoSize > '0').to.eql(true)
expect(stats.storageMax > '0').to.eql(true)
done()
})
})
})
}

0 comments on commit 3865142

Please sign in to comment.