Exemplo n.º 1
0
void
sane_qsort(void *array[], int left, int right, comp_func compare)
{

  int i, last;
  void *tmp;

loop:
  if (left >= right)
    return;

  /* Pick something at random at swap it into the leftmost slot   */
  /* This is the pivot, we'll put it back in the right spot later */

  i = get_random32(left, right);
  tmp = array[i];
  array[i] = array[left];
  array[left] = tmp;

  last = left;
  for (i = left + 1; i <= right; i++) {

    /* Walk the array, looking for stuff that's less than our */
    /* pivot. If it is, swap it with the next thing along     */

    if (compare(array[i], array[left]) < 0) {
      last++;
      if (last == i)
        continue;

      tmp = array[last];
      array[last] = array[i];
      array[i] = tmp;
    }
  }

  /* Now we put the pivot back, it's now in the right spot, we never */
  /* need to look at it again, trust me.                             */

  tmp = array[last];
  array[last] = array[left];
  array[left] = tmp;

  /* At this point everything underneath the 'last' index is < the */
  /* entry at 'last' and everything above it is not < it.          */

  if ((last - left) < (right - last)) {
    sane_qsort(array, left, last - 1, compare);
    left = last + 1;
    goto loop;
  } else {
    sane_qsort(array, last + 1, right, compare);
    right = last - 1;
    goto loop;
  }
}
Exemplo n.º 2
0
/** Do cuckoo hash cycling */
static bool
hash_insert(HASHTAB *htab, const char *key, int keylen, void *data)
{
  int loop = 0, n;
  struct hash_bucket bump;

  bump.key = key;
  bump.keylen = keylen;
  bump.data = data;

  while (loop < BUMP_LIMIT) {
    int hval;
    struct hash_bucket temp;

    /* See if bump has any empty choices and use it */
    for (n = 0; n < NHASH_TRIES; n++) {
      hash_func hash;
      int hashindex = (n + htab->hashfunc_offset) % NHASH_MOD;

      hash = hash_functions[hashindex];
      hval = hash(bump.key, bump.keylen, hash_seed) % htab->hashsize;
      if (htab->buckets[hval].key == NULL) {
        htab->buckets[hval] = bump;
        return true;
      }
    }

    /* None. Use a random func and bump the existing element */
    n = htab->hashfunc_offset + get_random32(0, NHASH_TRIES - 1);
    n %= NHASH_MOD;
    hval =
      (hash_functions[n]) (bump.key, bump.keylen, hash_seed) % htab->hashsize;
    temp = htab->buckets[hval];
    htab->buckets[hval] = bump;
    bump = temp;
    loop += 1;
  }

  /* At this point, we've bumped BUMP_LIMIT times. Probably in a
     loop. Find the first empty bucket, add the last bumped to, and
     return failure. The table will have to be resized now to restore
     the hash. */
  for (n = 0; n < htab->hashsize; n++)
    if (htab->buckets[n].key == NULL) {
      htab->buckets[n] = bump;
      return false;
    }

  /* Never reached. */
  return false;
}
Exemplo n.º 3
0
/** The whisper command.
 * \param player the enactor.
 * \param arg1 name of the object to whisper to.
 * \param arg2 message to whisper.
 * \param noisy if 1, others overhear that a whisper has occurred.
 * \param pe_info the pe_info for evaluating interact locks
 */
void
do_whisper(dbref player, const char *arg1, const char *arg2, int noisy,
           NEW_PE_INFO *pe_info)
{
  dbref who;
  int key;
  const char *gap;
  char *tbuf, *tp;
  char *p;
  dbref good[100];
  int gcount = 0;
  const char *head;
  int overheard;
  char *current;
  const char **start;
  char sname[BUFFER_LEN];

  if (!arg1 || !*arg1) {
    notify(player, T("Whisper to whom?"));
    return;
  }
  if (!arg2 || !*arg2) {
    notify(player, T("Whisper what?"));
    return;
  }
  tp = tbuf = (char *) mush_malloc(BUFFER_LEN, "string");
  if (!tbuf)
    mush_panic("Unable to allocate memory in do_whisper");

  overheard = 0;
  head = arg1;
  start = &head;
  /* Figure out what kind of message */
  gap = " ";
  switch (*arg2) {
  case SEMI_POSE_TOKEN:
    gap = "";
  case POSE_TOKEN:
    key = 1;
    arg2++;
    break;
  default:
    key = 2;
    break;
  }

  *tp = '\0';
  /* Make up a list of good and bad names */
  while (head && *head) {
    current = next_in_list(start);
    who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS |
                       MAT_CONTAINER);
    if (!GoodObject(who) || !can_interact(player, who, INTERACT_HEAR, pe_info)) {
      safe_chr(' ', tbuf, &tp);
      safe_str_space(current, tbuf, &tp);
      if (GoodObject(who))
        notify_format(player, T("%s can't hear you."),
                      AName(who, AN_SYS, NULL));
    } else {
      /* A good whisper */
      good[gcount++] = who;
      if (gcount >= 100) {
        notify(player, T("Too many people to whisper to."));
        break;
      }
    }
  }

  *tp = '\0';
  if (*tbuf)
    notify_format(player, T("Unable to whisper to:%s"), tbuf);

  if (!gcount) {
    mush_free(tbuf, "string");
    return;
  }

  /* Drunk wizards... */
  if (Dark(player))
    noisy = 0;

  /* Set up list of good names */
  tp = tbuf;
  safe_str(T(" to "), tbuf, &tp);
  for (who = 0; who < gcount; who++) {
    if (noisy && (get_random32(0, 100) < (uint32_t) WHISPER_LOUDNESS))
      overheard = 1;
    safe_itemizer(who + 1, (who == gcount - 1), ",", T("and"), " ", tbuf, &tp);
    safe_str(AName(good[who], AN_SAY, NULL), tbuf, &tp);
  }
  *tp = '\0';

  if (key == 1) {
    notify_format(player, (gcount > 1) ? T("%s sense: %s%s%s") :
                  T("%s senses: %s%s%s"), tbuf + 4, AName(player, AN_SAY, NULL),
                  gap, arg2);
    p = tprintf("You sense: %s%s%s", AName(player, AN_SAY, NULL), gap, arg2);
  } else {
    notify_format(player, T("You whisper, \"%s\"%s."), arg2, tbuf);
    p = tprintf(T("%s whispers%s: %s"), AName(player, AN_SAY, NULL),
                gcount > 1 ? tbuf : "", arg2);
  }

  strcpy(sname, AName(player, AN_SAY, NULL));
  for (who = 0; who < gcount; who++) {
    notify_must_puppet(good[who], p);
    if (Location(good[who]) != Location(player))
      overheard = 0;
  }
  if (overheard) {
    dbref first = Contents(Location(player));
    if (!GoodObject(first))
      return;
    p = tprintf(T("%s whispers%s."), sname, tbuf);
    DOLIST(first, first) {
      overheard = 1;
      for (who = 0; who < gcount; who++) {
        if ((first == player) || (first == good[who])) {
          overheard = 0;
          break;
        }
      }
      if (overheard)
        notify_noecho(first, p);
    }
  }