- 29 Sep, 2024 20 commits
-
-
Sergei Golubchik authored
add missing casts to float4store/float8store for bigendian. fix a typo in float4store() usage remove unnecessary one-byte-at-time appends
-
Sergei Golubchik authored
make generosity depend on 1. M. Keep small M's fast, increase generosity for larger M's to get better recall. 2. distance. Keep generosity small when vectors are far from the target, increase generosity when the search gets closer. This allows to examine more relevant vectors but doesn't waste time examining irrelevant vectors. Particularly important with cosine metric when the distance is bounded
-
Sergei Golubchik authored
-
Sergey Vojtovich authored
... until a few bugs that cause server crash are fixed.
-
Sergei Golubchik authored
also: renames, s/const/constexpr/ for consistency
-
Sergey Vojtovich authored
Replaced obscure FRM_ONLY, NO_FRM_RENAME, NO_HA_TABLE, NO_PAR_TABLE with straightforward explicit flags: QRMT_FRM - [re]moves .frm QRMT_PAR - [re]moves .par QRMT_HANDLER - calls ha_delete_table()/ha_rename_table() and [re]moves high-level indexes QRMT_DEFAULT - same as QRMT_FRM | QRMT_HANDLER, which is regular table drop/rename.
-
Sergey Vojtovich authored
quick_rm_table() expects .frm to exist when it removes high-level indexes. For cases like ALTER TABLE t1 RENAME TO t2, ENGINE=other_engine .frm was removed earlier. Another option would be removing high-level indexes explicitly before the first quick_rm_table() and skipping high-level indexes for subsequent quick_rm_table(NO_FRM_RENAME). But this suggested order may also help with ddl log recovery. That is if we crash before high-level indexes are removed, .frm is going to exist.
-
Sergey Vojtovich authored
Disable non-copy ALTER algorithms when VECTOR index is affected. Engines are not supposed to handle high-level indexes anyway. Also fixed misbehaving IF [NOT] EXISTS variants.
-
Sergey Vojtovich authored
Fixes for ALTER TABLE ... ADD/DROP COLUMN, ALGORITHM=COPY. Let quick_rm_table() remove high-level indexes along with original table. Avoid locking uninitialized LOCK_share for INTERNAL_TMP_TABLEs. Don't enable bulk insert when altering a table containing vector index. InnoDB can't handle situation when bulk insert is enabled for one table but disabled for another. We can't do bulk insert on vector index as it does table updates currently.
-
Sergei Golubchik authored
-
Sergei Golubchik authored
-
Sergei Golubchik authored
and create a parent Item_func_vec_distance_common class
-
Sergei Golubchik authored
-
Sergei Golubchik authored
-
Sergei Golubchik authored
into a separate transaction_participant structure handlerton inherits it, so handlerton itself doesn't change. but entities that only need to participate in a transaction, like binlog or online alter log, use a transaction_participant and no longer need to pretend to be a full-blown but invisible storage engine which doesn't support create table.
-
Sergei Golubchik authored
remove unused methods, reorder methods, add comments
-
Sergei Golubchik authored
-
Sergei Golubchik authored
-
Sergey Vojtovich authored
Rename high-level indexes along with a table.
-
Sergei Golubchik authored
* fix the truncate-by-handler variant, used by InnoDB * test that insert works after truncate, meaning graph table was emptied * test that the vector index size is zero after truncate in MyISAM
-
- 26 Sep, 2024 20 commits
-
-
Sergey Vojtovich authored
This patch fixes only TRUNCATE by recreate variant, there seem to be no reasonable engine that uses TRUNCATE by handler method for testing. Reset index_cinfo so that mi_create is not confused by garbage passed via index_file_name and sets MY_DELETE_OLD flag. Review question: can we add a test case to make sure VECTOR index is empty indeed?
-
Sergey Vojtovich authored
-
Sergey Vojtovich authored
-
Sergey Vojtovich authored
-
Vicențiu Ciorbaru authored
This commit introduces two utility functions meant to make working with vectors simpler. Vec_ToText converts a binary vector into a json array of numbers (floats). Vec_FromText takes in a json array of numbers and converts it into a little-endian IEEE float sequence of bytes (4 bytes per float).
-
Vicențiu Ciorbaru authored
This method will write out a float to a String object, keeping the charset of the original string. Also have Float::to_string make use of String::append_float
-
Sergei Golubchik authored
introduced a generosity factor that makes the search less greedy. it dramatically improves the recall by making the search a bit slower (for the same recall one can use half the M and smaller ef). had to add Queue::safe_push() method that removes one of the furthest elements (not necessarily the furthest) in the queue to keep it from overflowing.
-
Sergei Golubchik authored
to return only as many elements as needed, the caller no longer needs to overallocate result arrays for throwaway nodes
-
Sergei Golubchik authored
use int16_t instead of floats, they're faster and smaller. but perform intermediate SIMD calculations with floats to avoid overflows. recall drop with such scheme is below 0.002, often none. int8_t would've been better but the precision loss is too big and recall degrades too much.
-
Sergei Golubchik authored
-
Sergei Golubchik authored
make handler::prepare_for_insert() to be called to prepare the handler for writes, INSERT/UPDATE/DELETE.
-
Hugo Wen authored
When the source row is deleted, mark the corresponding node in HNSW index by setting `tref` to null. An index is added for the `tref` in secondary table for faster searching of the to-be-marked nodes. The nodes marked as deleted will still be used for search, but will not be included in the final query results. As skipping deleted nodes and not adding deleted nodes for new-inserted nodes' neighbor list could impact the performance, we now only skip these nodes in search results. - for some reason the bitmap is not set for hlindex during the delete so I had to temporarily comment out one line All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc.
-
Sergei Golubchik authored
-
Sergei Golubchik authored
* preserve the graph in memory between statements * keep it in a TABLE_SHARE, available for concurrent searches * nodes are generally read-only, walking the graph doesn't change them * distance to target is cached, calculated only once * SIMD-optimized bloom filter detects visited nodes * nodes are stored in an array, not List, to better utilize bloom filter * auto-adjusting heuristic to estimate the number of visited nodes (to configure the bloom filter) * many threads can concurrently walk the graph. MEM_ROOT and Hash_set are protected with a mutex, but walking doesn't need them * up to 8 threads can concurrently load nodes into the cache, nodes are partitioned into 8 mutexes (8 is chosen arbitrarily, might need tuning) * concurrent editing is not supported though * this is fine for MyISAM, TL_WRITE protects the TABLE_SHARE and the graph (note that TL_WRITE_CONCURRENT_INSERT is not allowed, because an INSERT into the main table means multiple UPDATEs in the graph) * InnoDB uses secondary transaction-level caches linked in a list in in thd->ha_data via a fake handlerton * on rollback the secondary cache is discarded, on commit nodes from the secondary cache are invalidated in the shared cache while it is exclusively locked * on savepoint rollback both caches are flushed. this can be improved in the future with a row visibility callback * graph size is controlled by @@mhnsw_cache_size, the cache is flushed when it reaches the threshold
-
Sergei Golubchik authored
instead of one row per node per layer, have one row per node. store all neighbors for all layers in that row, and the vector itself too it completely avoids searches in the graph table and will allow to implement deletions in the future
-
Sergei Golubchik authored
-
Sergei Golubchik authored
-
Sergei Golubchik authored
1. introduce alpha. the value of 1.1 is optimal, so hard-code it. 2. hard-code ef_construction=10, best by test 3. rename hnsw_max_connection_per_layer to mhnsw_max_edges_per_node (max_connection is rather ambiguous in MariaDB) and add a help text 4. rename hnsw_ef_search to mhnsw_min_limit and add a help text
-
Sergei Golubchik authored
* mhnsw: * use primary key, innodb loves and (and the index cannot have dupes anyway) * MyISAM is ok with that, performance-wise * must be ha_rnd_init(0) because we aren't going to scan * MyISAM resets the position on ha_rnd_init(0) so query it before * oh, and use the correct handler, just in case * HA_ERR_RECORD_IS_THE_SAME is no error * innodb: * return ref_length on create * don't assume table->pos_in_table_list is set * ok, assume away, but only for system versioned tables * set alter_info on create (InnoDB needs to check for FKs) * pair external_lock/external_unlock correctly
-
Sergei Golubchik authored
-