mirror of https://codeberg.org/pzp/pzp-db.git
172 lines
4.6 KiB
JavaScript
172 lines
4.6 KiB
JavaScript
const test = require('node:test')
|
|
const assert = require('node:assert')
|
|
const p = require('node:util').promisify
|
|
const Log = require('../../lib/log')
|
|
|
|
test('Log compaction', async (t) => {
|
|
await t.test('compact a log that does not have holes', async (t) => {
|
|
const file = '/tmp/pzp-db-log-compaction-test-' + Date.now() + '.log'
|
|
const log = Log(file, { blockSize: 15 })
|
|
|
|
const stats = await p(log.stats)()
|
|
assert.equal(stats.totalBytes, 0, 'stats.totalBytes (1)')
|
|
assert.equal(stats.deletedBytes, 0, 'stats.deletedBytes (1)')
|
|
|
|
const buf1 = Buffer.from('first')
|
|
const buf2 = Buffer.from('second')
|
|
|
|
const offset1 = await p(log.append)(buf1)
|
|
const offset2 = await p(log.append)(buf2)
|
|
await p(log.onDrain)()
|
|
assert('append two records')
|
|
|
|
const stats2 = await p(log.stats)()
|
|
assert.equal(stats2.totalBytes, 25, 'stats.totalBytes (2)')
|
|
assert.equal(stats2.deletedBytes, 0, 'stats.deletedBytes (2)')
|
|
|
|
const progressArr = []
|
|
log.compactionProgress((stats) => {
|
|
progressArr.push(stats)
|
|
})
|
|
|
|
await p(log.compact)()
|
|
|
|
assert.deepEqual(
|
|
progressArr,
|
|
[
|
|
{ percent: 0, done: false },
|
|
{ percent: 1, done: true, sizeDiff: 0, holesFound: 0 },
|
|
],
|
|
'progress events'
|
|
)
|
|
|
|
const stats3 = await p(log.stats)()
|
|
assert.equal(stats3.totalBytes, 25, 'stats.totalBytes (3)')
|
|
assert.equal(stats3.deletedBytes, 0, 'stats.deletedBytes (3)')
|
|
|
|
await new Promise((resolve, reject) => {
|
|
const arr = []
|
|
log.scan(
|
|
(offset, data, size) => {
|
|
arr.push(data)
|
|
},
|
|
(err) => {
|
|
if (err) return reject(err)
|
|
assert.deepEqual(arr, [buf1, buf2], 'both records exist')
|
|
resolve()
|
|
}
|
|
)
|
|
})
|
|
|
|
await p(log.close)()
|
|
})
|
|
|
|
await t.test('delete first record, compact, stream', async (t) => {
|
|
const file = '/tmp/pzp-db-log-compaction-test-' + Date.now() + '.log'
|
|
const log = Log(file, { blockSize: 15 })
|
|
|
|
const buf1 = Buffer.from('first')
|
|
const buf2 = Buffer.from('second')
|
|
|
|
const progressArr = []
|
|
log.compactionProgress((stats) => {
|
|
progressArr.push(stats)
|
|
})
|
|
|
|
const offset1 = await p(log.append)(buf1)
|
|
const offset2 = await p(log.append)(buf2)
|
|
await p(log.onDrain)()
|
|
assert('append two records')
|
|
|
|
const stats1 = await p(log.stats)()
|
|
assert.equal(stats1.totalBytes, 25, 'stats.totalBytes before')
|
|
assert.equal(stats1.deletedBytes, 0, 'stats.deletedBytes before')
|
|
|
|
await p(log.del)(offset1)
|
|
await p(log.onOverwritesFlushed)()
|
|
assert('delete first record')
|
|
|
|
await p(log.compact)()
|
|
|
|
assert.deepEqual(
|
|
progressArr,
|
|
[
|
|
{ percent: 0, done: false },
|
|
{ percent: 1, done: true, sizeDiff: 15, holesFound: 1 },
|
|
],
|
|
'progress events'
|
|
)
|
|
|
|
const stats2 = await p(log.stats)()
|
|
assert.equal(stats2.totalBytes, 10, 'stats.totalBytes after')
|
|
assert.equal(stats2.deletedBytes, 0, 'stats.deletedBytes after')
|
|
|
|
await new Promise((resolve, reject) => {
|
|
const arr = []
|
|
log.scan(
|
|
(offset, data, size) => {
|
|
arr.push(data)
|
|
},
|
|
(err) => {
|
|
if (err) return reject(err)
|
|
assert.deepEqual(arr, [buf2], 'only second record exists')
|
|
resolve()
|
|
}
|
|
)
|
|
})
|
|
|
|
await p(log.close)()
|
|
})
|
|
|
|
await t.test('delete last record, compact, stream', async (t) => {
|
|
const file = '/tmp/pzp-db-log-compaction-test-' + Date.now() + '.log'
|
|
const log = Log(file, { blockSize: 15 })
|
|
|
|
const buf1 = Buffer.from('first')
|
|
const buf2 = Buffer.from('second')
|
|
const buf3 = Buffer.from('third')
|
|
|
|
const offset1 = await p(log.append)(buf1)
|
|
const offset2 = await p(log.append)(buf2)
|
|
const offset3 = await p(log.append)(buf3)
|
|
await p(log.onDrain)()
|
|
assert('append three records')
|
|
|
|
await p(log.del)(offset3)
|
|
await p(log.onOverwritesFlushed)()
|
|
assert('delete third record')
|
|
|
|
await new Promise((resolve, reject) => {
|
|
const arr = []
|
|
log.scan(
|
|
(offset, data, size) => {
|
|
arr.push(data)
|
|
},
|
|
(err) => {
|
|
if (err) return reject(err)
|
|
assert.deepEqual(arr, [buf1, buf2, null], 'all blocks')
|
|
resolve()
|
|
}
|
|
)
|
|
})
|
|
|
|
await p(log.compact)()
|
|
|
|
await new Promise((resolve, reject) => {
|
|
const arr = []
|
|
log.scan(
|
|
(offset, data, size) => {
|
|
arr.push(data)
|
|
},
|
|
(err) => {
|
|
if (err) return reject(err)
|
|
assert.deepEqual(arr, [buf1, buf2], 'last block truncated away')
|
|
resolve()
|
|
}
|
|
)
|
|
})
|
|
|
|
await p(log.close)()
|
|
})
|
|
})
|