X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2539fff313cbd67c45b8490f7961e45e358d9ba2..51c23076e2b42ff07dc167dea1cb0e3a4ab3cf68:/src/xbt/dict_cursor.c diff --git a/src/xbt/dict_cursor.c b/src/xbt/dict_cursor.c index 48eab46c1d..f6b6a3d045 100644 --- a/src/xbt/dict_cursor.c +++ b/src/xbt/dict_cursor.c @@ -1,61 +1,31 @@ -/* $Id$ */ +/* dict_cursor - iterators over dictionaries */ -/* dict_cursor - iterators over dictionnaries */ - -/* Authors: Martin Quinson */ -/* Copyright (C) 2003,2004 Martin Quinson. */ +/* Copyright (c) 2004-2018. The SimGrid Team. + * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it - under the terms of the license (GNU LGPL) which comes with this package. */ + * under the terms of the license (GNU LGPL) which comes with this package. */ #include "xbt/misc.h" +#include "xbt/ex.h" #include "dict_private.h" -#include /* strlen() */ - -XBT_LOG_EXTERNAL_CATEGORY(dict); -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(dict_cursor,dict,"To traverse dictionaries"); +#include /* strlen() */ +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dict_cursor, xbt_dict, "To traverse dictionaries"); /*####[ Dict cursor functions ]#############################################*/ /* To traverse (simple) dicts */ /* Don't add or remove entries to the dict while traversing !!! */ /*###########################################################################*/ -struct xbt_dict_cursor_ { - /* we store all level encountered until here, to backtrack on next() */ - xbt_dynar_t keys; - xbt_dynar_t key_lens; - int pos; - int pos_len; - xbt_dictelm_t head; -}; - -static _XBT_INLINE void -_cursor_push_keys(xbt_dict_cursor_t p_cursor, - xbt_dictelm_t p_elm); - -#undef xbt_dict_CURSOR_DEBUG -/*#define xbt_dict_CURSOR_DEBUG 1*/ -/** - * xbt_dict_cursor_new: - * - * @head: the head of the dict - * @cursor: the curent position in the dict - * - * Structure creator +/** @brief Creator + * @param dict the dict */ -xbt_dict_cursor_t -xbt_dict_cursor_new(const xbt_dict_t head) { - xbt_error_t errcode = no_error; - xbt_dict_cursor_t res = NULL; - - res = xbt_new(s_xbt_dict_cursor_t,1); - res->keys = xbt_dynar_new(sizeof(char **), NULL); - res->key_lens = xbt_dynar_new(sizeof(int *), NULL); - res->pos = 0; - res->pos_len = 0; - res->head = head ? head->head : NULL; +inline xbt_dict_cursor_t xbt_dict_cursor_new(const xbt_dict_t dict) +{ + xbt_dict_cursor_t res = xbt_new(struct s_xbt_dict_cursor, 1); + res->dict = dict; xbt_dict_cursor_rewind(res); @@ -63,205 +33,146 @@ xbt_dict_cursor_new(const xbt_dict_t head) { } /** - * xbt_dict_cursor_free: - * - * @cursor: poor victim - * - * Structure destructor + * @brief Destructor + * @param cursor poor victim */ -void -xbt_dict_cursor_free(xbt_dict_cursor_t *cursor) { - if (*cursor) { - xbt_dynar_free(&((*cursor)->keys)); - xbt_dynar_free(&((*cursor)->key_lens)); - xbt_free(*cursor); - *cursor = NULL; - } +inline void xbt_dict_cursor_free(xbt_dict_cursor_t * cursor) +{ + xbt_free(*cursor); + *cursor = NULL; } -/** - * __cursor_not_null: - * +/* * Sanity check to see if the head contains something */ -static _XBT_INLINE -xbt_error_t -__cursor_not_null(xbt_dict_cursor_t cursor) { - - xbt_assert0(cursor, "Null cursor"); - - if (!cursor->head) { - return mismatch_error; - } - - return no_error; +static inline void __cursor_not_null(xbt_dict_cursor_t cursor) +{ + xbt_assert(cursor, "Null cursor"); } - -static _XBT_INLINE -void -_cursor_push_keys(xbt_dict_cursor_t cursor, - xbt_dictelm_t elm) { - xbt_error_t errcode = no_error; - xbt_dictelm_t child = NULL; - int i = 0; - static volatile int count = 0; /* ??? */ - - CDEBUG1(dict_cursor, "Push childs of %p in the cursor", (void*)elm); - - if (elm->content) { - xbt_dynar_push(cursor->keys, &elm->key ); - xbt_dynar_push(cursor->key_lens, &elm->key_len); - count++; - } - - xbt_dynar_foreach(elm->sub, i, child) { - if (child) - _cursor_push_keys(cursor, child); - } - - CDEBUG1(dict_cursor, "Count = %d", count); -} - -/** - * xbt_dict_cursor_rewind: - * @cursor: the cursor - * @Returns: xbt_error_t - * - * back to the first element - */ -void -xbt_dict_cursor_rewind(xbt_dict_cursor_t cursor) { - xbt_error_t errcode = no_error; - - CDEBUG0(dict_cursor, "xbt_dict_cursor_rewind"); +/** @brief Reinitialize the cursor. Mandatory after removal or add in dict. */ +inline void xbt_dict_cursor_rewind(xbt_dict_cursor_t cursor) +{ + XBT_CDEBUG(xbt_dict_cursor, "xbt_dict_cursor_rewind"); xbt_assert(cursor); - xbt_dynar_reset(cursor->keys); - xbt_dynar_reset(cursor->key_lens); - - if (!cursor->head) - return ; - - _cursor_push_keys(cursor, cursor->head); - - xbt_dynar_cursor_first(cursor->keys, &cursor->pos ); - xbt_dynar_cursor_first(cursor->key_lens, &cursor->pos_len); - + cursor->line = 0; + if (cursor->dict != NULL) { + cursor->current = cursor->dict->table[0]; + } else { + cursor->current = NULL; + } } /** - * xbt_dict_cursor_first: - * @dict: on what to let the cursor iterate - * @cursor: dest address + * @brief Create the cursor if it does not exists. Rewind it in any case. * - * Create the cursor if it does not exists. Rewind it in any case. + * @param dict on what to let the cursor iterate + * @param[out] cursor dest address */ -void xbt_dict_cursor_first (const xbt_dict_t dict, - xbt_dict_cursor_t *cursor){ - +inline void xbt_dict_cursor_first(const xbt_dict_t dict, xbt_dict_cursor_t * cursor) +{ + XBT_CDEBUG(xbt_dict_cursor, "xbt_dict_cursor_first"); if (!*cursor) { - DEBUG0("Create the cursor on first use"); - *cursor=xbt_dict_cursor_new(dict); + XBT_CDEBUG(xbt_dict_cursor, "Create the cursor on first use"); + *cursor = xbt_dict_cursor_new(dict); + } else { + xbt_dict_cursor_rewind(*cursor); + } + if (dict != NULL && (*cursor)->current == NULL) { + xbt_dict_cursor_step(*cursor); /* find the first element */ } - - xbt_dict_cursor_rewind(*cursor); } +/** \brief Move to the next element. */ +inline void xbt_dict_cursor_step(xbt_dict_cursor_t cursor) +{ + xbt_dictelm_t current; + int line; -/** - * xbt_dict_cursor_step: - * @cursor: the cursor - * - * Move to the next element. - */ -void -xbt_dict_cursor_step(xbt_dict_cursor_t cursor) { + XBT_CDEBUG(xbt_dict_cursor, "xbt_dict_cursor_step"); xbt_assert(cursor); - xbt_dynar_cursor_step(cursor->keys, &cursor->pos); - xbt_dynar_cursor_step(cursor->key_lens, &cursor->pos_len); + current = cursor->current; + line = cursor->line; + + if (cursor->dict != NULL) { + if (current != NULL) { + XBT_CDEBUG(xbt_dict_cursor, "current is not null, take the next element"); + current = current->next; + XBT_CDEBUG(xbt_dict_cursor, "next element: %p", current); + } + + while (current == NULL && (line + 1) <= cursor->dict->table_size) { + line++; + XBT_CDEBUG(xbt_dict_cursor, "current is NULL, take the next line"); + current = cursor->dict->table[line]; + XBT_CDEBUG(xbt_dict_cursor, "element in the next line: %p", current); + } + XBT_CDEBUG(xbt_dict_cursor, "search finished, current = %p, line = %d", current, line); + + cursor->current = current; + cursor->line = line; + } } /** - * xbt_dict_cursor_get_or_free: - * @cursor: the cursor - * @Returns: true if it's ok, false if there is no more data + * @brief Get current data, or free the cursor if there is no data left * - * Get current data + * @returns true if it's ok, false if there is no more data */ -int -xbt_dict_cursor_get_or_free(xbt_dict_cursor_t *cursor, - char **key, - void **data) { - xbt_error_t errcode = no_error; - int key_len = 0; - - if (!cursor || !(*cursor)) - return FALSE; +inline int xbt_dict_cursor_get_or_free(xbt_dict_cursor_t * cursor, char **key, void **data) +{ + xbt_dictelm_t current; - if (xbt_dynar_length((*cursor)->keys) <= (*cursor)->pos) { - xbt_dict_cursor_free(cursor); - return FALSE; - } - - *key = xbt_dynar_get_as((*cursor)->keys, (*cursor)->pos, char*); - key_len = xbt_dynar_get_as((*cursor)->key_lens, (*cursor)->pos_len, int); + XBT_CDEBUG(xbt_dict_cursor, "xbt_dict_get_or_free"); - errcode = xbt_dictelm_get_ext((*cursor)->head, *key, key_len, data); - if (errcode == mismatch_error) { + if (!cursor || !(*cursor)) + return 0; + + current = (*cursor)->current; + if (current == NULL) { /* no data left */ xbt_dict_cursor_free(cursor); - return FALSE; + return 0; } - xbt_assert1(errcode == no_error, - "Unexpected problem while retrieving the content of cursor. Got %s", - xbt_error_name(errcode)); - - return TRUE; + *key = current->key; + *data = current->content; + return 1; } /** - * xbt_dict_cursor_get_key: - * @cursor: the cursor - * @key: the current element - * @Returns: xbt_error_t - * - * Get current key + * @brief Get current key + * @param cursor: the cursor + * @returns the current key */ -xbt_error_t -xbt_dict_cursor_get_key(xbt_dict_cursor_t cursor, - /*OUT*/char **key) { - xbt_error_t errcode = no_error; +inline char *xbt_dict_cursor_get_key(xbt_dict_cursor_t cursor) +{ + __cursor_not_null(cursor); - TRY(__cursor_not_null(cursor)); - - *key = xbt_dynar_get_as(cursor->keys, cursor->pos - 1, char*); - - return errcode; + return cursor->current->key; } /** - * xbt_dict_cursor_get_data: - * @cursor: the cursor - * - * Get current data + * @brief Get current data + * @param cursor the cursor + * @returns the current data */ -xbt_error_t -xbt_dict_cursor_get_data(xbt_dict_cursor_t cursor, - /*OUT*/void **data) { - xbt_error_t errcode = no_error; - char *key = NULL; - int key_len = 0; +inline void *xbt_dict_cursor_get_data(xbt_dict_cursor_t cursor) +{ + __cursor_not_null(cursor); - TRY(__cursor_not_null(cursor)); - - key = xbt_dynar_get_as(cursor->keys, cursor->pos-1, char *); - key_len = xbt_dynar_get_as(cursor->key_lens, cursor->pos_len-1, int); - - TRY(xbt_dictelm_get_ext(cursor->head, key, key_len, data)); - - return errcode; + return cursor->current->content; } - +/** + * @brief Set current data + * @param cursor the cursor + * @param data the new data + * @param free_ctn unused parameter (kept for compatibility) + */ +inline void xbt_dict_cursor_set_data(xbt_dict_cursor_t cursor, void* data, XBT_ATTRIB_UNUSED void_f_pvoid_t free_ctn) +{ + __cursor_not_null(cursor); + xbt_dictelm_set_data(cursor->dict, cursor->current, data); +}