Skip to content

Commit 06137e1

Browse files
authored
feat: sync CREATE INDEX (#462)
* feat: sync CREATE INDEX Signed-off-by: usamoi <[email protected]> * test: fix IVF tests Signed-off-by: usamoi <[email protected]> * feat: add Alter trait Signed-off-by: usamoi <[email protected]> * chore: rename IndexOptions2 to IndexAlterableOptions Signed-off-by: usamoi <[email protected]> --------- Signed-off-by: usamoi <[email protected]>
1 parent b3c9181 commit 06137e1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+738
-523
lines changed

Cargo.lock

Lines changed: 16 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ thiserror.workspace = true
3636
tikv-jemallocator = { version = "0.5.4", features = [
3737
"disable_initial_exec_tls",
3838
] }
39-
toml = "0.8.10"
39+
toml.workspace = true
4040
validator.workspace = true
4141

4242
base = { path = "crates/base" }
@@ -87,8 +87,9 @@ rustix = { version = "0.38.31", features = ["fs", "mm", "net"] }
8787
serde = "1"
8888
serde_json = "1"
8989
thiserror = "1"
90+
toml = "0.8.10"
9091
uuid = { version = "1.7.0", features = ["serde", "v4"] }
91-
validator = { version = "0.17.0", features = ["derive"] }
92+
validator = { version = "0.18.0", features = ["derive"] }
9293

9394
[workspace.lints]
9495
rust.unsafe_op_in_unsafe_fn = "forbid"

crates/base/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ num-traits.workspace = true
1111
rand.workspace = true
1212
serde.workspace = true
1313
thiserror.workspace = true
14+
toml.workspace = true
1415
uuid.workspace = true
1516
validator.workspace = true
1617

18+
base_macros = { path = "../base_macros" }
1719
c = { path = "../c" }
1820
detect = { path = "../detect" }
1921

crates/base/src/index.rs

Lines changed: 65 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::distance::*;
22
use crate::vector::*;
3+
use base_macros::Alter;
34
use serde::{Deserialize, Serialize};
45
use thiserror::Error;
56
use uuid::Uuid;
@@ -8,7 +9,7 @@ use validator::{Validate, ValidationError};
89
#[must_use]
910
#[derive(Debug, Clone, Error, Serialize, Deserialize)]
1011
pub enum CreateError {
11-
#[error("Invalid index options.")]
12+
#[error("Invalid index options: {reason}.")]
1213
InvalidIndexOptions { reason: String },
1314
}
1415

@@ -81,47 +82,37 @@ pub enum StatError {
8182
#[must_use]
8283
#[derive(Debug, Clone, Error, Serialize, Deserialize)]
8384
pub enum AlterError {
84-
#[error("Setting key {key} is not exist.")]
85-
BadKey { key: String },
86-
#[error("Setting key {key} has a wrong value {value}.")]
87-
BadValue { key: String, value: String },
8885
#[error("Index not found.")]
8986
NotExist,
87+
#[error("Key {key} not found.")]
88+
KeyNotExists { key: String },
89+
#[error("Invalid index options: {reason}.")]
90+
InvalidIndexOptions { reason: String },
9091
}
9192

92-
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
93-
#[serde(deny_unknown_fields)]
94-
pub struct IndexFlexibleOptions {
95-
#[serde(default = "IndexFlexibleOptions::default_optimizing_threads")]
96-
#[validate(range(min = 1, max = 65535))]
97-
pub optimizing_threads: u16,
98-
}
99-
100-
impl IndexFlexibleOptions {
101-
pub fn default_optimizing_threads() -> u16 {
102-
1
103-
}
93+
#[must_use]
94+
#[derive(Debug, Clone, Error, Serialize, Deserialize)]
95+
pub enum StopError {
96+
#[error("Index not found.")]
97+
NotExist,
10498
}
10599

106-
impl Default for IndexFlexibleOptions {
107-
fn default() -> Self {
108-
Self {
109-
optimizing_threads: Self::default_optimizing_threads(),
110-
}
111-
}
100+
#[must_use]
101+
#[derive(Debug, Clone, Error, Serialize, Deserialize)]
102+
pub enum StartError {
103+
#[error("Index not found.")]
104+
NotExist,
112105
}
113106

114107
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
115108
#[serde(deny_unknown_fields)]
116109
#[validate(schema(function = "IndexOptions::validate_index_options"))]
117110
pub struct IndexOptions {
118-
#[validate]
111+
#[validate(nested)]
119112
pub vector: VectorOptions,
120-
#[validate]
113+
#[validate(nested)]
121114
pub segment: SegmentsOptions,
122-
#[validate]
123-
pub optimizing: OptimizingOptions,
124-
#[validate]
115+
#[validate(nested)]
125116
pub indexing: IndexingOptions,
126117
}
127118

@@ -140,13 +131,20 @@ impl IndexOptions {
140131
};
141132
if !is_trivial {
142133
return Err(ValidationError::new(
143-
"Quantization is not supported for svector, bvector, and vecint8.",
134+
"Quantization is not supported for svector, bvector, and veci8.",
144135
));
145136
}
146137
Ok(())
147138
}
148139
}
149140

141+
#[derive(Debug, Clone, Serialize, Deserialize, Validate, Alter)]
142+
#[serde(deny_unknown_fields)]
143+
pub struct IndexAlterableOptions {
144+
#[validate(nested)]
145+
pub optimizing: OptimizingOptions,
146+
}
147+
150148
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
151149
#[serde(deny_unknown_fields)]
152150
#[validate(schema(function = "Self::validate_0"))]
@@ -222,9 +220,12 @@ impl Default for SegmentsOptions {
222220
}
223221
}
224222

225-
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
223+
#[derive(Debug, Clone, Serialize, Deserialize, Validate, Alter)]
226224
#[serde(deny_unknown_fields)]
227225
pub struct OptimizingOptions {
226+
#[serde(default = "OptimizingOptions::default_optimizing_threads")]
227+
#[validate(range(min = 1, max = 65535))]
228+
pub optimizing_threads: u16,
228229
#[serde(default = "OptimizingOptions::default_sealing_secs")]
229230
#[validate(range(min = 1, max = 60))]
230231
pub sealing_secs: u64,
@@ -237,6 +238,9 @@ pub struct OptimizingOptions {
237238
}
238239

239240
impl OptimizingOptions {
241+
fn default_optimizing_threads() -> u16 {
242+
1
243+
}
240244
fn default_sealing_secs() -> u64 {
241245
60
242246
}
@@ -251,6 +255,7 @@ impl OptimizingOptions {
251255
impl Default for OptimizingOptions {
252256
fn default() -> Self {
253257
Self {
258+
optimizing_threads: Self::default_optimizing_threads(),
254259
sealing_secs: Self::default_sealing_secs(),
255260
sealing_size: Self::default_sealing_size(),
256261
delete_threshold: Self::default_delete_threshold(),
@@ -308,7 +313,7 @@ impl Validate for IndexingOptions {
308313
#[serde(deny_unknown_fields)]
309314
pub struct FlatIndexingOptions {
310315
#[serde(default)]
311-
#[validate]
316+
#[validate(nested)]
312317
pub quantization: QuantizationOptions,
313318
}
314319

@@ -336,7 +341,7 @@ pub struct IvfIndexingOptions {
336341
#[validate(range(min = 1, max = 1_000_000))]
337342
pub nsample: u32,
338343
#[serde(default)]
339-
#[validate]
344+
#[validate(nested)]
340345
pub quantization: QuantizationOptions,
341346
}
342347

@@ -375,17 +380,17 @@ pub struct HnswIndexingOptions {
375380
pub m: u32,
376381
#[serde(default = "HnswIndexingOptions::default_ef_construction")]
377382
#[validate(range(min = 10, max = 2000))]
378-
pub ef_construction: usize,
383+
pub ef_construction: u32,
379384
#[serde(default)]
380-
#[validate]
385+
#[validate(nested)]
381386
pub quantization: QuantizationOptions,
382387
}
383388

384389
impl HnswIndexingOptions {
385390
fn default_m() -> u32 {
386391
12
387392
}
388-
fn default_ef_construction() -> usize {
393+
fn default_ef_construction() -> u32 {
389394
300
390395
}
391396
}
@@ -492,7 +497,7 @@ impl Default for ProductQuantizationOptionsRatio {
492497
pub struct SearchOptions {
493498
pub prefilter_enable: bool,
494499
#[validate(range(min = 1, max = 65535))]
495-
pub hnsw_ef_search: usize,
500+
pub hnsw_ef_search: u32,
496501
#[validate(range(min = 1, max = 1_000_000))]
497502
pub ivf_nprobe: u32,
498503
}
@@ -507,8 +512,30 @@ pub struct IndexStat {
507512
#[derive(Debug, Serialize, Deserialize)]
508513
pub struct SegmentStat {
509514
pub id: Uuid,
510-
#[serde(rename = "type")]
511-
pub typ: String,
515+
pub r#type: String,
512516
pub length: usize,
513517
pub size: u64,
514518
}
519+
520+
pub trait Alter {
521+
fn alter(&mut self, key: &[&str], value: &str) -> Result<(), AlterError>;
522+
}
523+
524+
macro_rules! impl_alter_for {
525+
{$($t:ty)*} => {
526+
$(impl Alter for $t {
527+
fn alter(&mut self, key: &[&str], value: &str) -> Result<(), AlterError> {
528+
use std::str::FromStr;
529+
if key.is_empty() {
530+
*self = FromStr::from_str(value).map_err(|_| AlterError::InvalidIndexOptions { reason: "failed to parse".to_string() })?;
531+
return Ok(());
532+
}
533+
Err(AlterError::KeyNotExists { key: key.join(".") })
534+
}
535+
})*
536+
};
537+
}
538+
539+
impl_alter_for! {
540+
String u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 bool
541+
}

crates/base/src/worker.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ use crate::search::*;
33
use crate::vector::*;
44

55
pub trait WorkerOperations {
6-
fn create(&self, handle: Handle, options: IndexOptions) -> Result<(), CreateError>;
6+
fn create(
7+
&self,
8+
handle: Handle,
9+
options: IndexOptions,
10+
alterable_options: IndexAlterableOptions,
11+
) -> Result<(), CreateError>;
712
fn drop(&self, handle: Handle) -> Result<(), DropError>;
813
fn flush(&self, handle: Handle) -> Result<(), FlushError>;
914
fn insert(
@@ -17,7 +22,9 @@ pub trait WorkerOperations {
1722
fn view_vbase(&self, handle: Handle) -> Result<impl ViewVbaseOperations, VbaseError>;
1823
fn view_list(&self, handle: Handle) -> Result<impl ViewListOperations, ListError>;
1924
fn stat(&self, handle: Handle) -> Result<IndexStat, StatError>;
20-
fn alter(&self, handle: Handle, key: String, value: String) -> Result<(), AlterError>;
25+
fn alter(&self, handle: Handle, key: &str, value: &str) -> Result<(), AlterError>;
26+
fn stop(&self, handle: Handle) -> Result<(), StopError>;
27+
fn start(&self, handle: Handle) -> Result<(), StartError>;
2128
}
2229

2330
pub trait ViewBasicOperations {

crates/base_macros/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "base_macros"
3+
version.workspace = true
4+
edition.workspace = true
5+
6+
[lib]
7+
proc-macro = true
8+
9+
[dependencies]
10+
proc-macro2 = { version = "1.0.79", features = ["proc-macro"] }
11+
quote = "1.0.35"
12+
syn = { version = "2.0.53", default-features = false, features = [
13+
"clone-impls",
14+
"full",
15+
"parsing",
16+
"printing",
17+
"proc-macro",
18+
] }
19+
20+
[lints]
21+
workspace = true

0 commit comments

Comments
 (0)