Skip to content

Commit f3af349

Browse files
committed
fix: tombstone vector sets on DEL
1 parent 61c30cc commit f3af349

2 files changed

Lines changed: 12 additions & 37 deletions

File tree

src/storage/src/redis_strings.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use crate::{
3333
format_base_meta_value::ParsedBaseMetaValue,
3434
format_list_meta_value::ParsedListsMetaValue,
3535
format_strings_value::{ParsedStringsValue, StringValue},
36-
format_vector_member_key::VectorMemberDataKey,
3736
redis_sets::glob_match_bytes,
3837
};
3938

@@ -2059,7 +2058,7 @@ impl Redis {
20592058
log::warn!("failed to update key statistics for {key_str}: {error:?}");
20602059
}
20612060
}
2062-
DataType::Hash | DataType::Set | DataType::ZSet => {
2061+
DataType::Hash | DataType::Set | DataType::ZSet | DataType::VectorSet => {
20632062
let mut parsed = ParsedBaseMetaValue::new(&value[..])?;
20642063
if !parsed.is_valid() {
20652064
return Ok(false);
@@ -2081,39 +2080,6 @@ impl Redis {
20812080
log::warn!("failed to update key statistics for {key_str}: {error:?}");
20822081
}
20832082
}
2084-
DataType::VectorSet => {
2085-
let parsed = ParsedBaseMetaValue::new(&value[..])?;
2086-
if !parsed.is_valid() {
2087-
return Ok(false);
2088-
}
2089-
let count = parsed.count();
2090-
let prefix = VectorMemberDataKey::encode_key_prefix(key)?;
2091-
let Some(vector_cf) = self.get_cf_handle(ColumnFamilyIndex::VectorDataCF) else {
2092-
return Ok(false);
2093-
};
2094-
let mut keys_to_delete = Vec::new();
2095-
for item in db.iterator_cf(
2096-
&vector_cf,
2097-
rocksdb::IteratorMode::From(&prefix, rocksdb::Direction::Forward),
2098-
) {
2099-
let (member_key, _) = item.context(RocksSnafu)?;
2100-
if !member_key.starts_with(&prefix) {
2101-
break;
2102-
}
2103-
keys_to_delete.push(member_key.to_vec());
2104-
}
2105-
let mut batch = self.create_batch()?;
2106-
batch.delete(ColumnFamilyIndex::MetaCF, &encoded_meta_key)?;
2107-
for member_key in keys_to_delete {
2108-
batch.delete(ColumnFamilyIndex::VectorDataCF, &member_key)?;
2109-
}
2110-
batch.commit()?;
2111-
if let Err(error) =
2112-
self.update_specific_key_statistics(DataType::VectorSet, &key_str, count)
2113-
{
2114-
log::warn!("failed to update key statistics for {key_str}: {error:?}");
2115-
}
2116-
}
21172083
DataType::List => {
21182084
let mut parsed = ParsedListsMetaValue::new(&value[..])?;
21192085
if !parsed.is_valid() {

src/storage/tests/redis_vector_test.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,16 +653,25 @@ async fn test_expired_vectorset_reads_as_missing() {
653653
}
654654

655655
#[test]
656-
fn test_del_removes_vector_meta_and_members() {
656+
fn test_del_tombstones_vector_meta_and_defers_member_cleanup() {
657657
with_redis(|redis| {
658658
let vector = CanonicalVector::from_values(&[1.0, 0.0]).expect("vector");
659659
redis.vadd(b"vectors", b"a", &vector).expect("insert a");
660660
redis.vadd(b"vectors", b"b", &vector).expect("insert b");
661661
assert_eq!(count_cf_entries(redis, ColumnFamilyIndex::VectorDataCF), 2);
662+
let previous_version = read_stored_vector_meta(redis, b"vectors").version();
662663

663664
assert!(redis.del_key(b"vectors").expect("delete vector set"));
664665
assert_eq!(redis.vcard(b"vectors").expect("missing card"), 0);
665-
assert_eq!(count_cf_entries(redis, ColumnFamilyIndex::VectorDataCF), 0);
666+
let tombstone = read_stored_vector_meta(redis, b"vectors");
667+
assert_eq!(tombstone.count(), 0);
668+
assert_eq!(tombstone.etime(), 0);
669+
assert!(tombstone.version() > previous_version);
670+
assert_eq!(
671+
count_cf_entries(redis, ColumnFamilyIndex::VectorDataCF),
672+
2,
673+
"DEL should leave vector members for compaction"
674+
);
666675
});
667676
}
668677

0 commit comments

Comments
 (0)