Skip to content

Commit f4b4096

Browse files
committed
enable background prefetch/decompression
1 parent b8c5869 commit f4b4096

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ endif()
1818
FetchContent_Declare(
1919
sqlite_zstd_vfs
2020
GIT_REPOSITORY https://github.com/mlin/sqlite_zstd_vfs.git
21-
GIT_TAG d7cb925
21+
GIT_TAG e1624c6
2222
)
2323
FetchContent_MakeAvailable(sqlite_zstd_vfs)
2424
include_directories(${sqlite_zstd_vfs_SOURCE_DIR}/src)

src/genomicsqlite.cc

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ static void sqlfn_genomicsqlite_version(sqlite3_context *ctx, int argc,
5858
std::string GenomicSQLiteDefaultConfigJSON() {
5959
return R"({
6060
"unsafe_load": false,
61+
"immutable": false,
6162
"page_cache_MiB": 1024,
6263
"threads": -1,
64+
"force_prefetch": false,
6365
"zstd_level": 6,
6466
"inner_page_KiB": 16,
6567
"outer_page_KiB": 32
@@ -93,6 +95,13 @@ string GenomicSQLiteURI(const string &dbfile, const string &config_json = "") {
9395
SQLite::Database tmpdb(":memory:", SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE);
9496
auto extract = ConfigExtractor(tmpdb, config_json);
9597

98+
extract->bind(2, "$.immutable");
99+
if (!extract->executeStep() || extract->getColumnCount() != 1 ||
100+
!extract->getColumn(0).isInteger())
101+
throw std::runtime_error("error processing config JSON $.immutable");
102+
bool immutable = extract->getColumn(0).getInt() != 0;
103+
extract->reset();
104+
96105
extract->bind(2, "$.unsafe_load");
97106
if (!extract->executeStep() || extract->getColumnCount() != 1 ||
98107
!extract->getColumn(0).isInteger())
@@ -107,6 +116,20 @@ string GenomicSQLiteURI(const string &dbfile, const string &config_json = "") {
107116
int threads = extract->getColumn(0).getInt();
108117
extract->reset();
109118

119+
extract->bind(2, "$.force_prefetch");
120+
if (!extract->executeStep() || extract->getColumnCount() != 1 ||
121+
!extract->getColumn(0).isInteger())
122+
throw std::runtime_error("error processing config JSON $.force_prefetch");
123+
bool force_prefetch = extract->getColumn(0).getInt() != 0;
124+
extract->reset();
125+
126+
extract->bind(2, "$.inner_page_KiB");
127+
if (!extract->executeStep() || extract->getColumnCount() != 1 ||
128+
!extract->getColumn(0).isInteger())
129+
throw std::runtime_error("error processing config JSON $.inner_page_KiB");
130+
int inner_page_KiB = extract->getColumn(0).getInt();
131+
extract->reset();
132+
110133
extract->bind(2, "$.outer_page_KiB");
111134
if (!extract->executeStep() || extract->getColumnCount() != 1 ||
112135
!extract->getColumn(0).isInteger())
@@ -122,13 +145,20 @@ string GenomicSQLiteURI(const string &dbfile, const string &config_json = "") {
122145
extract->reset();
123146

124147
ostringstream uri;
125-
uri << "file:" << dbfile << "?vfs=zstd";
148+
uri << "file:" << dbfile << "?vfs=zstd"; // TODO: URI-encode dbfile
126149
uri << "&threads=" << to_string(threads);
127150
uri << "&outer_page_size=" << to_string(outer_page_KiB * 1024);
128151
uri << "&outer_cache_size=-65536"; // enlarge to hold index b-tree pages for large db's
129152
uri << "&level=" << to_string(zstd_level);
153+
if (threads > 1 && inner_page_KiB < 16 && !force_prefetch) {
154+
// prefetch is usually counterproductive if inner_page_KiB < 16
155+
uri << "&noprefetch=1";
156+
}
157+
if (immutable) {
158+
uri << "&immutable=1";
159+
}
130160
if (unsafe_load) {
131-
uri << "&outer_unsafe";
161+
uri << "&nolock=1&outer_unsafe";
132162
}
133163
return uri.str();
134164
}
@@ -227,12 +257,14 @@ string GenomicSQLiteTuningSQL(const string &config_json, const string &schema =
227257
}
228258
map<string, string> pragmas;
229259
pragmas[schema_prefix + "cache_size"] = to_string(-1024 * page_cache_MiB);
260+
pragmas[schema_prefix + "max_page_count"] = "2147483646";
230261
pragmas["threads"] =
231262
to_string(threads >= 0 ? threads : std::min(8, (int)thread::hardware_concurrency()));
232263
if (unsafe_load) {
233264
pragmas[schema_prefix + "journal_mode"] = "OFF";
234265
pragmas[schema_prefix + "synchronous"] = "OFF";
235266
pragmas[schema_prefix + "auto_vacuum"] = "FULL";
267+
pragmas[schema_prefix + "locking_mode"] = "EXCLUSIVE";
236268
} else {
237269
pragmas[schema_prefix + "journal_mode"] = "MEMORY";
238270
}

0 commit comments

Comments
 (0)