]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Changelog:
authorJan Safranek <jsafrane@redhat.com>
Tue, 10 Aug 2010 09:36:18 +0000 (15:06 +0530)
committerBalbir Singh <balbir@linux.vnet.ibm.com>
Tue, 10 Aug 2010 09:36:18 +0000 (15:06 +0530)
 - update comments:
  - emphasize that 'dictionary' is not hash
  - emphasize that order is important
  - better describe what CG_DICT_DONT_FREE_ITEMS frees

For subsequent patch (update cgconfig parser to accept quoted-strings as
parameter values), I need a simple storage of name-value pairs, so let's
create simple linked-list framework. It's internal only, these functions
should probably never get public,

It is indeed very simple, it can only add items to the end and iterate
through the items, while preserving their order. It does *not* provide
random access to its items and it is *not* based on hash structure (at least for
now).

Signed-off-by: Jan Safranek <jsafrane@redhat.com>
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
src/api.c
src/libcgroup-internal.h

index 195e0e6aa26dffbd2a387f20827a36cb73ad48af..4bd6b463c56d3451a4d47c3a5911963d105c107c 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -3528,3 +3528,115 @@ int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size)
 
        return 0;
 }
+
+
+int cgroup_dictionary_create(struct cgroup_dictionary **dict,
+               int flags)
+{
+       *dict = (struct cgroup_dictionary *) calloc(
+                       1, sizeof(struct cgroup_dictionary));
+
+       if (!dict)
+               return ECGFAIL;
+       (*dict)->flags = flags;
+       return 0;
+}
+
+
+int cgroup_dictionary_add(struct cgroup_dictionary *dict,
+               const char *name, const char *value)
+{
+       struct cgroup_dictionary_item *it;
+
+       if (!dict)
+               return ECGINVAL;
+
+       it = (struct cgroup_dictionary_item *) malloc(
+                       sizeof(struct cgroup_dictionary_item));
+       if (!it)
+               return ECGFAIL;
+
+       it->next = NULL;
+       it->name = name;
+       it->value = value;
+
+       if (dict->tail) {
+               dict->tail->next = it;
+               dict->tail = it;
+       } else {
+               /* it is the first item */
+               dict->tail = it;
+               dict->head = it;
+       }
+       return 0;
+}
+
+int cgroup_dictionary_free(struct cgroup_dictionary *dict)
+{
+       struct cgroup_dictionary_item *it;
+
+       if (!dict)
+               return ECGINVAL;
+
+       it = dict->head;
+       while (it) {
+               struct cgroup_dictionary_item *del = it;
+               it = it->next;
+               if (!(dict->flags & CG_DICT_DONT_FREE_ITEMS)) {
+                       free((void *)del->value);
+                       free((void *)del->name);
+               }
+               free(del);
+       }
+
+       free(dict);
+       return 0;
+}
+
+int cgroup_dictionary_iterator_begin(struct cgroup_dictionary *dict,
+               void **handle, const char **name, const char **value)
+{
+       struct cgroup_dictionary_iterator *iter;
+
+       *handle = NULL;
+
+       if (!dict)
+               return ECGINVAL;
+
+       iter = (struct cgroup_dictionary_iterator *) malloc(
+                       sizeof(struct cgroup_dictionary_iterator));
+       if (!iter)
+               return ECGFAIL;
+
+       iter->item = dict->head;
+       *handle = iter;
+       return cgroup_dictionary_iterator_next(handle, name, value);
+}
+
+int cgroup_dictionary_iterator_next(void **handle,
+               const char **name, const char **value)
+{
+       struct cgroup_dictionary_iterator *iter;
+
+       if (!handle)
+               return ECGINVAL;
+
+       iter = *handle;
+       if (!iter->item)
+               return ECGEOF;
+
+       *name = iter->item->name;
+       *value = iter->item->value;
+       iter->item = iter->item->next;
+       return 0;
+}
+
+void cgroup_dictionary_iterator_end(void **handle)
+{
+       if (!handle)
+               return;
+
+       free(*handle);
+       *handle = NULL;
+}
+
index d232111a55d62ab312ebe5dc7f2aa23f32f356ff..92b9fd8d6fc1492de1bd65875a6e11c028b0bdf7 100644 (file)
@@ -128,6 +128,47 @@ struct cgroup_tree_handle {
        int flags;
 };
 
+/**
+ * Internal item of dictionary. Linked list is sufficient for now - we need
+ * only 'add' operation and simple iterator. In future, this might be easily
+ * rewritten to dynamic array when random access is needed,
+ * just keep in mind that the order is important and the iterator should
+ * return the items in the order they were added there.
+ */
+struct cgroup_dictionary_item {
+       const char *name;
+       const char *value;
+       struct cgroup_dictionary_item *next;
+};
+
+/* Flags for cgroup_dictionary_create */
+/**
+ * All items (i.e. both name and value strings) stored in the dictionary
+ * should *NOT* be free()d on cgroup_dictionary_free(),
+ * only the  dictionary helper structures (i.e. underlying linked list)
+ * should be freed.
+ */
+#define CG_DICT_DONT_FREE_ITEMS                1
+
+/**
+ * Dictionary of (name, value) items.
+ * The dictionary keeps its order, iterator iterates in the same order
+ * as the items were added there. It is *not* hash-style structure,
+ * it does not provide random access to its items nor quick search.
+ * This structure should be opaque to users of the dictionary, underlying data
+ * structure might change anytime and without warnings.
+ */
+struct cgroup_dictionary {
+       struct cgroup_dictionary_item *head;
+       struct cgroup_dictionary_item *tail;
+       int flags;
+};
+
+/** Opaque iterator of an dictionary. */
+struct cgroup_dictionary_iterator {
+       struct cgroup_dictionary_item *item;
+};
+
 /**
  * per thread errno variable, to be used when return code is ECGOTHER
  */
@@ -164,6 +205,39 @@ int cgroup_config_insert_into_mount_table(char *name, char *mount_point);
 int cgroup_config_insert_into_namespace_table(char *name, char *mount_point);
 void cgroup_config_cleanup_mount_table(void);
 void cgroup_config_cleanup_namespace_table(void);
+
+/**
+ * Create an empty dictionary.
+ */
+extern int cgroup_dictionary_create(struct cgroup_dictionary **dict,
+               int flags);
+/**
+ * Add an item to existing dictionary.
+ */
+extern int cgroup_dictionary_add(struct cgroup_dictionary *dict,
+               const char *name, const char *value);
+/**
+ * Fully destroy existing dictionary. Depending on flags passed to
+ * cgroup_dictionary_create(), names and values might get destroyed too.
+ */
+extern int cgroup_dictionary_free(struct cgroup_dictionary *dict);
+
+/**
+ * Start iterating through a dictionary. The items are returned in the same
+ * order as they were added using cgroup_dictionary_add().
+ */
+extern int cgroup_dictionary_iterator_begin(struct cgroup_dictionary *dict,
+               void **handle, const char **name, const char **value);
+/**
+ * Continue iterating through the dictionary.
+ */
+extern int cgroup_dictionary_iterator_next(void **handle,
+               const char **name, const char **value);
+/**
+ * Finish iteration through the dictionary.
+ */
+extern void cgroup_dictionary_iterator_end(void **handle);
+
 __END_DECLS
 
 #endif