* Jan Safranek <[email protected]> [2010-07-29 12:22:25]:

> For subsequent patch, 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,
>

Since we'll be committing the changelog, it would be nice to have a description
of what you need it for.
 
> It is indeed very simple, it can only add items to the end and iterate
> through the items, while preserving their order.
> 
> Signed-off-by: Jan Safranek <[email protected]>
> ---
> 
>  src/api.c                |  112 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  src/libcgroup-internal.h |   66 +++++++++++++++++++++++++++
>  2 files changed, 178 insertions(+), 0 deletions(-)
> 
> diff --git a/src/api.c b/src/api.c
> index dcdd75b..2d46cc6 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 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;
> +}
> +
> diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
> index d232111..3d70a0d 100644
> --- a/src/libcgroup-internal.h
> +++ b/src/libcgroup-internal.h
> @@ -128,6 +128,39 @@ struct cgroup_tree_handle {
>       int flags;
>  };
> 
> +/** Internal item of dictionary */
> +struct cgroup_dictionary_item {
> +     const char *name;
> +     const char *value;
> +     struct cgroup_dictionary_item *next;

A singly linked list is sufficient for the dictionary?
Is there a reason why you prefer a list to say a hash
table? Is it because you care about the order?

> +};
> +
> +/* 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 should be freed.
> + */
> +#define CG_DICT_DONT_FREE_ITEMS              1
> +

What is a dictionary helper structure?

> +/**
> + * Dictionary of (name, value) items.
> + * The dictionary keeps its order, iterator iterates in the same order
> + * as the items were added there.

OK, so order is important

> + * 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 +197,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
> 

-- 
        Three Cheers,
        Balbir

------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share
of $1 Million in cash or HP Products. Visit us here for more details:
http://p.sf.net/sfu/dev2dev-palm
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to