How can I store multiple elements in a Rust HashMap for the same key? - data-structures

I have a HashMap<u32, Sender>. Sender is a open connection object and the key is a user id. Each user can connect from multiple devices. I need to store all possible open connections for the same user id. After this I can iterate and send messages to all open connections for same user.
The above HashMap only stores each user id and connection once. I need to get one key with multiple values. How can I make the value into a list or an array, so I can see which connections exist and send to them all?
I am not talking about different value types, like enums. I am talking about the same type values but more than one. Maybe HashMap is not designed for this?
Alternative ideas are also welcomed.

To do this with a HashMap you should use a Vec as the values, so that each key can point to multiple Senders. The type then would be HashMap<u32, Vec<Sender>>.
Using this structure, just using insert() can get clunky when you need to mutate the values like this, but instead you can use the Entry API for retrieving and updating records in one go. For example:
let mut hash_map: HashMap<u32, Vec<Sender>> = HashMap::new();
hash_map.entry(3)
// If there's no entry for key 3, create a new Vec and return a mutable ref to it
.or_default()
// and insert the item onto the Vec
.push(sender);
You could also use the multimap crate, which does something similar under the hood, but adds a layer of abstraction. You might find it easier to work with:
let mut multi_map = MultiMap::new();
multi_map.insert(3, sender_1);
multi_map.insert(3, sender_2);
The method multi_map.get(key) will the first value with that key, while multi_map.get_vec(key) will retrieve all of them.

Related

Is there a generic way to access objects in UFT

My task is to check the value of data from the global data sheet within different UIs, each of them having lots of data.
My idea was to do this in a generic way.
I create a array with the objects name, which corresponds with the name of the data sheet column
And then I just compare the content
Browser("").Page("").GENERIC_TYPE(label).GetROProperty("value") = datasheet.GetParameter(label)
Is there such a Generic Type that works for WebEdit and WebList?
You can use WebElement and this is generic as all elements on the page are web elements.
If you are reading the objects from OR, then you might have to update the element type to WebElement and it's tidious (if you are dealing with multiple objects). So the alternative way is using the below approach.
Browser("").Page("").WebElement("xpath:=//*[#common_attribute=" + element_attribute_value + "]").GetROProperty("value") = datasheet.GetParameter(label)

macOS command line app - User Defaults dictionaryRepresentation shows too many values

I a developing a macOS commandline application in Xcode, which uses User Defaults. I have the following code for my User Defaults
if let configDefaults = UserDefaults.init(suiteName: "com.tests.configuration") {
configDefaults.set("myStringValue", forKey: "stringKey")
configDefaults.synchronize()
print(configDefaults.dictionaryRepresentation())
}
This will create my own .plist file in the ~/Library/Preferences folder. If I look into the file, I can see only my single value which I added, which is perfectly fine. But when I call dictionaryRepresentation() on my UserDefaults object, the there are a lot of other attributes (I guess from the shared UserDefaults object), like
com.apple.trackpad.twoFingerFromRightEdgeSwipeGesture or AKLastEmailListRequestDateKey
Looking into the documentation of UserDefaults, it seems that this has to do with the search list of UserDefaults and that the standard object is in the search list:
func dictionaryRepresentation() -> [String : Any]
Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.
There are also the methods addSuite and removeSuite for a UserDefaults object, so I am guessing I need to remove the .standard suite from my configDefaults object, but I don't know the name, which should be used for that in the method.
Is it possible to remove the .standard defaults from the dictionary representation? I basically just want all of my own data in a dictionary, nothing more.
The reason I am trying to get only my values from the UserDefaults, is that a have a number of object of a custom type Connection (which store the configuration to connect to a server), which are saved in the UserDefaults. On program start I want to be able to load all objects into my app. Therefore I thought I could use dictionaryRepresentation(), as it would return all elements in the UserDefaults. But then there should be only my Connection objects in the dictionary, so that I can cast it to [String: Connection].
Given your purpose (in your latest edit of your question), what you should do is store a collection of Connection objects under a single key. Then, look up that key to get the collection.
It's not clear if the collection should be an array of Connection objects or a dictionary mapping strings to Connections. That's a choice you can make.
But, in any case, you shouldn't rely on the defaults being empty of everything else.
In other words, you would do:
UserDefaults.standard.set(yourStringToConnectionDictionary, forKey:"yourSingleKey")
and later:
let connectionMap = UserDefaults.dictionary(forKey:"yourSingleKey")
then look up Connections in the connectionMap by their name/ID/whatever.
Though the other solution proposed by Ken Thomases may be better from a design standpoint, I've found a solution that does exactly what I initially wanted. Calling
UserDefaults.standard.persistentDomain(forName: "com.company.TestApp.configuration")
Returns a dictionary containing only the values I've added to the domain com.company.TestApp.configuration, using
let configs = UserDefaults.init(suiteName: "com.company.TestApp.configuration")!
configs.set(someData, forKey: someKey)
Strangely in the Apple documentation says this about persistentDomain(forName:):
Calling this method is equivalent to initializing a user defaults object with init(suiteName:) passing domainName and calling the dictionaryRepresentation() method on it.
But this is not the case (see my question). Clarification on that subject is more than welcome.

