|
1 | 1 | #![allow(deprecated)]
|
2 | 2 |
|
3 |
| -use rand::prelude::*; |
4 |
| -use rand::distributions::Uniform; |
5 |
| -use std::collections::HashSet; |
6 | 3 | use futures::{StreamExt, TryStreamExt};
|
7 | 4 | use libsql::{
|
8 | 5 | named_params, params,
|
9 | 6 | params::{IntoParams, IntoValue},
|
10 | 7 | Connection, Database, Value,
|
11 | 8 | };
|
| 9 | +use rand::distributions::Uniform; |
| 10 | +use rand::prelude::*; |
| 11 | +use std::collections::HashSet; |
12 | 12 |
|
13 | 13 | async fn setup() -> Connection {
|
14 | 14 | let db = Database::open(":memory:").unwrap();
|
@@ -663,43 +663,85 @@ async fn vector_fuzz_test() {
|
663 | 663 | for attempt in 0..10000 {
|
664 | 664 | let seed = global_rng.next_u64();
|
665 | 665 |
|
666 |
| - let mut rng = rand::rngs::StdRng::from_seed(unsafe { std::mem::transmute([seed, seed, seed, seed]) }); |
| 666 | + let mut rng = |
| 667 | + rand::rngs::StdRng::from_seed(unsafe { std::mem::transmute([seed, seed, seed, seed]) }); |
667 | 668 | let db = Database::open(":memory:").unwrap();
|
668 | 669 | let conn = db.connect().unwrap();
|
669 | 670 | let dim = rng.gen_range(1..=1536);
|
670 | 671 | let operations = rng.gen_range(1..128);
|
671 |
| - println!("============== ATTEMPT {} (seed {}u64, dim {}, operations {}) ================", attempt, seed, dim, operations); |
672 |
| - |
673 |
| - let _ = conn.execute(&format!("CREATE TABLE users (id INTEGER PRIMARY KEY, v FLOAT32({}) )", dim), ()).await; |
| 672 | + println!( |
| 673 | + "============== ATTEMPT {} (seed {}u64, dim {}, operations {}) ================", |
| 674 | + attempt, seed, dim, operations |
| 675 | + ); |
| 676 | + |
| 677 | + let _ = conn |
| 678 | + .execute( |
| 679 | + &format!( |
| 680 | + "CREATE TABLE users (id INTEGER PRIMARY KEY, v FLOAT32({}) )", |
| 681 | + dim |
| 682 | + ), |
| 683 | + (), |
| 684 | + ) |
| 685 | + .await; |
674 | 686 | // println!("CREATE TABLE users (id INTEGER PRIMARY KEY, v FLOAT32({}) );", dim);
|
675 |
| - let _ = conn.execute("CREATE INDEX users_idx ON users ( libsql_vector_idx(v) );", ()).await; |
| 687 | + let _ = conn |
| 688 | + .execute( |
| 689 | + "CREATE INDEX users_idx ON users ( libsql_vector_idx(v) );", |
| 690 | + (), |
| 691 | + ) |
| 692 | + .await; |
676 | 693 | // println!("CREATE INDEX users_idx ON users ( libsql_vector_idx(v) );");
|
677 | 694 |
|
678 | 695 | let mut next_id = 1;
|
679 | 696 | let mut alive = HashSet::new();
|
680 | 697 | let uniform = Uniform::new(-1.0, 1.0);
|
681 | 698 | for _ in 0..operations {
|
682 | 699 | let operation = rng.gen_range(0..4);
|
683 |
| - let vector : Vec<f32> = (0..dim).map(|_| rng.sample(uniform)).collect(); |
684 |
| - let vector_str = format!("[{}]", vector.iter().map(|x| format!("{}", x)).collect::<Vec<String>>().join(",")); |
| 700 | + let vector: Vec<f32> = (0..dim).map(|_| rng.sample(uniform)).collect(); |
| 701 | + let vector_str = format!( |
| 702 | + "[{}]", |
| 703 | + vector |
| 704 | + .iter() |
| 705 | + .map(|x| format!("{}", x)) |
| 706 | + .collect::<Vec<String>>() |
| 707 | + .join(",") |
| 708 | + ); |
685 | 709 | if operation == 0 {
|
686 | 710 | // println!("INSERT INTO users VALUES ({}, vector('{}') );", next_id, vector_str);
|
687 |
| - conn.execute("INSERT INTO users VALUES (?, vector(?) )", libsql::params![next_id, vector_str]).await.unwrap(); |
| 711 | + conn.execute( |
| 712 | + "INSERT INTO users VALUES (?, vector(?) )", |
| 713 | + libsql::params![next_id, vector_str], |
| 714 | + ) |
| 715 | + .await |
| 716 | + .unwrap(); |
688 | 717 | alive.insert(next_id);
|
689 | 718 | next_id += 1;
|
690 | 719 | } else if operation == 1 {
|
691 | 720 | let id = rng.gen_range(0..next_id);
|
692 | 721 | // println!("DELETE FROM users WHERE id = {};", id);
|
693 |
| - conn.execute("DELETE FROM users WHERE id = ?", libsql::params![id]).await.unwrap(); |
| 722 | + conn.execute("DELETE FROM users WHERE id = ?", libsql::params![id]) |
| 723 | + .await |
| 724 | + .unwrap(); |
694 | 725 | alive.remove(&id);
|
695 | 726 | } else if operation == 2 && !alive.is_empty() {
|
696 | 727 | let id = alive.iter().collect::<Vec<_>>()[rng.gen_range(0..alive.len())];
|
697 | 728 | // println!("UPDATE users SET v = vector('{}') WHERE id = {};", vector_str, id);
|
698 |
| - conn.execute("UPDATE users SET v = vector(?) WHERE id = ?", libsql::params![vector_str, id]).await.unwrap(); |
| 729 | + conn.execute( |
| 730 | + "UPDATE users SET v = vector(?) WHERE id = ?", |
| 731 | + libsql::params![vector_str, id], |
| 732 | + ) |
| 733 | + .await |
| 734 | + .unwrap(); |
699 | 735 | } else if operation == 3 {
|
700 | 736 | let k = rng.gen_range(1..200);
|
701 | 737 | // println!("SELECT * FROM vector_top_k('users_idx', '{}', {});", vector_str, k);
|
702 |
| - let result = conn.query("SELECT * FROM vector_top_k('users_idx', ?, ?)", libsql::params![vector_str, k]).await.unwrap(); |
| 738 | + let result = conn |
| 739 | + .query( |
| 740 | + "SELECT * FROM vector_top_k('users_idx', ?, ?)", |
| 741 | + libsql::params![vector_str, k], |
| 742 | + ) |
| 743 | + .await |
| 744 | + .unwrap(); |
703 | 745 | let count = result.into_stream().count().await;
|
704 | 746 | assert!(count <= alive.len());
|
705 | 747 | if alive.len() > 0 {
|
|
0 commit comments