-
Notifications
You must be signed in to change notification settings - Fork 55
Object List
Object List (ObjList) is the primary data abstraction in Husky. You can store your data as Objects in Object List. For example, you can store vertex Object in a vertex Object List, to represent vertexes in a graph, you can store each word as an Object in a word Object List to represent all the words in a corpus, or you can store all the data points together with their features in an Object List to represent each training data in a ML algorithm.
Object List is a distributed abstraction of Objects. It distributes among the cluster, but you don't need to understand all the details. An Object List can communicate with another Object List through Channels.
Now, let's see how to use Object List.
Suppose you have a type named Obj:
class Obj {
public:
using KeyT = int;
KeyT key;
const KeyT& id() const { return key; }
Obj() = default;
explicit Obj(const KeyT& k) : key(k) {}
};
Define an Obj in Husky is very simple. There are three things that you need to take care of:
-
You need to define what is the key type (KeyT) in your Object. In the example above, the key type is
int
. -
You need to write an id() function returning the key or your Object.
-
Object should have a default constructor, and a constructor taking only the key parameter.
That's all you need to do to define an object.
You can create an Object List in two ways, but the last way is preferred. You need to specify the Object Type for the Object List when creating an Object List.
// 1. Create an Object List from ObjListStore
auto& objlist = ObjListStore::create_objlist<Obj>();
// 2. Create an Object List from ObjListStore with a name
auto& objlist = ObjListStore::create_objlist<Obj>("my_objlist");
When you use ObjListStore to create an Object List, don't forget to get it using a reference "&".
The benefit of using the third method is that now your Objlist has a name. You can later access this Object List using name or drop the Object List permanently.
auto& objlist2 = ObjListStore::get_objlist<Obj>("my_objlist"); // The same list as before
ObjListStore::drop_objlist("my_objlist"); // my_objlist is dropped
ObjList stores the Object. So the next question is how to add objects into Object List.
It's straightforward. Just invoke add_object
!
// Suppose you have an Object List name objlist
Obj obj(3);
objlist.add_object(obj); // The Object is now in Object List
objlist.add_object(Obj(7)); // Add Object from an rvalue
Another way of adding Objects to Object list is sending messages to a non-exist Object, then the Object will be automatically created.
Two types of executors that are most relevant to Object List is globalize
and list_execute
.
If you want to let your Object List be located distributedly (e.g. you want to send messages to a specific Object), make sure your Object List is globalized. If not, use the globalize
function.
It's easy to understand the reason behind. When you add/delete some Objects in an Object List, the effect is only available locally. For example, when you add an object in thread 0, how do other threads know that this Object is in thread 0 but not others. So in this case, you need to globalize
your Object List to make each and every Object can be located globally. Then, when we want to send a message to an Object, Husky will help you figure out where the Object is.
// to globalize an Object List
globalize(objlist);
The most important function in Husky is probably the list_execute
.
list_execute
runs an user-defined function for every Object in an Object List.
list_execute(objlist, [](Obj& obj) {
base::log_msg("My id is: " + obj.id());
});
list_execute
takes two parameters. The first one is the Object List you want to play with and the second one is the user-defined function you want to add on each Object.
With Channels, you can specify which channels are used explicitly. You should define the in-coming channels and out-going channels as the second and the third parameters.
list_execute(objlist, {in_ch}, {out_ch}, [](Obj& obj) {
auto msg = in_ch.get(obj);
...
out_ch.push(msg);
});
Or you can ignore it, just as the previous example:
list_execute(objlist, [](Obj& obj) {
auto msg = in_ch.get(obj);
...
out_ch.push(msg);
});
TODO...
May introduce more operators for Object List which are seldom used by users.