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

[OGR provider] Allow opening (GeoPackage) datasets with many layers #5409

Merged
merged 2 commits into from Oct 20, 2017

Conversation

rouault
Copy link
Contributor

@rouault rouault commented Oct 19, 2017

Currently each time you instanciate a QgsOgrProvider layer, a GDAL dataset is
created. In the case of GeoPackage, this means a SQLite connection and a file
handle. As GDAL enables Spatialite function on GeoPackage connections, we are
bound to Spatialite limits, and Spatialite has a hard limit on a maximum of
64 simultaneous connections. Thus we cannot open more than 64 layers of the
same GeoPackage.
This commits enables sharing of the same GDALDataset object among several
QgsOgrProvider object. Care is made to reuse a GDALDataset object only if the
QgsOgrProvider do not point to the same layer. Mutexes are also taken to
allow safe instanciation and use of QgsOgrProvider objects from multiple
threads (but a same QgsOgrProvider should not be used by more than one thread
at a time)

Checklist

Reviewing is a process done by project maintainers, mostly on a volunteer basis. We try to keep the overhead as small as possible and appreciate if you help us to do so by completing the following items. Feel free to ask in a comment if you have troubles with any of them.

  • Commit messages are descriptive and explain the rationale for changes
  • Commits which fix bugs include fixes #11111 in the commit message next to the description
  • Commits which add new features are tagged with [FEATURE] in the commit message
  • Commits which change the UI or existing user workflows are tagged with [needs-docs] in the commit message and containt sufficient information in the commit message to be documented
  • I have read the QGIS Coding Standards and this PR complies with them
  • This PR passes all existing unit tests (test results will be reported by travis-ci after opening this PR)
  • New unit tests have been added for core changes
  • I have run the scripts/prepare-commit.sh script before each commit

@rduivenvoorde
Copy link
Contributor

Contact me if you need a huge gpkg to test

@rduivenvoorde
Copy link
Contributor

