Changelog II:
- dictionary renamed to cg_param_list

Changelog:
 - update comments:
  - emphasize that 'dictionary' is not hash
  - emphasize that order is important
  - better describe what CG_DICT_DONT_FREE_ITEMS frees

8<---

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 <[email protected]>
---

 src/api.c                |  112 ++++++++++++++++++++++++++++++++++++++++++++++
 src/libcgroup-internal.h |   75 +++++++++++++++++++++++++++++++
 2 files changed, 187 insertions(+), 0 deletions(-)

diff --git a/src/api.c b/src/api.c
index dcdd75b..b9e5576 100644
--- a/src/api.c
+++ b/src/api.c
@@ -3390,3 +3390,115 @@ int cgroup_get_all_controller_begin(void **handle, 
struct controller_data *info)
 
        return cgroup_get_all_controller_next(handle, info);
 }
+
+
+int cg_param_list_create(struct cg_param_list **list,
+               int flags)
+{
+       *list = (struct cg_param_list *) calloc(
+                       1, sizeof(struct cg_param_list));
+
+       if (!list)
+               return ECGFAIL;
+       (*list)->flags = flags;
+       return 0;
+}
+
+
+int cg_param_list_add(struct cg_param_list *list,
+               const char *name, const char *value)
+{
+       struct cg_param *it;
+
+       if (!list)
+               return ECGINVAL;
+
+       it = (struct cg_param *) malloc(
+                       sizeof(struct cg_param));
+       if (!it)
+               return ECGFAIL;
+
+       it->next = NULL;
+       it->name = name;
+       it->value = value;
+
+       if (list->tail) {
+               list->tail->next = it;
+               list->tail = it;
+       } else {
+               /* it is the first item */
+               list->tail = it;
+               list->head = it;
+       }
+       return 0;
+}
+
+int cg_param_list_free(struct cg_param_list *list)
+{
+       struct cg_param *it;
+
+       if (!list)
+               return ECGINVAL;
+
+       it = list->head;
+       while (it) {
+               struct cg_param *del = it;
+               it = it->next;
+               if (!(list->flags & CG_LIST_DONT_FREE_ITEMS)) {
+                       free((void *)del->value);
+                       free((void *)del->name);
+               }
+               free(del);
+       }
+
+       free(list);
+       return 0;
+}
+
+int cg_param_list_iterator_begin(struct cg_param_list *list,
+               void **handle, const char **name, const char **value)
+{
+       struct cg_param_list_iterator *iter;
+
+       *handle = NULL;
+
+       if (!list)
+               return ECGINVAL;
+
+       iter = (struct cg_param_list_iterator *) malloc(
+                       sizeof(struct cg_param_list_iterator));
+       if (!iter)
+               return ECGFAIL;
+
+       iter->item = list->head;
+       *handle = iter;
+       return cg_param_list_iterator_next(handle, name, value);
+}
+
+int cg_param_list_iterator_next(void **handle,
+               const char **name, const char **value)
+{
+       struct cg_param_list_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 cg_param_list_iterator_end(void **handle)
+{
+       if (!handle)
+               return;
+
+       free(*handle);
+       *handle = NULL;
+}
+
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index d232111..9e49b5e 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -129,6 +129,48 @@ struct cgroup_tree_handle {
 };
 
 /**
+ * Internal item of parame_list. 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 cg_param {
+       const char *name;
+       const char *value;
+       struct cg_param *next;
+};
+
+/* Flags for cg_param_list_create */
+/**
+ * All items (i.e. both name and value strings) stored in the param_list
+ * should *NOT* be free()d on cg_param_list_free(),
+ * only the list helper structures (i.e. underlying linked list)
+ * should be freed.
+ */
+#define CG_LIST_DONT_FREE_ITEMS                1
+
+/**
+ * List of (name, value) items.
+ * The list 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 list, underlying data
+ * structure might change anytime and without warnings - e.g. to dynamic
+ * array.
+ */
+struct cg_param_list {
+       struct cg_param *head;
+       struct cg_param *tail;
+       int flags;
+};
+
+/** Opaque iterator of a parameter list. */
+struct cg_param_list_iterator {
+       struct cg_param *item;
+};
+
+/**
  * per thread errno variable, to be used when return code is ECGOTHER
  */
 extern __thread int last_errno;
@@ -164,6 +206,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 list of parameters.
+ */
+extern int cg_param_list_create(struct cg_param_list **list,
+               int flags);
+/**
+ * Add an item to existing list of parameters.
+ */
+extern int cg_param_list_add(struct cg_param_list *list,
+               const char *name, const char *value);
+/**
+ * Fully destroy existing list. Depending on flags passed to
+ * cg_param_list_create(), names and values might get destroyed too.
+ */
+extern int cg_param_list_free(struct cg_param_list *list);
+
+/**
+ * Start iterating through a list. The items are returned in the same
+ * order as they were added using cg_param_list_add().
+ */
+extern int cg_param_list_iterator_begin(struct cg_param_list *list,
+               void **handle, const char **name, const char **value);
+/**
+ * Continue iterating through the listy.
+ */
+extern int cg_param_list_iterator_next(void **handle,
+               const char **name, const char **value);
+/**
+ * Finish iteration through the list.
+ */
+extern void cg_param_list_iterator_end(void **handle);
+
 __END_DECLS
 
 #endif


------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to