Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP webkitFileSystem backend #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,9 @@ export default [
getConfig('src/indexeddb/backend.js', 'indexeddb-backend.js'),
getConfig('src/indexeddb/main-thread.js', 'indexeddb-main-thread.js'),
getConfig('src/indexeddb/backend.js', 'indexeddb-backend.js', true),
getConfig('src/indexeddb/main-thread.js', 'indexeddb-main-thread.js', true)
getConfig('src/indexeddb/main-thread.js', 'indexeddb-main-thread.js', true),
getConfig('src/webkitFileSystem/backend.js', 'webkitFileSystem-backend.js'),
getConfig('src/webkitFileSystem/main-thread.js', 'webkitFileSystem-main-thread.js'),
getConfig('src/webkitFileSystem/backend.js', 'webkitFileSystem-backend.js', true),
getConfig('src/webkitFileSystem/main-thread.js', 'webkitFileSystem-main-thread.js', true)
];
10 changes: 7 additions & 3 deletions src/examples/bench/main.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ import initSqlJs from '@jlongster/sql.js';
import { SQLiteFS } from '../..';
import MemoryBackend from '../../memory/backend';
import IndexedDBBackend from '../../indexeddb/backend';
import webkitFileSystemBackend from '../../webkitFileSystem/backend';
import * as queries from './queries';
import * as rawIDBQueries from './queries-raw-idb';

// Various global state for the demo
let currentBackendType = 'idb';
let cacheSize = 0;
let pageSize = 4096;
let dbName = `db21.sqlite`;
let dbName = `db23.sqlite`;
let recordProfile = false;
let useRawIDB = false;

let memoryBackend = new MemoryBackend({});
let idbBackend = new IndexedDBBackend();
let fsBackend = new webkitFileSystemBackend();
let sqlFS;

// Helper methods
Expand All @@ -23,7 +25,7 @@ let SQL = null;
async function init() {
if (SQL == null) {
SQL = await initSqlJs({ locateFile: file => file });
sqlFS = new SQLiteFS(SQL.FS, idbBackend);
sqlFS = new SQLiteFS(SQL.FS, fsBackend);
SQL.register_for_idb(sqlFS);

if (typeof SharedArrayBuffer === 'undefined') {
Expand Down Expand Up @@ -172,7 +174,7 @@ async function populateSmall() {
async function populateLarge() {
clearTimings();

let count = 400000;
let count = 50000;
if (currentBackendType === 'memory') {
output(
'Cannot write 1,000,000 items to memory backend, reducing to 100,000'
Expand Down Expand Up @@ -329,6 +331,8 @@ if (typeof self !== 'undefined') {
// but it works for the demo
if (currentBackendType === 'memory') {
sqlFS.backend = memoryBackend;
} else if (currentBackendType === 'fs') {
sqlFS.backend = fsBackend;
} else {
sqlFS.backend = idbBackend;
}
Expand Down
1 change: 0 additions & 1 deletion src/indexeddb/backend.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { File } from '../sqlite-file';
import * as perf from 'perf-deets';
import { LOCK_TYPES, getPageSize } from '../sqlite-util';
import { FileOps } from './file-ops';
import { FileOpsFallback } from './file-ops-fallback';

Expand Down
2 changes: 1 addition & 1 deletion src/indexeddb/file-ops.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Reader, Writer } from './shared-channel';
import { Reader, Writer } from '../shared-channel';

function positionToKey(pos, blockSize) {
// We are forced to round because of floating point error. `pos`
Expand Down
2 changes: 1 addition & 1 deletion src/indexeddb/worker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Reader, Writer } from './shared-channel';
import { Reader, Writer } from '../shared-channel';
import * as perf from 'perf-deets';
import { LOCK_TYPES, isSafeToWrite } from '../sqlite-util';

Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion src/sqlite-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export class File {
open() {
this.ops.open();
let meta = this.ops.readMeta();
console.log('got meta', meta);

// It's possible that `setattr` has already been called if opening
// the file in a mode that truncates it to 0
Expand Down Expand Up @@ -216,7 +217,7 @@ export class File {
}

write(bufferView, offset, length, position) {
// console.log('writing', this.filename, offset, length, position);
console.log('writing', this.filename, offset, length, position);

if (this.meta.blockSize == null) {
// We don't have a block size yet (an empty file). The first
Expand Down
100 changes: 100 additions & 0 deletions src/webkitFileSystem/backend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { File } from '../sqlite-file';
import { getPageSize } from '../sqlite-util';
import * as perf from 'perf-deets';

class FileOps {
constructor(filename, rootEntry) {
this.filename = filename;
this.rootEntry = rootEntry;
}

getDatabaseName() {
return this.filename.replace(/\//g, '-');
}

lock(lockType) {
return true;
}

unlock(lockType) {
return true;
}

delete() {
console.log('deleting');
this.entry.remove();
}

open() {
this.entry = this.rootEntry.getFile(this.getDatabaseName(), {
create: true
});
}

close() {
// close
}

readMeta() {
let file = this.entry.file();
let reader = new FileReaderSync();

let blockSize = null;
if (file.size > 0) {
let data = reader.readAsArrayBuffer(file.slice(16, 18));
let arr = new Uint16Array(data);
blockSize = arr[0] * 256;
}

return { size: file.size, blockSize: blockSize == 0 ? null : blockSize };
}

writeMeta(meta) {
let writer = this.entry.createWriter();
writer.truncate(meta.size);
return 0;
}

readBlocks(positions, blockSize) {
let res = [];
let file = this.entry.file();
let reader = new FileReaderSync();
for (let pos of positions) {
let data = reader.readAsArrayBuffer(file.slice(pos, pos + blockSize));
res.push({
pos,
data: data.byteLength === 0 ? new ArrayBuffer(blockSize) : data
});
}
return res;
}

writeBlocks(writes, blockSize) {
for (let write of writes) {
let writer = this.entry.createWriter();
writer.seek(write.pos);
writer.write(new Blob([write.data], { type: 'octet/stream' }));
}
return 0;
}
}

export default class webkitFileSystemBackend {
constructor() {
// TODO: need to do `navigator.webkitPersistentStorage.requestQuota(10000000, function (quota) { console.log(quota) })`
this.FS = self.webkitRequestFileSystemSync(self.PERSISTENT, 100000);
this.rootEntry = this.FS.root.getDirectory('dbs', { create: true });
}

createFile(filename) {
return new File(filename, new FileOps(filename, this.rootEntry));
}

startProfile() {
perf.start();
}

stopProfile() {
perf.stop();
}
}