level-version

Versioned data for levelup.

Level Version

Create versioned data inside leveldb.

level-version wraps levelup in a similar way to level-sublevel works, where instead of assigning your keys a prefix, it postfixes your keys with a version stamp.

By default the versions are millisecond timestamps, but they can be anything you want. Either specify them manually or provide a default version generating function. For some of the features to work correctly the versions should lexically sort. In the initial version some features only support numeric versions, but with some modifications it should all be able to support non-numeric lexically ordered values.

It also includes GC options that let you control how many or how old of versions you want to keep around.

Works with level-sublevel instances.

 
var LevelUp = require("levelup")
var version = require("level-version")
 
var original = LevelUp("./my-db")
 
// writes to db will be versioned, writes to original will not 
var db = version(original)
 
// insert a record with the default version 
db.put(key, value, function (errversion) {
  /* ... */
})
 
// insert a record explicitly at version 10 
db.put(key, value, {version: 10}, function (errversion) {
  /* ... */
})
 
// batch insert a few records 
db.batch([
  {type: "put", key: "cat", value: "sleep"}, // default version 
  {type: "put", key: "cat", value: "play", version: 122},
  /* ... */
], function () {
  /* ... */
})
 
// get the most recent version of the key (synonymous with .getLast(k, cb)) 
db.get(key, function (errvalueversion) {
  /* ... */
})
 
// get the first (oldest) version of the key 
db.getFirst(key, function (errvalueversion) {
  /* ... */
})
 
// get a specific version 
db.get(key, {version: 10}, function (errvalueversion) {
  /* ... */
})
 
// remove an entry 
db.del(key, {version: 10}, function (errversion) {
  /* ... */
})
 
// a version stream for a single key between versions 100 and 1000 
db.createVersionStream(key, {minVersion: 100, maxVersion: 1000}).pipe(/* ... */)
 
// stream all keys, but only the most recent version of each 
db.createReadStream({versionLimit: 1}).pipe(/* ... */)
 

var db = version(leveldb [,options])


Construct a new levelup object with version as a wrapper. The original leveldb instance will remain unchanged. The wrapped object should behave almost identically to the original, except all put/get operations are version aware.

Garbage Collection options can be set in order to control how many versions of each record are retained.

  • gcMaxVersions [no default] When doing GC it will only keep gcMaxVersions newest versions of each key
  • gcMaxAge [no default] When doing GC only keep versions where Date.now() - gcMaxAge > version
  • gcFreqMs [60000] How often the GC runs to apply GC rules. Only runs if a gcMax* option is set.
  • gcBackup [no default] A level-version instance to stream culled records into
  • gcCallback [no default] A callback to execute when gc sweeps complete
  • defaultVersion: [Date.now] A function to provide the default version if none is specified.
  • delimiter: [\xff] The internal delimiter to use.

.put(key, value [, options] [, cb])


Insert a record into leveldb with a version stamp.

callback(err, version) -- version will be the version the record was saved with.

  • version: [defaultVersion()] The version stamp for the record. If not given, it will use the defaultVersion function to generate one.
  • standard levelup put options.

.get(key [, options] [, cb])


Retrieve a record from leveldb. If no version is specified, this is equivalent to getLast.

callback(err, value, version)

  • version: [scan for highest] The version stamp for the record. If not specified, it will find the version with the highest version.
  • standard levelup get options.

.getLast(key [, options] [, cb])


Retrieve the latest version of a record from leveldb. That is the version with the highest version number.

callback(err, value, version)

  • standard levelup get options.

.getFirst(key [, options] [, cb])


Retrieve the first version of a record from leveldb. That is the version with the lowest version number.

callback(err, value, version)

  • standard levelup get options.

.del(key [, options] [, cb])


Remove a version of a record from leveldb. You should generally always be specifying a version with del

callback(err, version) -- version will be the version of the record removed.

  • version: [defaultVersion()] The version stamp for the record. If not given, it will use the defaultVersion function to generate one. (I.e. specify a version)
  • standard levelup del options.

.createVersionStream(key [, options])


Stream versions of a key from highest to lowest version. I.e. newest first. Results in an objectMode stream where records are in the format {key: key, value: value, version: version}

  • minVersion: [default -Math.pow(2, 53)] The lowest version to return
  • maxVersion: [default Math.pow(2, 53)] The highest version to return
  • versionLimit: [no default] How many versions to return before ending the stream
  • standard levelup readstream options except start/end are ignored

.createReadStream(key [, options])


Stream versions of all records within options.start and options.end from highest to lowest version. I.e. newest first. Results in an objectMode stream where records are in the format {key: key, value: value, version: version}

  • minVersion: [default -Math.pow(2, 53)] The lowest version to return
  • maxVersion: [default Math.pow(2, 53)] The highest version to return
  • versionLimit: [no default] How many versions to return before ending the stream
  • standard levelup readstream options

.createValueStream(key [, options])


Identical to createReadStream but only values & versions will be returned.

.createKeyStream(key [, options])


Identical to createReadStream but only keys & versions will be returned.

.createWriteStream(key [, options])


Creates a writable stream suitable for writing to or deleting from a versioned leveldb.

var ws = db.createWriteStream()
ws.write({key: "cat", value: "meow", version: 12345})
ws.write({key: "dog", value: "woof"})
ws.write({type: "del", key: "fish", version: 2121})
ws.end()
  • standard levelup writesteram options

Garbage Collection


When creating your versioned db, you can specify options related to garbage collection. If you set a gcMaxVersions or gcMaxAge it will periodically scan through your db instance and delete any versions based on the criteria you've specified.

  • gcMaxVersions [no default] When doing GC it will only keep gcMaxVersions newest versions of each key
  • gcMaxAge [no default] When doing GC only keep versions where Date.now() - gcMaxAge > version
  • gcFreqMs [60000] How often the GC runs to apply GC rules. Only runs if a gcMax* option is set.
  • gcBackup [no default] A level-version instance to stream culled records into
  • gcCallback [no default] A callback to execute when gc sweeps complete

LICENSE

MIT