Containers are data structures meant to store several objects, and perform various operations on them. Internally, objects are stored in lists, hash tables
or other data structures depending on the needs.
- NOTA BENE: at the moment the only container we support is the hash table and its degenerate form, the list.
Operations on container include:
- c = ao2_container_alloc(size, cmp_fn, hash_fn) allocate a container with desired size and default compare and hash function
- ao2_find(c, arg, flags) returns zero or more element matching a given criteria (specified as arg). Flags indicate how many results we want (only one or all matching entries), and whether we should unlink the object from the container.
- ao2_callback(c, flags, fn, arg) apply fn(obj, arg) to all objects in the container. Similar to find. fn() can tell when to stop, and do anything with the object including unlinking it. Note that the entire operation is run with the container locked, so noone else can change its content while we work on it. However, we pay this with the fact that doing anything blocking in the callback keeps the container blocked. The mechanism is very flexible because the callback function fn() can do basically anything e.g. counting, deleting records, etc. possibly using arg to store the results.
- iterate on a container this is done with the following sequence
The difference with the callback is that the control on how to iterate is left to us.
- ao2_ref(c, -1) dropping a reference to a container destroys it, very simple!
Containers are ao2 objects themselves, and this is why their implementation is simple too.
Before declaring containers, we need to declare the types of the arguments passed to the constructor - in turn, this requires to define callback and hash functions and their arguments.