Skip to content

Commit

Permalink
Fix slow loading when database path contains res:https:// or user:https://
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed May 25, 2024
1 parent 274b1af commit 22e6dc9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 39 deletions.
4 changes: 3 additions & 1 deletion doc/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Semver is not yet in place, so each version can have breaking changes, although
- `VoxelViewer`: added `view_distance_vertical_ratio` to use different vertical view distance proportionally to the horizontal distance

- Fixes
- `VoxelStreamSQLite`: fixed `set_key_cache_enabled(true)` caused nothing to load
- `VoxelStreamSQLite`:
- Fixed `set_key_cache_enabled(true)` caused nothing to load
- Fixed slow loading when the database path contains `res:https://` or `user:https://`


1.2 - 20/04/2024 - branch `1.2` - tag `v1.2.0`
Expand Down
72 changes: 35 additions & 37 deletions streams/sqlite/voxel_stream_sqlite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../../util/errors.h"
#include "../../util/godot/classes/project_settings.h"
#include "../../util/godot/core/array.h"
#include "../../util/godot/core/string.h"
#include "../../util/math/conv.h"
#include "../../util/profiling.h"
#include "../../util/string/format.h"
Expand Down Expand Up @@ -677,7 +678,7 @@ VoxelStreamSQLite::VoxelStreamSQLite() {}

VoxelStreamSQLite::~VoxelStreamSQLite() {
ZN_PRINT_VERBOSE("~VoxelStreamSQLite");
if (!_connection_path.is_empty() && _cache.get_indicative_block_count() > 0) {
if (!_globalized_connection_path.empty() && _cache.get_indicative_block_count() > 0) {
ZN_PRINT_VERBOSE("~VoxelStreamSQLite flushy flushy");
flush_cache();
ZN_PRINT_VERBOSE("~VoxelStreamSQLite flushy done");
Expand All @@ -691,20 +692,17 @@ VoxelStreamSQLite::~VoxelStreamSQLite() {

void VoxelStreamSQLite::set_database_path(String path) {
MutexLock lock(_connection_mutex);
if (path == _connection_path) {
if (path == _user_specified_connection_path) {
return;
}
if (!_connection_path.is_empty() && _cache.get_indicative_block_count() > 0) {
if (!_globalized_connection_path.empty() && _cache.get_indicative_block_count() > 0) {
// Save cached data before changing the path.
// Not using get_connection() because it locks, we are already locked.
VoxelStreamSQLiteInternal con;
// To support Godot shortcuts like `user:https://` and `res:https://` (though the latter won't work on exported builds)
const String globalized_connection_path = ProjectSettings::get_singleton()->globalize_path(_connection_path);
const CharString cpath = globalized_connection_path.utf8();
// Note, the path could be invalid,
// Since Godot helpfully sets the property for every character typed in the inspector.
// So there can be lots of errors in the editor if you type it.
if (con.open(cpath.get_data())) {
if (con.open(_globalized_connection_path.data())) {
flush_cache_to_connection(&con);
}
}
Expand All @@ -714,13 +712,16 @@ void VoxelStreamSQLite::set_database_path(String path) {
_block_keys_cache.clear();
_connection_pool.clear();

_connection_path = path;
_user_specified_connection_path = path;
// To support Godot shortcuts like `user:https://` and `res:https://` (though the latter won't work on exported builds)
_globalized_connection_path = zylann::godot::to_std_string(ProjectSettings::get_singleton()->globalize_path(path));

// Don't actually open anything here. We'll do it only when necessary
}

String VoxelStreamSQLite::get_database_path() const {
MutexLock lock(_connection_mutex);
return _connection_path;
return _user_specified_connection_path;
}

void VoxelStreamSQLite::load_voxel_block(VoxelStream::VoxelQueryData &q) {
Expand Down Expand Up @@ -1050,30 +1051,27 @@ void VoxelStreamSQLite::flush_cache_to_connection(VoxelStreamSQLiteInternal *p_c
}

VoxelStreamSQLiteInternal *VoxelStreamSQLite::get_connection() {
_connection_mutex.lock();
if (_connection_path.is_empty()) {
_connection_mutex.unlock();
return nullptr;
}
if (_connection_pool.size() != 0) {
VoxelStreamSQLiteInternal *s = _connection_pool.back();
_connection_pool.pop_back();
_connection_mutex.unlock();
return s;
}
// First connection we get since we set the database path
StdString fpath;
{
MutexLock mlock(_connection_mutex);

String fpath = _connection_path;
_connection_mutex.unlock();
if (_globalized_connection_path.empty()) {
return nullptr;
}
if (_connection_pool.size() != 0) {
VoxelStreamSQLiteInternal *s = _connection_pool.back();
_connection_pool.pop_back();
return s;
}
// First connection we get since we set the database path
fpath = _globalized_connection_path;
}

if (fpath.is_empty()) {
if (fpath.empty()) {
return nullptr;
}
VoxelStreamSQLiteInternal *con = new VoxelStreamSQLiteInternal();
// To support Godot shortcuts like `user:https://` and `res:https://` (though the latter won't work on exported builds)
const String globalized_fpath = ProjectSettings::get_singleton()->globalize_path(fpath);
const CharString fpath_utf8 = globalized_fpath.utf8();
if (!con->open(fpath_utf8.get_data())) {
if (!con->open(fpath.data())) {
delete con;
con = nullptr;
}
Expand All @@ -1088,16 +1086,16 @@ VoxelStreamSQLiteInternal *VoxelStreamSQLite::get_connection() {
}

void VoxelStreamSQLite::recycle_connection(VoxelStreamSQLiteInternal *con) {
String con_path = con->get_opened_file_path();
_connection_mutex.lock();
// If path differs, delete this connection
if (_connection_path != con_path) {
_connection_mutex.unlock();
delete con;
} else {
_connection_pool.push_back(con);
_connection_mutex.unlock();
const char *con_path = con->get_opened_file_path();
// Put back in the pool if the connection path didn't change
{
MutexLock mlock(_connection_mutex);
if (_globalized_connection_path == con_path) {
_connection_pool.push_back(con);
return;
}
}
delete con;
}

void VoxelStreamSQLite::set_key_cache_enabled(bool enable) {
Expand Down
4 changes: 3 additions & 1 deletion streams/sqlite/voxel_stream_sqlite.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../../util/containers/std_unordered_set.h"
#include "../../util/containers/std_vector.h"
#include "../../util/math/vector3i16.h"
#include "../../util/string/std_string.h"
#include "../../util/thread/mutex.h"
#include "../voxel_block_serializer.h"
#include "../voxel_stream.h"
Expand Down Expand Up @@ -112,7 +113,8 @@ class VoxelStreamSQLite : public VoxelStream {

static void _bind_methods();

String _connection_path;
String _user_specified_connection_path;
StdString _globalized_connection_path;
StdVector<VoxelStreamSQLiteInternal *> _connection_pool;
Mutex _connection_mutex;
// This cache stores blocks in memory, and gets flushed to the database when big enough.
Expand Down

0 comments on commit 22e6dc9

Please sign in to comment.