What is the purpose of RocksDBStore with Serdes.Bytes() and Serdes.ByteArray()?

RocksDBStore<K,V> stores keys and values as byte[] on disk. It converts to/from K and V typed objects using Serdes provided while constructing the object of RocksDBStore<K,V>.
Given this, please help me understand the purpose of the following code in RocksDbKeyValueBytesStoreSupplier:
return new RocksDBStore<>(name,
Serdes.Bytes(),
Serdes.ByteArray());
Providing Serdes.Bytes() and Serdes.ByteArray() looks redundant.
RocksDbKeyValueBytesStoreSupplier is introduced in KAFKA-5650 (Kafka Streams 1.0.0) as part of KIP-182: Reduce Streams DSL overloads and allow easier use of custom storage engines.
In KIP-182, there is the following sentence :
The new Interface BytesStoreSupplier supersedes the existing StateStoreSupplier (which will remain untouched). This so we can provide a convenient way for users creating custom state stores to wrap them with caching/logging etc if they chose. In order to do this we need to force the inner most store, i.e, the custom store, to be a store of type <Bytes, byte[]>.
Please help me understand why we need to force custom stores to be of type <Bytes, byte[]>?
Another place (KAFKA-5749) where I found similar sentence:
In order to support bytes store we need to create a MeteredSessionStore and ChangeloggingSessionStore. We then need to refactor the current SessionStore implementations to use this. All inner stores should by of type < Bytes, byte[] >
Why?
Your observation is correct -- the PR implementing KIP-182 did miss to remove the Serdes from RocksDBStore that are not required anymore. This was fixed in 1.1 release already.

Multiple parallel Increments on Parse.Object

Is it acceptable to perform multiple increment operations on different fields of the same object on Parse Server ?
e.g., in Cloud Code :
node.increment('totalExpense', cost);
node.increment('totalLabourCost', cost);
node.increment('totalHours', hours);
return node.save(null,{useMasterKey: true});
seems like mongodb supports it, based on this answer, but does Parse ?
Yes. One thing you can't do is both add and remove something from the same array within the same save. You can only do one of those operations. But, incrementing separate keys shouldn't be a problem. Incrementing a single key multiple times might do something weird but I haven't tried it.
FYI you can also use the .increment method on a key for a shell object. I.e., this works:
var node = new Parse.Object.("Node");
node.id = request.params.nodeId;
node.increment("myKey", value);
return node.save(null, {useMasterKey:true});
Even though we didn't fetch the data, we don't need to know the previous value in order to increment it on the database. Note that you don't have the data so can't access any other necessary data here.

How do you query Active record with enums

I am trying this query and it is not working:
OrderFulfillment.where(shopper_id: shopper.id, fulfillment_status: [:fulfillment_requested_assignment, :fulfillment_assigned, :fulfillment_shopping])
I am not sure why but I am unable to get querying using enums to work
OrderFulfillment.where(shopper_id: shopper.id,
fulfillment_status: OrderFulfillment
.fulfillment_statuses
.values_at([:fulfillment_requested_assignment,
:fulfillment_assigned,
:fulfillment_shopping]))
Rails isn't smart enough to know that you are passing keys and not values, so when you were passing the statuses straight like that it was looking for the wrong values (it changed them to null because it didn't understand). The enums are physically stored as integers, so that's what you actually need to use in the query. Therefore, you can use the Rails-provided fulfillment_statuses method to grab a hash of the key/value pairs of the enum, and then the values_at method of the hash to get the values for the array of keys you pass in.

Resources