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

Developer demo of alternate wiki store implementation #7329

Draft
wants to merge 76 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
fdec12f
Initial commit
Jermolene Mar 4, 2023
7fdd8a5
Merge branch 'master' into demo-alternate-store
Jermolene May 10, 2023
6233710
Merge branch 'master' into demo-alternate-store
Jermolene May 10, 2023
b6bc197
Remove unneeded override
Jermolene May 10, 2023
3561318
Merge branch 'master' into demo-alternate-store
Jermolene Jun 22, 2023
1d0b928
Incorporate @joshuafontany's plain JS wiki implementation
Jermolene Jun 22, 2023
544e079
Proof of concept of instantiating sqlite3 without needing external de…
Jermolene Jun 22, 2023
0546a14
Restructure the sqlite3 store as a separate plugin
Jermolene Jun 22, 2023
146a22b
Make rawmarkup code dynamically load dependencies
Jermolene Jun 22, 2023
449e227
Test code to exercise the database
Jermolene Jun 23, 2023
6f24f33
Include sqlite3 in the empty edition
Jermolene Jun 23, 2023
c43bc8f
Start prototyping some tiddler operations in sql
Jermolene Jun 23, 2023
831fb39
Tiddler sql function tests should show custom field
Jermolene Jun 23, 2023
8690936
Cleanup and clarify
Jermolene Jun 23, 2023
9427cf7
Additional method to retrieve all titles
Jermolene Jun 23, 2023
9ac21f1
Simplify the plain JS store implementation
Jermolene Jun 25, 2023
7e60726
Wire the sql functions into the wiki object
Jermolene Jun 25, 2023
9cb8721
Use sql functions for processing shadow tiddlers
Jermolene Jun 27, 2023
ede5f1e
Prepare the save tiddler query
Jermolene Jun 28, 2023
8399538
Merge branch 'master' into demo-alternate-store
Jermolene Jun 28, 2023
2099c4f
Turn on performance instrumentation for testing
Jermolene Jun 28, 2023
12a19bb
Remove instrumentation
Jermolene Jun 28, 2023
87213f2
Refactpr sql-wiki-store into two files
Jermolene Jun 29, 2023
6ded5e6
Merge branch 'master' into demo-alternate-store
Jermolene Jun 29, 2023
b29af44
Fix typo
Jermolene Jun 29, 2023
1f4be3e
I experimented with custom collations to match JS sort order, but 5x …
Jermolene Jun 30, 2023
687b1df
Merge branch 'master' into demo-alternate-store
Jermolene Jun 30, 2023
71c02e5
Merge branch 'master' into demo-alternate-store
Jermolene Jul 1, 2023
2d229e2
Add logging utility
Jermolene Jul 6, 2023
9e190a4
Use a temporary database so that multiple wiki stores can coexist
Jermolene Jul 6, 2023
21ef2d7
Make the tests work in the browser
Jermolene Jul 6, 2023
f3bc32a
Merge branch 'master' into demo-alternate-store
Jermolene Jul 6, 2023
d2e21dd
Add a custom collator that matches JS ordering
Jermolene Jul 7, 2023
64ffa52
Write tiddlers with string fields
Jermolene Jul 7, 2023
b557dea
Update comment
Jermolene Jul 7, 2023
e3255a4
Merge branch 'master' into demo-alternate-store
Jermolene Jul 13, 2023
f48bddb
Merge branch 'master' into demo-alternate-store
Jermolene Jul 13, 2023
709669b
Merge branch 'master' into demo-alternate-store
Jermolene Jul 14, 2023
cc2cd20
Add tags tables and tag indexer and make custom collator be optional
Jermolene Jul 18, 2023
83e7d32
Merge branch 'master' into demo-alternate-store
Jermolene Jul 18, 2023
979a1f7
Introduce sql console
Jermolene Jul 18, 2023
88c8c2c
SQL console - process query on enter key
Jermolene Jul 19, 2023
b4fe896
Styling for SQL console
Jermolene Jul 19, 2023
09b0e28
Style update for sql console
Jermolene Jul 19, 2023
2cd2a05
Fix tag saving
Jermolene Jul 19, 2023
2d3027f
Sql console styling
Jermolene Jul 19, 2023
7fd2dd5
Wire up the tag indexer properly
Jermolene Jul 19, 2023
b9245da
Sort tag lookups according to TW semantics
Jermolene Jul 20, 2023
39d0451
Experiment with optimising specific filters with direct SQL equivalents
Jermolene Jul 21, 2023
7eeaa20
Merge branch 'master' into demo-alternate-store
Jermolene Jul 22, 2023
bb41ae0
Merge branch 'master' into demo-alternate-store
Jermolene Jul 28, 2023
e6309e9
Fix tag collation syntax
Jermolene Jul 29, 2023
66cba18
Merge branch 'master' into demo-alternate-store
Jermolene Aug 22, 2023
25138ec
Merge branch 'master' into demo-alternate-store
Jermolene Sep 19, 2023
1754be2
Merge branch 'master' into demo-alternate-store
Jermolene Oct 15, 2023
c52014c
Simplify the SQL schema
Jermolene Oct 21, 2023
fd3d8ae
Merge branch 'master' into demo-alternate-store
Jermolene Oct 21, 2023
863066d
Merge branch 'master' into demo-alternate-store
Jermolene Oct 23, 2023
d4dec0c
Use the empty string as special plugin name for ordinary tiddlers
Jermolene Oct 24, 2023
f49b9fa
Move tags into their own tables
Jermolene Oct 25, 2023
12c6cb3
Add indexes for columns used in joins
Jermolene Oct 25, 2023
dc94ed8
Refactor indexer implementation
Jermolene Oct 25, 2023
3a4f5b8
Cache allTitles and allShadowTitles
Jermolene Oct 25, 2023
e9d640b
Fix sqlAllTitles wrongly including shadow tiddlers
Jermolene Oct 25, 2023
01e1882
More indexes
Jermolene Oct 27, 2023
a58f119
Enable performance instrumentation
Jermolene Oct 27, 2023
e4af21a
Don't use LEFT JOIN unless we have to
Jermolene Oct 27, 2023
d982658
Remove all plugins to simplify benchmarking
Jermolene Oct 27, 2023
8c1f7a6
SQL Console: Add number of rows returned
Jermolene Oct 30, 2023
9493084
Merge branch 'master' into demo-alternate-store
Jermolene Nov 7, 2023
02f3065
Revert attempt at optimising filter execution
Jermolene Nov 7, 2023
d7f0c5c
Minor refactoring
Jermolene Nov 7, 2023
6997c61
Refactor filter compilation to allow SQL engine to optimise queries
Jermolene Nov 7, 2023
5d20e98
Refactor filter compilation into its own source file
Jermolene Nov 8, 2023
4897248
Fix indentation
Jermolene Nov 10, 2023
6983564
Merge branch 'master' into demo-alternate-store
Jermolene Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 40 additions & 6 deletions boot/boot.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 47 additions & 26 deletions core/modules/filters.js
Expand Up @@ -171,15 +171,15 @@ exports.parseFilter = function(filterString) {
}
if(match[3]) {
operation.suffixes = [];
$tw.utils.each(match[3].split(":"),function(subsuffix) {
$tw.utils.each(match[3].split(":"),function(subsuffix) {
operation.suffixes.push([]);
$tw.utils.each(subsuffix.split(","),function(entry) {
entry = $tw.utils.trim(entry);
if(entry) {
operation.suffixes[operation.suffixes.length -1].push(entry);
}
});
});
});
}
}
if(match[4]) { // Opening square bracket
Expand Down Expand Up @@ -225,13 +225,17 @@ source: an iterator function for the source tiddlers, called source(iterator), w
widget: an optional widget node for retrieving the current tiddler etc.
*/
exports.compileFilter = function(filterString) {
var self = this;
// Set up the filter function cache
if(!this.filterCache) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
// Use the cached version of this filter function if it exists
if(this.filterCache[filterString] !== undefined) {
return this.filterCache[filterString];
}
// Parse the filter string
var filterParseTree;
try {
filterParseTree = this.parseFilter(filterString);
Expand All @@ -241,10 +245,42 @@ exports.compileFilter = function(filterString) {
return [$tw.language.getString("Error/Filter") + ": " + e];
};
}
// Get the filter function
var fnFilter = this.optimiseFilter && this.optimiseFilter(filterString,filterParseTree);
if(!fnFilter) {
fnFilter = this.compileFilterToJavaScript(filterParseTree);
}
// Add recursion detection
var fnGuardedFilter = function guardedFilterFunction(source,widget) {
var results;
self.filterRecursionCount = (self.filterRecursionCount || 0) + 1;
if(self.filterRecursionCount < MAX_FILTER_DEPTH) {
results = fnFilter(source,widget);
} else {
results = ["/**-- Excessive filter recursion --**/"];
}
self.filterRecursionCount = self.filterRecursionCount - 1;
return results;
}
// Add performance measurement
var fnMeasured = $tw.perf.measure("filter: " + filterString,fnGuardedFilter);
// Cache the final filter function
if(this.filterCacheCount >= 2000) {
// To prevent memory leak, we maintain an upper limit for cache size.
// Reset if exceeded. This should give us 95% of the benefit
// that no cache limit would give us.
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[filterString] = fnMeasured;
this.filterCacheCount++;
return fnMeasured;
};

exports.compileFilterToJavaScript = function(filterParseTree) {
var operationFunctions = [];
// Get the hashmap of filter operator functions
var filterOperators = this.getFilterOperators();
// Assemble array of functions, one for each operation
var operationFunctions = [];
// Step through the operations
var self = this;
$tw.utils.each(filterParseTree,function(operation) {
Expand Down Expand Up @@ -334,8 +370,8 @@ exports.compileFilter = function(filterString) {
}
})());
});
// Return a function that applies the operations to a source iterator of tiddler titles
var fnMeasured = $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
// Make the filter function
return function filterFunction(source,widget) {
if(!source) {
source = self.each;
} else if(typeof source === "object") { // Array or hashmap
Expand All @@ -345,27 +381,12 @@ exports.compileFilter = function(filterString) {
widget = $tw.rootWidget;
}
var results = new $tw.utils.LinkedList();
self.filterRecursionCount = (self.filterRecursionCount || 0) + 1;
if(self.filterRecursionCount < MAX_FILTER_DEPTH) {
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
} else {
results.push("/**-- Excessive filter recursion --**/");
}
self.filterRecursionCount = self.filterRecursionCount - 1;
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
return results.toArray();
});
if(this.filterCacheCount >= 2000) {
// To prevent memory leak, we maintain an upper limit for cache size.
// Reset if exceeded. This should give us 95% of the benefit
// that no cache limit would give us.
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[filterString] = fnMeasured;
this.filterCacheCount++;
return fnMeasured;
};
};

})();

