diff --git a/autotest/ogr/ogr_gpkg.py b/autotest/ogr/ogr_gpkg.py index 2c76b25c2418..9b9b339f0195 100755 --- a/autotest/ogr/ogr_gpkg.py +++ b/autotest/ogr/ogr_gpkg.py @@ -7244,10 +7244,15 @@ def test_ogr_gpkg_background_rtree_build(filename): ds = gdaltest.gpkg_dr.CreateDataSource(filename) with gdaltest.config_option("OGR_GPKG_THREADED_RTREE_AT_FIRST_FEATURE", "YES"): lyr = ds.CreateLayer("foo") + assert lyr.StartTransaction() == ogr.OGRERR_NONE for i in range(1000): f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometryDirectly(ogr.CreateGeometryFromWkt("POINT(%d %d)" % (i, i))) assert lyr.CreateFeature(f) == ogr.OGRERR_NONE + if i == 500: + assert lyr.CommitTransaction() == ogr.OGRERR_NONE + assert lyr.StartTransaction() == ogr.OGRERR_NONE + assert lyr.CommitTransaction() == ogr.OGRERR_NONE ds = None assert gdal.VSIStatL(filename + ".tmp_rtree_foo.db") is None diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp index 0e22866236b7..b23b98fb01c8 100644 --- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp +++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp @@ -2173,6 +2173,10 @@ OGRErr OGRGeoPackageTableLayer::CreateOrUpsertFeature( OGRFeature *poFeature, bo else if( !bUpsert && m_bAllowedRTreeThread && !m_bErrorDuringRTreeThread ) { GPKGRTreeEntry sEntry; +#ifdef DEBUG_VERBOSE + if( m_aoRTreeEntries.empty() ) + CPLDebug("GPKG", "Starting to fill m_aoRTreeEntries at FID " CPL_FRMT_GIB, nFID); +#endif sEntry.nId = nFID; sEntry.fMinX = rtreeValueDown(oEnv.MinX); sEntry.fMaxX = rtreeValueUp(oEnv.MaxX); @@ -2226,7 +2230,7 @@ void OGRGeoPackageTableLayer::SetDeferredSpatialIndexCreation( bool bFlag ) // For unit tests if( CPLTestBool(CPLGetConfigOption("OGR_GPKG_THREADED_RTREE_AT_FIRST_FEATURE", "NO")) ) { - m_nRTreeBatchSize = 1; + m_nRTreeBatchSize = 10; m_nRTreeBatchesBeforeStart = 1; } } @@ -2363,11 +2367,21 @@ void OGRGeoPackageTableLayer::AsyncRTreeThreadFunction() } SQLCommand(m_hAsyncDBHandle, "BEGIN"); + GIntBig nCount = 0; while( true ) { const auto aoEntries = m_oQueueRTreeEntries.get_and_pop_front(); if( aoEntries.empty() ) break; +#ifdef DEBUG_VERBOSE + CPLDebug("GPKG", "AsyncRTreeThreadFunction(): " + "Processing batch of %d features, " + "starting at FID " CPL_FRMT_GIB " and ending " + "at FID " CPL_FRMT_GIB, + static_cast(aoEntries.size()), + aoEntries.front().nId, + aoEntries.back().nId); +#endif for( const auto& entry: aoEntries ) { if( (entry.nId % 500000) == 0 ) @@ -2382,6 +2396,7 @@ void OGRGeoPackageTableLayer::AsyncRTreeThreadFunction() } sqlite3_reset(hStmt); + nCount ++; sqlite3_bind_int64(hStmt,1,entry.nId); sqlite3_bind_double(hStmt,2,entry.fMinX); sqlite3_bind_double(hStmt,3,entry.fMaxX); @@ -2408,6 +2423,7 @@ void OGRGeoPackageTableLayer::AsyncRTreeThreadFunction() } sqlite3_finalize(hStmt); + CPLDebug("GPKG", "AsyncRTreeThreadFunction(): " CPL_FRMT_GIB " rows inserted into RTree", nCount); if( m_bErrorDuringRTreeThread ) {