let dashMap:DashMap<String,String>:DashMap::new();
// Then I put it into app_data of Actix to use it as a global variable,
// which is an Arc.
// Then when I want to use it in iteration :
for item:RefMulti<String,String> in dashMap.into_iter() {
...
}
I need to iterate the dashMap.
I'm not sure what to do with item as it is RefMulti type. I was expecting (k,v)
How would I access the key from iteration ?
Is there a nice way to access the (key, value) pairs even from RefMulti ?
[UPDATED WITH MRE]
//cargo.toml
actix-web = { version = "4.0.0-beta.6", features=["rustls"] }
dashmap = "4.0.2"
[code] is a gist, couldn't post it here. was getting formatting errors
Related
In short, I am interested in finding the most optimal, minimal call amount way of executing this pseudocode logic:
match find(doc) {
Some(x) => x.update(select_fields),
None=>collection.insert(all_fields)
}
but in bulk, for the entire local DB, without iterating one by one. Is there such a method? What's the most minimal one currently available?
My use case:
I have a HashMap<T,MyStruct>. I've packed both key and value into the doc!{}. Is that okay?
For some reason I was getting error trait From<u64> is not implemented for Bson in key3, so I changed my code to f64:
let dmp_op = my_database.lock().unwrap().clone();
let mut dmp_db = vec![];
for (k,v) in dmp_op{
dmp_db.push(doc! { "key": value, "key2": value2, "key3": value3 as f64 },
)
};
match collection.insert_many(dmp_db, None).await{
Ok(x)=>x,
Err(x)=>{
println!("{:?}",x);
continue
}
};
This part works, but that's non-repeatable. Instead of doing this, I'd love to execute the aforementioned logic in the most optimal way from scratch.
I can't find any information as to whether all the singular methods I used in an implementation of find_one_and_update() + upsert can be used in bulk.
PS: On second thought... maybe my infra logic is flawed? Just starting with MongoDB, what is more preferable:
Inserting/Updating one by one inside worker threads into MongoDB instead of local HashMap
Creating a separate thread that from time to time inserts into MongoDB the local HashMap / cleanses it to keep low resource?
Is there a better way than iter to convert HashMap to JsValue?
let mut map = HashMap::new<String, String>();
// put stuff in the map...
let obj = js_sys::Object::new();
for (k,v) in map.iter() {
let key = JsValue::from(k);
let value = JsValue::from(v);
js_sys::Reflect::set(&obj, &key, &value).unwrap();
}
JsValue::from(obj)
From Serializing and Deserializing Arbitrary Data Into and From JsValue with Serde in the wasm-bindgen guide: you can convert any type that is Serialize-able with the help of the serde-wasm-bindgen crate:
Using it, your code would look like this:
serde_wasm_bindgen::to_value(&map).unwrap()
The guide lists another crate, gloo-utils, that offers similar functionality but communicates data differently over the Wasm/Javascript bridge.
This is my data model:
pub struct RaffleDetails {
prize: Balance,
start: Timestamp,
end: Timestamp,
participants: UnorderedMap<AccountId, Balance>,
}
pub struct RaffleDapp {
raffles: UnorderedMap<AccountId, RaffleDetails>,
}
How can I insert a key-value pair in the 'participants' variable?
I tried self.raffles.get(&raffle_account_id).unwrap().participants.insert(&env::predecessor_account_id(), &confidence); but it's not persistent.
References:
UnorderedMap
NEAR Rust SDK
You need to make sure you are updating the RaffleDetails instance that is in the map, not a copy/clone of it.
I'm not familiar with UnorderedMap, but it seems to me the get() method returns a copy of the value that is in the map, so you are only updating the copied value. I don't know if UnorderedMap allows you to mutate a value in it directly (skimming through the docs, I don't see such a method). What you can do though is re-insert the modified RaffleDetails into the raffles map (so as to replace the old one with the modified one).
I'm talking about something like this (I haven't tested compiling it):
let o = self.raffles.get(&raffle_account_id);
if let copied_rd = Some(o) {
copied_rd.participants.insert(&env::predecessor_account_id(), &confidence);
self.raffles.insert(&raffle_account_id, &copied_rd);
}
I'm learning Rust (coming from Javascript), and in Rust I'm trying to create a component-based UI template. This is the minimum example I can reproduce in a Rust playground.
I have a Vector of Enums. I want to add components that will return a new set of vectors. The component returns a vector from a member function that is not a reference.
let _new_children = match new_view.unwrap() {
View::View(children) => children, // reference &Vec<View>
View::Render(ref component) => component.render(), // struct Vec<View>
};
let _new_children = match new_view.unwrap() {
View::View(children) => children,
View::Render(ref component) => &component.render(), // temporary value dropped while borrowed
};
How can I solve this problem? Do I need to rewrite the way functions check the difference between two vectors (itertools has a zip_longest method, which I also use).
In order to return a reference to a temporary you need to make the temporary live longer than the use of that reference.
In your code the temporary object is dropped as soon as the match branch ends, so a reference to it cannot escape the match.
There is a nice trick in Rust to extend the lifetime of a temporary. It consist in declaring the temporary name+ in the larger block where you want it to live, without initializing it. Then you assign-initialize it where the object temporary is actually created. Something like this:
let tmp_new;
let new_children = match new_view.unwrap() {
View::View(children) => children,
View::Render(ref component) => {
tmp_new = component.render();
&tmp_new }
};
Now new_children is of type &Vec<_> and it will live for the shorter of the two lifetimes of the match branches.
Note that unless you initialize the temporary in every branch of your match you cannot use tmp_new after it, because you will get:
use of possibly-uninitialized variable: tmp_new
I want to add a new key-value pair into Golang map from concurrent threads. Problem is that if there is a key present in the map we don't create new pair. From multithreaded perspective how to check the current condition and if key isn't present insert the key - value.
Is there any way to organize code to add key safely when first encountered?
The main problem is safely initializing mutex
Is there any way to organize code to add key safely when first encountered?
No. You need proper synchronisation.
I would recommend the combination of sync.Map to store the key-values and sync.Once inside of the value to perform the one-time initialization.
Here is an example:
type Value struct {
init sync.Once
someValue string
}
func (v *Value) Init() {
v.init.Do(func() {
// This function will only be executed one time
v.someValue = "initialized"
})
}
func main() {
var m sync.Map
v1, _ := m.LoadOrStore("key", &Value{})
v1.(*Value).Init() // init function is called
v2, _ := m.LoadOrStore("key", &Value{})
v2.(*Value).Init() // init function is not called
}