Ejemplo n.º 1
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Sorts a dynar according to their color assuming elements can have only three colors.
 * Since there are only three colors, it is linear and much faster than a classical sort.
 * See for example http://en.wikipedia.org/wiki/Dutch_national_flag_problem
 *
 * \param dynar the dynar to sort
 * \param color the color function of type (int (compar_fn*) (void*) (void*)). The return value of color is assumed to
 *        be 0, 1, or 2.
 *
 * At the end of the call, elements with color 0 are at the beginning of the dynar, elements with color 2 are at the
 * end and elements with color 1 are in the middle.
 *
 * Remark: if the elements stored in the dynar are structures, the color function has to retrieve the field to sort
 * first.
 */
XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar, int_f_pvoid_t color)
{
  unsigned long int i;
  unsigned long int p = -1;
  unsigned long int q = dynar->used;
  const unsigned long elmsize = dynar->elmsize;
  void *tmp = xbt_malloc(elmsize);
  void *elm;

  for (i = 0; i < q;) {
    void *elmi = _xbt_dynar_elm(dynar, i);
    int colori = color(elmi);

    if (colori == 1) {
      ++i;
    } else {
      if (colori == 0) {
        elm = _xbt_dynar_elm(dynar, ++p);
        ++i;
      } else {                  /* colori == 2 */
        elm = _xbt_dynar_elm(dynar, --q);
      }
      if (elm != elmi) {
        memcpy(tmp,  elm,  elmsize);
        memcpy(elm,  elmi, elmsize);
        memcpy(elmi, tmp,  elmsize);
      }
    }
  }
  xbt_free(tmp);
}
Ejemplo n.º 2
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Remove a slice of the dynar, sliding the rest of the values to the left
 *
 * This function removes an n-sized slice that starts at element idx. It is equivalent to xbt_dynar_remove_at with a
 * NULL object argument if n equals to 1.
 *
 * Each of the removed elements is freed using the free_f function passed at dynar creation.
 */
void xbt_dynar_remove_n_at(xbt_dynar_t const dynar, const unsigned int n, const int idx)
{
  unsigned long nb_shift;
  unsigned long offset;
  unsigned long cur;

  if (!n) return;

  _sanity_check_dynar(dynar);
  _check_inbound_idx(dynar, idx);
  _check_inbound_idx(dynar, idx + n - 1);

  if (dynar->free_f) {
    for (cur = idx; cur < idx + n; cur++) {
      dynar->free_f(_xbt_dynar_elm(dynar, cur));
    }
  }

  nb_shift = dynar->used - n - idx;

  if (nb_shift) {
    offset = nb_shift * dynar->elmsize;
    memmove(_xbt_dynar_elm(dynar, idx), _xbt_dynar_elm(dynar, idx + n), offset);
  }

  dynar->used -= n;
}
Ejemplo n.º 3
0
/** @brief Remove the Nth dynar's element, sliding the previous values to the left
 *
 * Get the Nth element of a dynar, removing it from the dynar and moving
 * all subsequent values to one position left in the dynar.
 *
 * If the object argument of this function is a non-null pointer, the removed
 * element is copied to this address. If not, the element is freed using the
 * free_f function passed at dynar creation.
 */
void
xbt_dynar_remove_at(xbt_dynar_t const dynar,
                    const int idx, void *const object)
{
  unsigned long nb_shift;
  unsigned long offset;

  _sanity_check_dynar(dynar);
  _check_inbound_idx(dynar, idx);

  if (object) {
    _xbt_dynar_get_elm(object, dynar, idx);
  } else if (dynar->free_f) {
    dynar->free_f(_xbt_dynar_elm(dynar, idx));
  }

  nb_shift = dynar->used - 1 - idx;

  if (nb_shift) {
    offset = nb_shift * dynar->elmsize;
    memmove(_xbt_dynar_elm(dynar, idx), _xbt_dynar_elm(dynar, idx + 1),
            offset);
  }

  dynar->used--;
}
Ejemplo n.º 4
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Make room for a new element, and return a pointer to it
 *
 * You can then use regular affectation to set its value instead of relying on the slow memcpy. This is what
 * xbt_dynar_insert_at_as() does.
 */
void *xbt_dynar_insert_at_ptr(xbt_dynar_t const dynar, const int idx)
{
  void *res;
  unsigned long old_used;
  unsigned long new_used;
  long nb_shift;

  _sanity_check_dynar(dynar);
  _sanity_check_idx(idx);

  old_used = dynar->used;
  new_used = old_used + 1;

  _xbt_dynar_expand(dynar, new_used);

  nb_shift = old_used - idx;

  if (nb_shift>0) {
    memmove(_xbt_dynar_elm(dynar, idx + 1), _xbt_dynar_elm(dynar, idx), nb_shift * dynar->elmsize);
  }

  dynar->used = new_used;
  res = _xbt_dynar_elm(dynar, idx);
  return res;
}
Ejemplo n.º 5
0
Archivo: dynar.c Proyecto: R7R8/simgrid
inline void *xbt_dynar_set_at_ptr(const xbt_dynar_t dynar, const unsigned long idx)
{
  _sanity_check_dynar(dynar);

  if (idx >= dynar->used) {
    _xbt_dynar_expand(dynar, idx + 1);
    if (idx > dynar->used) {
      memset(_xbt_dynar_elm(dynar, dynar->used), 0, (idx - dynar->used) * dynar->elmsize);
    }
    dynar->used = idx + 1;
  }
  return _xbt_dynar_elm(dynar, idx);
}
Ejemplo n.º 6
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Mark the last dynar's element as unused and return a pointer to it.
 *
 * You can then use regular affectation to set its value instead of relying on the slow memcpy. This is what
 * xbt_dynar_pop_as() does.
 */
