* 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