Hi, Thanks for this work
Build this PR, and did some tests:

  • loading an already provided project (the one I sent to Even: 143 tables, 4.6 million features) is going fine...
    I do not see the max 64 connections messages anymore (actually no message at all...?)
    AND the project is loaded fast. \o/

  • if I try to load the giant gpkg via the Data Source Manager, I can load 1 layer but with more it either crashes QGIS (stracktrace below), or just does not end (without any message, running 100% on 1 cpu core). Could be not related to this commits though...

  • if I drag/drop de gpkg in the layermanager, the FIRST time it is just fast, and QGIS shows me the 'select a layer' dialog, and I can even select all 143 layers.
    BUT a second or third time, this same action takes a very long time??

  • another observation: when I browse to the gpkg I see
    ERROR 4: `/home/richard/z/17/rivm/20170926_grootmodel/oudemodel/TotalGammaDoseRate.gpkg' not recognized as a supported file format.
    BUT I can open it, or at least one layer...

A stacktrace (I think more related to the multithread Data Source Manager...) but crashing QGIS:

`/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x9649c)[0x7fe84662f49c]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x964b8)[0x7fe84662f4b8]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x53ee2)[0x7fe8465ecee2]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x2d9c7)[0x7fe8465c69c7]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x47fea)[0x7fe8465e0fea]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(+0x2c5ef)[0x7fe8465c55ef]
/home/richard/bin/qgis_all/pr/debug/lib/qgis/plugins/libogrprovider.so(classFactory+0x2b)[0x7fe8465d9968]
/home/richard/bin/qgis_all/pr/debug/lib/libqgis_core.so.2.99.0(QgsProviderRegistry::createProvider(QString const&, QString const&)+0x41e)[0x7fe8dd977b56]
/home/richard/bin/qgis_all/pr/debug/lib/libqgis_core.so.2.99.0(QgsVectorLayer::setDataProvider(QString const&)+0x263)[0x7fe8dda1f803]
/home/richard/bin/qgis_all/pr/debug/lib/libqgis_core.so.2.99.0(QgsVectorLayer::setDataSource(QString const&, QString const&, QString const&, bool)+0xc8)[0x7fe8dda1f388]
QGIS died on signal 11[New LWP 30585]
[New LWP 30586]
[New LWP 30587]
[New LWP 30588]
[New LWP 30589]
[New LWP 30590]
[New LWP 30593]
[New LWP 30594]
[New LWP 30595]
[New LWP 30596]
[New LWP 30597]
[New LWP 30598]
[New LWP 30620]
[New LWP 30660]
[New LWP 30661]
[New LWP 30662]
[New LWP 30663]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fe8d391203a in __GI___waitpid (pid=30903, stat_loc=0x7fff3b460654, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
29 ../sysdeps/unix/sysv/linux/waitpid.c: No such file or directory.
[Current thread is 1 (Thread 0x7fe8e133c340 (LWP 30584))]
#0 0x00007fe8d391203a in __GI___waitpid (pid=30903, stat_loc=0x7fff3b460654, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
resultvar = 18446744073709551104
sc_cancel_oldtype = 0
#1 0x000055dc75317f7a in qgisCrash (signal=11) at ../src/app/main.cpp:323
status = 32744
pidstr = "--pid=30584\000\377\177\000\000\200\004F;\377\177\000\000\364\274|\335\350\177\000"
gdbpid = 30903
exename = "/home/richard/bin/qgis_all/pr/debug/bin/qgis\000\177\000\000\240\004F;\377\177\000\000\340ͤ\324\350\177\000\000\260\327\316|\334U\000\000L:\226\324\350\177\000\000\260k!\200\334U\000\000̫ \341\350\177\000\000\260\327\316|\334U\000\000\030\366 \341\350\177", '\000' <repeats 11 times>, "\366\220\214=$\246\325p)\236v\334U\000\000\260\327\316|\334U\000\000\340\aF;\377\177\000\000@\177\060v\334U\000\000\060m+v\334U\000\000\260\327\316|\334U\000\000\260k!\200\334U\000\000E\224\\331\350\177\000\000p_H|\334U\000\000\340\a"...
len = 44
#2
No locals.
#3 0x0000000000147590 in ?? ()
No symbol table info available.
#4 0x00007fe8d496c9b9 in QMetaObject::cast(QObject const*) const () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#5 0x00007fe8d96198ed in ?? () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#6 0x00007fe8d95d22f6 in QApplication::notify(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#7 0x00007fe8dd745a0b in QgsApplication::notify (this=0x7fff3b462660, receiver=0x7fe810397040, event=0x7fff3b461070) at ../src/core/qgsapplication.cpp:314
done = true
FUNCTION = "notify"
#8 0x00007fe8d4963d68 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#9 0x00007fe8d49bb89e in QTimerInfoList::activateTimers() () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#10 0x00007fe8d49bc061 in ?? () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#11 0x00007fe8d161df67 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#12 0x00007fe8d161e1a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#13 0x00007fe8d161e22c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#14 0x00007fe8d49bc3ff in QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#15 0x00007fe8d4961dba in QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#16 0x00007fe8d97f5547 in QDialog::exec() () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#17 0x00007fe8e0543b4b in QgisApp::dataSourceManager (this=0x55dc766fa700, pageName=...) at ../src/app/qgisapp.cpp:1574
No locals.
#18 0x00007fe8e054602d in QgisApp::<lambda()>::operator()(void) const (_closure=0x55dc76b94d00) at ../src/app/qgisapp.cpp:1825
this = 0x55dc766fa700
#19 0x00007fe8e05ab614 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, QgisApp::createActions()::<lambda()> >::call(QgisApp::<lambda()> &, void **) (f=..., arg=0x7fff3b461770) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:130
No locals.
#20 0x00007fe8e05aac01 in QtPrivate::Functor<QgisApp::createActions()::<lambda()>, 0>::call<QtPrivate::List<>, void>(QgisApp::<lambda()> &, void *, void **) (f=..., arg=0x7fff3b461770) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:240
No locals.
#21 0x00007fe8e05a92d1 in QtPrivate::QFunctorSlotObject<QgisApp::createActions()::<lambda()>, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this
=0x55dc76b94cf0, r=0x55dc766fa700, a=0x7fff3b461770, ret=0x0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobject_impl.h:168
No locals.
#22 0x00007fe8d499297f in QMetaObject::activate(QObject*, int, int, void**) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#23 0x00007fe8d95c2d82 in QAction::triggered(bool) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#24 0x00007fe8d95c546c in QAction::activate(QAction::ActionEvent) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#25 0x00007fe8d9786aeb in ?? () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#26 0x00007fe8d9786d44 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#27 0x00007fe8d976607a in QToolButton::mouseReleaseEvent(QMouseEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#28 0x00007fe8d9609db8 in QWidget::event(QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#29 0x00007fe8d9766114 in QToolButton::event(QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#30 0x00007fe8d95c946c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#31 0x00007fe8d95d128f in QApplication::notify(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#32 0x00007fe8dd745a0b in QgsApplication::notify (this=0x7fff3b462660, receiver=0x55dc76841e50, event=0x7fff3b461d20) at ../src/core/qgsapplication.cpp:314
done = true
FUNCTION = "notify"
#33 0x00007fe8d4963d68 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#34 0x00007fe8d95d0262 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer&, bool) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#35 0x00007fe8d962493b in ?? () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#36 0x00007fe8d9626faa in ?? () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#37 0x00007fe8d95c946c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#38 0x00007fe8d95d0d34 in QApplication::notify(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Widgets.so.5
No symbol table info available.
#39 0x00007fe8dd745a0b in QgsApplication::notify (this=0x7fff3b462660, receiver=0x55dc7b683490, event=0x7fff3b4621f0) at ../src/core/qgsapplication.cpp:314
done = true
FUNCTION = "notify"
#40 0x00007fe8d4963d68 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#41 0x00007fe8d52adf43 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
No symbol table info available.
#42 0x00007fe8d52afa25 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
No symbol table info available.
#43 0x00007fe8d5287cab in QWindowSystemInterface::sendWindowSystemEvents(QFlagsQEventLoop::ProcessEventsFlag) () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
No symbol table info available.
#44 0x00007fe8b93115a0 in ?? () from /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
No symbol table info available.
#45 0x00007fe8d161df67 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#46 0x00007fe8d161e1a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#47 0x00007fe8d161e22c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#48 0x00007fe8d49bc3ff in QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#49 0x00007fe8d4961dba in QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#50 0x00007fe8d496ad24 in QCoreApplication::exec() () from /lib/x86_64-linux-gnu/libQt5Core.so.5
No symbol table info available.
#51 0x000055dc7531dbc9 in main (argc=1, argv=0x7fff3b4639e8) at ../src/app/main.cpp:1345
profile = 0x55dc762bb3b0
presetStyle = {static null = {}, d = 0x55dc7645be80}
rootProfileFolder = {static null = {}, d = 0x55dc76306870}
myLocaleOverrideFlag = false
qgistor =
w = 600
mySplashPath = {static null = {}, d = 0x7fe8dde0db20 <QgsApplication::splashPath()::{lambda()#1}::operator()() const::qstring_literal>}
h = 300
mypSplash = 0x55dc763ff240
qgis = 0x55dc766fa700
retval = 994457712
manager = { = {}, static staticMetaObject = {d = {superdata = 0x7fe8d4e13a00 QObject::staticMetaObject, stringdata = 0x7fe8ddf006e0 <qt_meta_stringdata_QgsUserProfileManager>, data = 0x7fe8ddf00760 <qt_meta_data_QgsUserProfileManager>, static_metacall = 0x7fe8ddda9dd8 <QgsUserProfileManager::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, mWatchProfiles = false, mWatcher = std::unique_ptr containing 0x0, mRootProfilePath = {static null = {}, d = 0x55dc76306870}, mUserProfile = std::unique_ptr containing 0x0, mSettings = std::unique_ptr containing 0x55dc762bb2f0}
profileFolder = {static null = {}, d = 0x55dc76307100}
mySettings = { = {}, static staticMetaObject = {d = {superdata = 0x7fe8d4e13a00 QObject::staticMetaObject, stringdata = 0x7fe8ddef1960 <qt_meta_stringdata_QgsSettings>, data = 0x7fe8ddef19a0 <qt_meta_data_QgsSettings>, static_metacall = 0x7fe8ddd95bf8 <QgsSettings::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, static sGlobalSettingsPath = {static null = {}, d = 0x55dc7644fd60}, mUserSettings = 0x55dc764bd540, mGlobalSettings = 0x55dc76445e00, mUsingGlobalArray = false}
systemEnvVars = {d = 0x55dc764202b0}
activeStyleName = {static null = {}, d = 0x55dc764bd660}
i18nPath = {static null = {}, d = 0x55dc7666ee10}
myUserLocale = {static null = {}, d = 0x55dc764bd590}
qttor =
myApp = { = {}, static staticMetaObject = {d = {superdata = 0x7fe8d9c8a020 QApplication::staticMetaObject, stringdata = 0x7fe8ddee0980 <qt_meta_stringdata_QgsApplication>, data = 0x7fe8ddee0ae0 <qt_meta_data_QgsApplication>, static_metacall = 0x7fe8ddd7e4a0 <QgsApplication::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, static QGIS_ORGANIZATION_NAME = 0x7fe8dde0d148 "QGIS", static QGIS_ORGANIZATION_DOMAIN = 0x7fe8dde0d14d "qgis.org", static QGIS_APPLICATION_NAME = 0x7fe8dde0d156 "QGIS3", static mFileOpenEventReceiver29900 = 0x55dc766fa700, static mFileOpenEventList29900 = {<QList> = {<QListSpecialMethods> = {}, {p = {static shared_null = {ref = {atomic = {_q_value = {<std::__atomic_base> = {static _S_alignment = 4, _M_i = -1}, }}}, alloc = 0, begin = 0, end = 0, array = {0x0}}, d = 0x7fe8d4a53960 QListData::shared_null}, d = 0x7fe8d4a53960 QListData::shared_null}}, }, static mUIThemeName29900 = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}, static mPrefixPath29900 = {static null = , d = 0x55dc76415d60}, static mPluginPath29900 = {static null = , d = 0x55dc7644ff40}, static mPkgDataPath29900 = {static null = , d = 0x55dc7644b620}, static mLibraryPath29900 = {static null = , d = 0x55dc763fd4f0}, static mLibexecPath29900 = {static null = , d = 0x55dc76460910}, static mThemeName29900 = {static null = , d = 0x7fe8dde0d6c0 <QgsApplication::setUITheme(QString const&)::{lambda()#2}::operator()() const::qstring_literal>}, static mDefaultSvgPaths29900 = {<QList> = {<QListSpecialMethods> = {}, {p = {static shared_null = {ref = {atomic = {_q_value = {<std::__atomic_base> = {static _S_alignment = 4, _M_i = -1}, }}}, alloc = 0, begin = 0, end = 0, array = {0x0}}, d = 0x55dc76420500}, d = 0x55dc76420500}}, }, static mSystemEnvVars29900 = {d = 0x55dc764202b0}, static mConfigPath29900 = {static null = {}, d = 0x55dc76460ad0}, static mRunningFromBuildDir29900 = false, static mBuildSourcePath29900 = {static null = , d = 0x7fe8d4a51360 QArrayData::shared_null}, static mBuildOutputPath29900 = {static null = , d = 0x7fe8d4a51360 QArrayData::shared_null}, static mGdalSkipList29900 = {<QList> = {<QListSpecialMethods> = {}, {p = {static shared_null = {ref = {atomic = {_q_value = {<std::__atomic_base> = {static _S_alignment = 4, _M_i = -1}, }}}, alloc = 0, begin = 0, end = 0, array = {0x0}}, d = 0x7fe8d4a53960 QListData::shared_null}, d = 0x7fe8d4a53960 QListData::shared_null}}, }, static mMaxThreads29900 = -1, static mAuthDbDirPath29900 = {static null = {}, d = 0x55dc76460ad0}, static sUserName = {static null = , d = 0x55dc763f7910}, static sUserFullName = {static null = , d = 0x55dc76b1d6c0}, static sPlatformName = {static null = , d = 0x55dc76307260}, mIconCache = {d = 0x55dc76448570}, mDataItemProviderRegistry = 0x55dc7708a980, mApplicationMembers = 0x55dc76435370, static sApplicationMembers = 0x0}
customizationsettings = 0x55dc764508e0
useCustomVars = false
myPixmap =
FUNCTION = "main"
mySnapshotFileName = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
configLocalStorageLocation = {static null = {}, d = 0x55dc763066c0}
profileName = {static null = {}, d = 0x55dc76306210}
mySnapshotWidth = 800
mySnapshotHeight = 600
myHideSplash = false
mySkipVersionCheck = false
myRestoreDefaultWindowState = false
myRestorePlugins = true
myCustomization = true
dxfOutputFile = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
dxfSymbologyMode = QgsDxfExport::SymbolLayerSymbology
dxfScale = 50000
dxfEncoding = {static null = {}, d = 0x55dc75325560 <main::{lambda()#1}::operator()() const::qstring_literal>}
dxfPreset = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
dxfExtent = {mXmin = 0, mYmin = 0, mXmax = 0, mYmax = 0}
myInitialExtent = {static null = {}, d = 0x55dc753255a0 <main::{lambda()#2}::operator()() const::qstring_literal>}
myTranslationCode = {static null = {}, d = 0x55dc764bd560}
configpath = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
authdbdirectory = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
pythonfile = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
customizationfile = {static null = {}, d = 0x7fe8d4a51360 QArrayData::shared_null}
globalsettingsfile = {static null = {}, d = 0x55dc7644fd60}
args = {<QList> = {<QListSpecialMethods> = {}, {p = {static shared_null = {ref = {atomic = {_q_value = {<std::__atomic_base> = {static _S_alignment = 4, _M_i = -1}, }}}, alloc = 0, begin = 0, end = 0, array = {0x0}}, d = 0x55dc762bb090}, d = 0x55dc762bb090}}, }
myUseGuiFlag = true
settings = { = {}, static staticMetaObject = {d = {superdata = 0x7fe8d4e13a00 QObject::staticMetaObject, stringdata = 0x7fe8ddef1960 <qt_meta_stringdata_QgsSettings>, data = 0x7fe8ddef19a0 <qt_meta_data_QgsSettings>, static_metacall = 0x7fe8ddd95bf8 <QgsSettings::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, static sGlobalSettingsPath = {static null = {}, d = 0x55dc7644fd60}, mUserSettings = 0x55dc762bb170, mGlobalSettings = 0x0, mUsingGlobalArray = false}
gdb returned 0
/home/richard/bin/qgispr: line 5: 30584 Aborted /home/richard/bin/qgis_all/pr/debug/bin/qgis "$@"

`

@rouault
Copy link
Contributor Author

rouault commented Oct 20, 2017

@rduivenvoorde

if I try to load the giant gpkg via the Data Source Manager, I can load 1 layer but with more it either crashes QGIS (stracktrace below), or just does not end (without any message, running 100% on 1 cpu core)

I couldn't reproduce a crash, but the slowness yes. Which I've fixed with 129a9e2 .

I should note also that best performance is reached with GDAL trunk as I've pushed a bunch of optimizations for faster opening of GeoPackage with a large number of layers, and "lazy" opening of layers. For example a test GeoPackage with 1000 layers opens in 5 seconds with GDAL 2.2, and 0.5s with GDAL trunk. On your GeoPackage with 144 layers, GDAL 2.2 in 300 ms, GDAL trunk in 160 ms.

if I drag/drop de gpkg in the layermanager, the FIRST time it is just fast, and QGIS shows me the 'select a layer' dialog, and I can even select all 143 layers.
BUT a second or third time, this same action takes a very long time??

I couldn't reproduce this issue. Speed is the same for me.

another observation: when I browse to the gpkg I see
ERROR 4: `/home/richard/z/17/rivm/20170926_grootmodel/oudemodel/TotalGammaDoseRate.gpkg' not recognized as a supported file format.

You can ignore this. This is probably due to the browser trying to open at some point the .gpkg as a raster one.

@andreasneumann
Copy link
Member

andreasneumann commented Oct 20, 2017 via email

Currently each time you instanciate a QgsOgrProvider layer, a GDAL dataset is
created. In the case of GeoPackage, this means a SQLite connection and a file
handle. As GDAL enables Spatialite function on GeoPackage connections, we are
bound to Spatialite limits, and Spatialite has a hard limit on a maximum of
64 simultaneous connections. Thus we cannot open more than 64 layers of the
same GeoPackage.
This commits enables sharing of the same GDALDataset object among several
QgsOgrProvider object. Care is made to reuse a GDALDataset object only if the
QgsOgrProvider do not point to the same layer. Mutexes are also taken to
allow safe instanciation and use of QgsOgrProvider objects from multiple
threads (but a same QgsOgrProvider should not be used by more than one thread
at a time)
@rouault rouault merged commit a733ace into qgis:master Oct 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants