- BaseKVStorage / BaseEventStorage / BaseDocumentStorage define the API once; implementations provide only raw primitives (client and server share an API) - Drop KV indexes, query planner, unique indexes; document stores take index fields - Escape every char <= '/' so child keys stay contiguous; skip-scan is now simple - Event-sourced documents = event storage + any document store for projections - New folder layout (kv-storage, event-storage, document-storage, utils); tests only in test/ Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
import { bench, describe } from 'vitest'
|
|
import { DocumentStorageInMemory } from '../src/document-storage/document-storage-in-memory.js'
|
|
import { EventSourcedDocumentStorage } from '../src/document-storage/event-sourced-document-storage.js'
|
|
import { EventStorageKV } from '../src/event-storage/event-storage-kv.js'
|
|
import { KVStorageInMemory } from '../src/kv-storage/kv-storage-in-memory.js'
|
|
import type { BaseDocumentStorage } from '../src/document-storage/base-document-storage.js'
|
|
|
|
const N = 10_000
|
|
const stores: [string, BaseDocumentStorage][] = [
|
|
['in-memory', new DocumentStorageInMemory({ indexes: { users: ['age'] } })],
|
|
['event-sourced', new EventSourcedDocumentStorage(new EventStorageKV(new KVStorageInMemory()), new DocumentStorageInMemory({ indexes: { users: ['age'] } }))],
|
|
]
|
|
for (const [name, docs] of stores) {
|
|
const users = docs.child('users')
|
|
for (let i = 0; i < N; i++) await users.set(`u${i}`, { name: `user ${i}`, age: i % 100, city: `c${i % 50}` })
|
|
let i = 0
|
|
describe(`documents (${name}) @ 10k`, () => {
|
|
bench('get', async () => {
|
|
await users.get(`u${i++ % N}`)
|
|
})
|
|
bench('update ($inc)', async () => {
|
|
await users.update(`u${i++ % N}`, { $inc: { logins: 1 } })
|
|
})
|
|
bench('find by indexed field (~100 hits)', async () => {
|
|
for await (const _ of users.find({ age: i++ % 100 })) {
|
|
}
|
|
})
|
|
bench('find by unindexed field (scan, ~200 hits)', async () => {
|
|
for await (const _ of users.find({ city: `c${i++ % 50}` })) {
|
|
}
|
|
})
|
|
})
|
|
}
|