33 changes: 0 additions & 33 deletions core/modules/tiddler.js
Expand Up @@ -24,21 +24,6 @@ exports.isDraft = function() {
return this.hasField("draft.of");
};

exports.getFieldString = function(field,defaultValue) {
var value = this.fields[field];
// Check for a missing field
if(value === undefined || value === null) {
return defaultValue || "";
}
// Stringify the field with the associated tiddler field module (if any)
var fieldModule = $tw.Tiddler.fieldModules[field];
if(fieldModule && fieldModule.stringify) {
return fieldModule.stringify.call(this,value);
} else {
return value.toString();
}
};

/*
Get the value of a field as a list
*/
Expand All @@ -51,24 +36,6 @@ exports.getFieldList = function(field) {
return $tw.utils.parseStringArray(value);
};

/*
Get all the fields as a hashmap of strings. Options:
exclude: an array of field names to exclude
*/
exports.getFieldStrings = function(options) {
options = options || {};
var exclude = options.exclude || [];
var fields = {};
for(var field in this.fields) {
if($tw.utils.hop(this.fields,field)) {
if(exclude.indexOf(field) === -1) {
fields[field] = this.getFieldString(field);
}
}
}
return fields;
};

/*
Get all the fields as a name:value block. Options:
exclude: an array of field names to exclude
Expand Down
2 changes: 1 addition & 1 deletion core/wiki/config/PerformanceInstrumentation.tid
@@ -1,2 +1,2 @@
title: $:/config/Performance/Instrumentation
text: no
text: yes
1 change: 1 addition & 0 deletions editions/empty/tiddlywiki.info
@@ -1,6 +1,7 @@
{
"description": "Empty edition",
"plugins": [
"tiddlywiki/sqlite3store"
],
"themes": [
"tiddlywiki/vanilla",
Expand Down
@@ -0,0 +1,2 @@
title: $:/config/Performance/Instrumentation
text: yes
24 changes: 2 additions & 22 deletions editions/prerelease/tiddlywiki.info
@@ -1,31 +1,11 @@
{
"description": "Content for the current prerelease",
"plugins": [
"tiddlywiki/browser-sniff",
"tiddlywiki/help",
"tiddlywiki/stacked-view",
"tiddlywiki/powered-by-tiddlywiki",
"tiddlywiki/internals",
"tiddlywiki/highlight",
"tiddlywiki/bibtex",
"tiddlywiki/savetrail",
"tiddlywiki/external-attachments",
"tiddlywiki/dynaview",
"tiddlywiki/dynannotate",
"tiddlywiki/codemirror",
"tiddlywiki/menubar",
"tiddlywiki/jszip"
"tiddlywiki/sqlite3store"
],
"themes": [
"tiddlywiki/vanilla",
"tiddlywiki/snowwhite",
"tiddlywiki/starlight",
"tiddlywiki/seamless",
"tiddlywiki/centralised",
"tiddlywiki/heavier",
"tiddlywiki/tight",
"tiddlywiki/tight-heavier",
"tiddlywiki/readonly"
"tiddlywiki/snowwhite"
],
"languages": [
],
Expand Down
3 changes: 2 additions & 1 deletion editions/test/tiddlywiki.info
@@ -1,7 +1,8 @@
{
"description": "TiddlyWiki core tests",
"plugins": [
"tiddlywiki/jasmine"
"tiddlywiki/jasmine",
"tiddlywiki/sqlite3store"
],
"themes": [
"tiddlywiki/vanilla",
Expand Down
@@ -0,0 +1,2 @@
title: $:/config/Performance/Instrumentation
text: yes
17 changes: 2 additions & 15 deletions editions/tw5.com/tiddlywiki.info
@@ -1,24 +1,11 @@
{
"description": "Documentation from https://tiddlywiki.com",
"plugins": [
"tiddlywiki/nodewebkitsaver",
"tiddlywiki/browser-sniff",
"tiddlywiki/railroad",
"tiddlywiki/evernote",
"tiddlywiki/internals",
"tiddlywiki/menubar",
"tiddlywiki/qrcode"
"tiddlywiki/sqlite3store"
],
"themes": [
"tiddlywiki/vanilla",
"tiddlywiki/snowwhite",
"tiddlywiki/starlight",
"tiddlywiki/seamless",
"tiddlywiki/centralised",
"tiddlywiki/tight",
"tiddlywiki/heavier",
"tiddlywiki/tight-heavier",
"tiddlywiki/readonly"
"tiddlywiki/snowwhite"
],
"languages": [
],
Expand Down
6 changes: 6 additions & 0 deletions plugins/tiddlywiki/demo-alternate-store/plugin.info
@@ -0,0 +1,6 @@
{
"title": "$:/plugins/tiddlywiki/demo-alternate-store",
"name": "Demo alternate store",
"description": "Developer demo of an alternate wiki store implementation",
"list": "readme"
}