inline void *xbt_dynar_pop_ptr(xbt_dynar_t const dynar)
{
  _check_populated_dynar(dynar);
  XBT_CDEBUG(xbt_dyn, "Pop %p", (void *) dynar);
  dynar->used--;
  return _xbt_dynar_elm(dynar, dynar->used);
}
Ejemplo n.º 7
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Merge dynar d2 into d1
 *
 * \param d1 dynar to keep
 * \param d2 dynar to merge into d1. This dynar is free at end.
 */
void xbt_dynar_merge(xbt_dynar_t *d1, xbt_dynar_t *d2)
{
  if((*d1)->elmsize != (*d2)->elmsize)
    xbt_die("Element size must are not equal");

  const unsigned long elmsize = (*d1)->elmsize;

  void *ptr = _xbt_dynar_elm((*d2), 0);
  _xbt_dynar_resize(*d1, (*d1)->size + (*d2)->size);
  void *elm = _xbt_dynar_elm((*d1), (*d1)->used);

  memcpy(elm, ptr, ((*d2)->size)*elmsize);
  (*d1)->used += (*d2)->used;
  (*d2)->used = 0;
  xbt_dynar_free(d2);
}
Ejemplo n.º 8
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Retrieve a pointer to the Nth element of a dynar.
 *
 * \param dynar information dealer
 * \param idx index of the slot we want to retrieve
 * \return the \a idx-th element of \a dynar.
 *
 * \warning The returned value is the actual content of the dynar.
 * Make a copy before fooling with it.
 */
inline void *xbt_dynar_get_ptr(const xbt_dynar_t dynar, const unsigned long idx)
{
  void *res;
  _sanity_check_dynar(dynar);
  _check_inbound_idx(dynar, idx);

  res = _xbt_dynar_elm(dynar, idx);
  return res;
}
Ejemplo n.º 9
0
static XBT_INLINE
    void
_xbt_dynar_get_elm(void *const dst,
                   const xbt_dynar_t dynar, const unsigned long idx)
{
  void *const elm = _xbt_dynar_elm(dynar, idx);

  memcpy(dst, elm, dynar->elmsize);
}
Ejemplo n.º 10
0
static XBT_INLINE
    void
_xbt_dynar_put_elm(const xbt_dynar_t dynar,
                   const unsigned long idx, const void *const src)
{
  void *const elm = _xbt_dynar_elm(dynar, idx);
  const unsigned long elmsize = dynar->elmsize;

  memcpy(elm, src, elmsize);
}
Ejemplo n.º 11
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Returns the position of the element in the dynar (or -1 if not found)
 *
 * Beware that if your dynar contains pointed values (such as strings) instead of scalar, this function is probably not
 * what you want. Check the documentation of xbt_dynar_search() for more info.
 * 
 * Note that usually, the dynar indices are unsigned integers. If you have more than 2 million elements in your dynar,
 * this very function will not work (but the other will).
 */
signed int xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const elem)
{
  unsigned long it;

  for (it = 0; it < dynar->used; it++)
    if (!memcmp(_xbt_dynar_elm(dynar, it), elem, dynar->elmsize)) {
      return it;
    }

  return -1;
}
Ejemplo n.º 12
0
/** @brief Returns a boolean indicating whether the element is part of the dynar
 *
 * Beware that if your dynar contains pointed values (such as strings) instead of scalar, this function is probably not
 * what you want. Check the documentation of xbt_dynar_search() for more info.
 */
int xbt_dynar_member(xbt_dynar_t const dynar, void* const elem)
{
  unsigned long it;

  for (it = 0; it < dynar->used; it++)
    if (not memcmp(_xbt_dynar_elm(dynar, it), elem, dynar->elmsize)) {
      return 1;
    }

  return 0;
}
Ejemplo n.º 13
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Returns the position of the element in the dynar
 *
 * Beware that if your dynar contains pointed values (such as strings) instead of scalar, this function compares the
 * pointer value, not what's pointed. The only solution to search for a pointed value is then to write the foreach loop
 * yourself:
 * \code
 * signed int position = -1;
 * xbt_dynar_foreach(dynar, iter, elem) {
 *    if (!memcmp(elem, searched_element, sizeof(*elem))) {
 *        position = iter;
 *        break;
 *    }
 * }
 * \endcode
 * 
 * Raises not_found_error if not found. If you have less than 2 millions elements, you probably want to use
 * #xbt_dynar_search_or_negative() instead, so that you don't have to TRY/CATCH on element not found.
 */
unsigned int xbt_dynar_search(xbt_dynar_t const dynar, void *const elem)
{
  unsigned long it;

  for (it = 0; it < dynar->used; it++)
    if (!memcmp(_xbt_dynar_elm(dynar, it), elem, dynar->elmsize)) {
      return it;
    }

  THROWF(not_found_error, 0, "Element %p not part of dynar %p", elem, dynar);
  return -1; // Won't happen, just to please eclipse
}
Ejemplo n.º 14
0
Archivo: dynar.c Proyecto: R7R8/simgrid
/** @brief Set the Nth element of a dynar (expanded if needed). Previous value is freed
 *
 * \param dynar
 * \param idx
 * \param object
 *
 * Set the Nth element of a dynar, expanding the dynar if needed, AND DO free the previous value at this position. If
 * you don't want to free the previous content, use xbt_dynar_set().
 */
void xbt_dynar_replace(xbt_dynar_t dynar, const unsigned long idx, const void *const object)
{
  _sanity_check_dynar(dynar);

  if (idx < dynar->used && dynar->free_f) {
    void *const old_object = _xbt_dynar_elm(dynar, idx);

    dynar->free_f(old_object);
  }

  xbt_dynar_set(dynar, idx, object);
}