From bd5f9bb61fe2e036f2ad9c7df585adf13785b426 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 6 Oct 2025 02:37:25 +0700 Subject: [PATCH] cache exclude-only queries too --- develop/fuzzing/execute_fuzz.lua | 30 ++++++++ evolved.lua | 123 ++++++++++++++++++++----------- 2 files changed, 110 insertions(+), 43 deletions(-) diff --git a/develop/fuzzing/execute_fuzz.lua b/develop/fuzzing/execute_fuzz.lua index af58d47..11bf6c0 100644 --- a/develop/fuzzing/execute_fuzz.lua +++ b/develop/fuzzing/execute_fuzz.lua @@ -224,6 +224,36 @@ end --- --- +for _ = 1, math.random(1, 5) do + local fragment = all_fragment_list[math.random(1, #all_fragment_list)] + + evo.set(fragment, evo.EXPLICIT) +end + +for _ = 1, math.random(1, 5) do + local query = pre_query_list[math.random(1, pre_query_count)] + + if math.random(1, 2) == 1 then + generate_query(query) + else + if math.random(1, 2) == 1 then + evo.remove(query, evo.INCLUDES) + else + evo.remove(query, evo.EXCLUDES) + end + end +end + +for i = 1, all_query_count do + execute_query(all_query_list[i]) +end + +--- +--- +--- +--- +--- + if math.random(1, 2) == 1 then evo.collect_garbage() end diff --git a/evolved.lua b/evolved.lua index 854cc3a..393d2fa 100644 --- a/evolved.lua +++ b/evolved.lua @@ -129,6 +129,10 @@ local __minor_chunks = {} ---@type table> local __major_queries = {} ---@type table> +local __root_query_set = {} ---@type table +local __root_query_list = {} ---@type evolved.query[] +local __root_query_count = 0 ---@type integer + local __entity_chunks = {} ---@type table local __entity_places = {} ---@type table @@ -1138,21 +1142,37 @@ end ---@param chunk evolved.chunk function __update_chunk_queries(chunk) - local chunk_major = chunk.__fragment + if chunk.__parent then + local major_queries = __major_queries[chunk.__fragment] + local major_query_list = major_queries and major_queries.__item_list + local major_query_count = major_queries and major_queries.__item_count or 0 - local major_queries = __major_queries[chunk_major] - local major_query_list = major_queries and major_queries.__item_list - local major_query_count = major_queries and major_queries.__item_count or 0 + for major_query_index = 1, major_query_count do + local major_query = major_query_list[major_query_index] + local major_query_chunks = __query_chunks[major_query] - for major_query_index = 1, major_query_count do - local major_query = major_query_list[major_query_index] - local major_query_chunks = __query_chunks[major_query] + if major_query_chunks then + if __chunk_matches(chunk, major_query) then + __assoc_list_insert(major_query_chunks, chunk) + else + __assoc_list_remove(major_query_chunks, chunk) + end + end + end + else + local root_query_list = __root_query_list + local root_query_count = __root_query_count - if major_query_chunks then - if __chunk_matches(chunk, major_query) then - __assoc_list_insert(major_query_chunks, chunk) - else - __assoc_list_remove(major_query_chunks, chunk) + for root_query_index = 1, root_query_count do + local root_query = root_query_list[root_query_index] + local root_query_chunks = __query_chunks[root_query] + + if root_query_chunks then + if __chunk_matches(chunk, root_query) then + __assoc_list_insert(root_query_chunks, chunk) + else + __assoc_list_remove(root_query_chunks, chunk) + end end end end @@ -1312,14 +1332,22 @@ end ---@param query evolved.query ---@return evolved.assoc_list function __update_query_chunks(query) - ---@type evolved.assoc_list - local query_chunks = __assoc_list_new(4) - __query_chunks[query] = query_chunks - local query_includes = __sorted_includes[query] local query_include_list = query_includes and query_includes.__item_list local query_include_count = query_includes and query_includes.__item_count or 0 + local query_excludes = __sorted_excludes[query] + local query_exclude_count = query_excludes and query_excludes.__item_count or 0 + + if query_include_count == 0 and query_exclude_count == 0 then + __error_fmt('the empty query (%s) cannot be cached', + __id_name(query)) + end + + ---@type evolved.assoc_list + local query_chunks = __assoc_list_new(4) + __query_chunks[query] = query_chunks + if query_include_count > 0 then local query_major = query_include_list[query_include_count] @@ -1334,6 +1362,12 @@ function __update_query_chunks(query) __assoc_list_insert(query_chunks, major_chunk) end end + elseif query_exclude_count > 0 then + for _, root_chunk in __lua_next, __root_chunks do + if __chunk_matches(root_chunk, query) then + __assoc_list_insert(query_chunks, root_chunk) + end + end end return query_chunks @@ -5953,10 +5987,9 @@ function __evolved_execute(query) local query_excludes = __sorted_excludes[query] local query_exclude_set = query_excludes and query_excludes.__item_set - local query_exclude_list = query_excludes and query_excludes.__item_list local query_exclude_count = query_excludes and query_excludes.__item_count or 0 - if query_include_count > 0 then + if query_include_count > 0 or query_exclude_count > 0 then local query_chunks = __query_chunks[query] or __update_query_chunks(query) local query_chunk_list = query_chunks and query_chunks.__item_list local query_chunk_count = query_chunks and query_chunks.__item_count or 0 @@ -5968,23 +6001,9 @@ function __evolved_execute(query) chunk_stack_size = chunk_stack_size + query_chunk_count end - elseif query_exclude_count > 0 then - for _, root_chunk in __lua_next, __root_chunks do - local is_root_chunk_matched = - (not root_chunk.__has_explicit_fragments) and - (not __chunk_has_any_fragment_list(root_chunk, query_exclude_list, query_exclude_count)) - - if is_root_chunk_matched then - chunk_stack_size = chunk_stack_size + 1 - chunk_stack[chunk_stack_size] = root_chunk - end - end else for _, root_chunk in __lua_next, __root_chunks do - local is_root_chunk_matched = - (not root_chunk.__has_explicit_fragments) - - if is_root_chunk_matched then + if not root_chunk.__has_explicit_fragments then chunk_stack_size = chunk_stack_size + 1 chunk_stack[chunk_stack_size] = root_chunk end @@ -6975,7 +6994,7 @@ __evolved_set(__ON_REMOVE, __UNIQUE) --- --- -local function __insert_major_query(query) +local function __insert_query(query) local query_includes = __sorted_includes[query] local query_include_list = query_includes and query_includes.__item_list local query_include_count = query_includes and query_includes.__item_count or 0 @@ -6990,10 +7009,19 @@ local function __insert_major_query(query) end __assoc_list_insert(major_queries, query) + else + local query_excludes = __sorted_excludes[query] + local query_exclude_count = query_excludes and query_excludes.__item_count or 0 + + if query_exclude_count > 0 then + __root_query_count = __assoc_list_insert_ex( + __root_query_set, __root_query_list, __root_query_count, + query) + end end end -local function __remove_major_query(query) +local function __remove_query(query) local query_includes = __sorted_includes[query] local query_include_list = query_includes and query_includes.__item_list local query_include_count = query_includes and query_includes.__item_count or 0 @@ -7005,14 +7033,23 @@ local function __remove_major_query(query) if major_queries and __assoc_list_remove(major_queries, query) == 0 then __major_queries[query_major] = nil end + else + local query_excludes = __sorted_excludes[query] + local query_exclude_count = query_excludes and query_excludes.__item_count or 0 + + if query_exclude_count > 0 then + __root_query_count = __assoc_list_remove_ex( + __root_query_set, __root_query_list, __root_query_count, + query) + end end end ---@param query evolved.query ---@param include_list evolved.fragment[] __evolved_set(__INCLUDES, __ON_SET, function(query, _, include_list) + __remove_query(query) __reset_query_chunks(query) - __remove_major_query(query) local include_count = #include_list @@ -7029,18 +7066,18 @@ __evolved_set(__INCLUDES, __ON_SET, function(query, _, include_list) end if include_count > 0 or __sorted_excludes[query] then - __insert_major_query(query) + __insert_query(query) end end) __evolved_set(__INCLUDES, __ON_REMOVE, function(query) + __remove_query(query) __reset_query_chunks(query) - __remove_major_query(query) __sorted_includes[query] = nil if __sorted_excludes[query] then - __insert_major_query(query) + __insert_query(query) end end) @@ -7053,8 +7090,8 @@ end) ---@param query evolved.query ---@param exclude_list evolved.fragment[] __evolved_set(__EXCLUDES, __ON_SET, function(query, _, exclude_list) + __remove_query(query) __reset_query_chunks(query) - __remove_major_query(query) local exclude_count = #exclude_list @@ -7071,18 +7108,18 @@ __evolved_set(__EXCLUDES, __ON_SET, function(query, _, exclude_list) end if exclude_count > 0 or __sorted_includes[query] then - __insert_major_query(query) + __insert_query(query) end end) __evolved_set(__EXCLUDES, __ON_REMOVE, function(query) + __remove_query(query) __reset_query_chunks(query) - __remove_major_query(query) __sorted_excludes[query] = nil if __sorted_includes[query] then - __insert_major_query(query) + __insert_query(query) end end)