@@ -89,6 +89,7 @@ TRAMPOLINE(app_as_geometrycollection, as_geometrycollection)
8989} // anonymous namespace
9090
9191TRAMPOLINE (table_insert, insert)
92+ TRAMPOLINE(table_in_id_cache, in_id_cache)
9293
9394prepared_lua_function_t::prepared_lua_function_t(lua_State *lua_state,
9495 calling_context context,
@@ -270,6 +271,9 @@ void flush_tables(std::vector<table_connection_t> &table_connections)
270271 for (auto &table : table_connections) {
271272 table.flush ();
272273 }
274+ for (auto &table : table_connections) {
275+ table.sync ();
276+ }
273277}
274278
275279void create_expire_tables (std::vector<expire_output_t > const &expire_outputs,
@@ -789,6 +793,10 @@ int output_flex_t::table_insert()
789793 auto const &object = check_and_get_context_object (table);
790794 osmid_t const id = table.map_id (object.type (), object.id ());
791795
796+ if (table.with_id_cache ()) {
797+ get_id_cache (table).push_back (id);
798+ }
799+
792800 table_connection.new_line ();
793801 auto *copy_mgr = table_connection.copy_mgr ();
794802
@@ -823,6 +831,46 @@ int output_flex_t::table_insert()
823831 return 1 ;
824832}
825833
834+ int output_flex_t::table_in_id_cache ()
835+ {
836+ if (m_calling_context == calling_context::process_node) {
837+ throw std::runtime_error{
838+ " Id cache not available while processing nodes." };
839+ }
840+
841+ // The first parameter is the table object.
842+ auto const &table = get_table_from_param ();
843+
844+ if (!table.with_id_cache ()) {
845+ throw fmt_error (" No ID cache on table '{}'." , table.name ());
846+ }
847+
848+ // The second parameter is an array of ids
849+ if (!lua_istable (lua_state (), 1 ) || !luaX_is_array (lua_state ())) {
850+ throw std::runtime_error{" Second parameter must be an array of ids." };
851+ }
852+
853+ std::vector<osmid_t > ids;
854+ luaX_for_each (lua_state (),
855+ [&]() { ids.push_back (lua_tointeger (lua_state (), -1 )); });
856+
857+ auto const &cache = get_id_cache (table);
858+ lua_createtable (lua_state (), 0 , 0 );
859+
860+ lua_Integer n = 0 ;
861+ lua_Integer idx = 1 ;
862+ for (auto const id : ids) {
863+ if (cache.contains (id)) {
864+ lua_pushinteger (lua_state (), ++n);
865+ lua_pushinteger (lua_state (), idx);
866+ lua_rawset (lua_state (), -3 );
867+ }
868+ ++idx;
869+ }
870+
871+ return 1 ;
872+ }
873+
826874void output_flex_t::call_lua_function (prepared_lua_function_t func)
827875{
828876 lua_pushvalue (lua_state (), func.index ());
@@ -980,6 +1028,28 @@ void output_flex_t::after_nodes()
9801028 }
9811029
9821030 flush_tables (m_table_connections);
1031+
1032+ for (auto &table : *m_tables) {
1033+ if (table.with_id_cache ()) {
1034+ auto &cache = get_id_cache (table);
1035+ if (get_options ()->append ) {
1036+ log_debug (" Initializing cache for table '{}' from database..." ,
1037+ table.name ());
1038+ auto const result = m_db_connection.exec (
1039+ " SELECT \" {}\" FROM {}" , table.id_column_names (),
1040+ table.full_name ());
1041+
1042+ cache.reserve (result.num_tuples ());
1043+ for (int i = 0 ; i < result.num_tuples (); ++i) {
1044+ cache.push_back (
1045+ osmium::string_to_object_id (result.get_value (i, 0 )));
1046+ }
1047+ }
1048+ cache.sort_unique ();
1049+ log_debug (" Cache for table '{}' initialized with {} entries." ,
1050+ table.name (), cache.size ());
1051+ }
1052+ }
9831053}
9841054
9851055void output_flex_t::after_ways ()
@@ -1199,6 +1269,10 @@ void output_flex_t::relation_modify(osmium::Relation const &rel)
11991269void output_flex_t::start ()
12001270{
12011271 for (auto &table : m_table_connections) {
1272+ if (table.table ().with_id_cache ()) {
1273+ log_debug (" Enable cache for table '{}'." , table.table ().name ());
1274+ create_id_cache (table.table ());
1275+ }
12021276 table.start (m_db_connection, get_options ()->append );
12031277 }
12041278
@@ -1212,6 +1286,7 @@ output_flex_t::output_flex_t(output_flex_t const *other,
12121286 std::shared_ptr<db_copy_thread_t > copy_thread)
12131287: output_t (other, std::move(mid)), m_locators(other->m_locators),
12141288 m_tables (other->m_tables), m_expire_outputs(other->m_expire_outputs),
1289+ m_id_caches(other->m_id_caches),
12151290 m_db_connection(get_options()->connection_params, "out.flex.thread"),
12161291 m_stage2_way_ids(other->m_stage2_way_ids),
12171292 m_copy_thread(std::move(copy_thread)), m_lua_state(other->m_lua_state),
0 commit comments