Skip to content

Instantly share code, notes, and snippets.

@jsn
Created November 9, 2024 07:38
Show Gist options
  • Save jsn/50cf8429e7496c6ac50e5e4ed0476268 to your computer and use it in GitHub Desktop.
Save jsn/50cf8429e7496c6ac50e5e4ed0476268 to your computer and use it in GitHub Desktop.
use std::borrow::Cow;
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::RwLock;
pub trait IndexKey<Item>: Sized {
fn keys(i: &Item) -> Vec<Self>;
}
pub struct Index<Item, K> {
pub items: Vec<Item>,
pub index: HashMap<K, usize>,
}
impl<Item, K: Eq + Hash + IndexKey<Item>> Index<Item, K> {
pub fn get(&self, k: &K) -> Option<&Item> {
Some(&self.items[*self.index.get(k)?])
}
pub fn get_mut(&mut self, k: &K) -> Option<&mut Item> {
Some(&mut self.items[*self.index.get(k)?])
}
pub fn insert(&mut self, o: Item) {
let i = self.items.len();
for k in K::keys(&o) {
self.index.insert(k, i);
}
self.items.push(o);
}
pub fn replace(&mut self, o: Item) {
let ks = K::keys(&o);
if let Some(i) = self.index.get(&ks[0]) {
let i = *i;
for k in K::keys(&self.items[i]) {
self.index.remove(&k);
}
for k in ks {
self.index.insert(k, i);
}
} else {
self.insert(o);
}
}
pub fn remove(&mut self, o: Item) {
for k in K::keys(&o) {
self.index.remove(&k);
}
}
}
impl<Item, K: Eq + Hash + IndexKey<Item>> From<Vec<Item>> for Index<Item, K> {
fn from(items: Vec<Item>) -> Self {
let mut index = HashMap::new();
for i in 0..items.len() {
for k in K::keys(&items[i]) {
index.insert(k, i);
}
}
Self { items, index }
}
}
struct Item(String, i32);
#[derive(Eq, PartialEq, Hash)]
enum ItemBy<'a> {
Zero(Cow<'a, String>),
}
impl<'a> IndexKey<Item> for ItemBy<'a> {
fn keys(n: &Item) -> Vec<Self> {
vec![ItemBy::Zero(Cow::Owned(n.0.clone()))]
}
}
static XS: RwLock<Option<Index<Item, ItemBy>>> = RwLock::new(None);
fn f(k: &String) {
let mut xs = XS.write().unwrap();
let x = xs
.as_mut()
.unwrap()
.get_mut(&ItemBy::Zero(Cow::Borrowed(k)))
.unwrap();
x.1 = 2;
}
fn main() {
*XS.write().unwrap() = Some(vec![Item("aaaa".into(), 1)].into());
f(&String::from("aaaa"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment