예제 #1
0
void intro_sort ( iter_t first, iter_t last,compare comp = compare())
{   //------------------------- begin ----------------------
    auto N = last - first;
    assert ( N > 0);
    uint32_t Level = (MS1B ( N)+1)<<1 ;
    intro_sort_internal ( first , last, Level,comp);
};
예제 #2
0
void hopscotch_fill(struct hopscotch_t* h, iter_t iter, void* opaque)
{
  for (int i = 0; i < h->size; i++) h->array[i] = *(iter(opaque));
  struct stats_t stats;
  create_stats(&h->array[0], h->size, &stats);
  int target_value = h->size / 20;
  h->neighborhood_size = (CACHE_LINE_BYTES / 2) / sizeof(item_t);
  int needed_bits = MS1B(h->size);
  if (h->size > ((1 << needed_bits) + h->neighborhood_size - 1)) needed_bits++;
  for (;;)
  {
    h->mask = choose_hash_func_mask(&stats, needed_bits, target_value);
    h->bits_used = popcount(h->mask);
    int num_buckets = 1 << h->bits_used;
    //printf("size: %d, num_buckets: %d\n", h->size, num_buckets);
    h->buckets = (item_t*)calloc(num_buckets + h->neighborhood_size - 1, sizeof(item_t));
    int *metadata = (int*)calloc(num_buckets + h->neighborhood_size - 1, sizeof(int));
    for (int item_being_placed = 0; item_being_placed < h->size; item_being_placed++)
    {
      //printf("begin trying to place item #%d: %08X\n", item_being_placed, h->array[item_being_placed]);
      int key = (int)apply_simple_hash_function(h->array[item_being_placed], h->mask);
      //printf("key is: %d\n", key);
      int probe = key;
      int neighborhood_i = 0;
      for ( ; neighborhood_i < h->neighborhood_size; probe++, neighborhood_i++)
      {
        if (h->buckets[probe] == 0)
        {
        place_in_keys_neighborhood:
          //printf("placing into bucket %d, as item %d of key %d\n", probe, neighborhood_i, key);
          h->buckets[probe] = h->array[item_being_placed];
          metadata[key] |= 1 << neighborhood_i;
          goto has_placed;
        }
      }
      //printf("searching for empty bucket away from neighborhood\n");
      for ( ; probe < num_buckets + h->neighborhood_size; probe++)
        if (h->buckets[probe] == 0)
          goto has_found_empty_bucket;
      goto failed_to_find_space;
    has_found_empty_bucket:
      //printf("found empty bucket in #%d\n", probe);
      do
      {
        for (int probe_back = 1; probe_back < h->neighborhood_size; probe_back++)
        {
          if (!metadata[probe - probe_back]) continue;
          for (int thing_to_relocate = 0; thing_to_relocate < probe_back; thing_to_relocate++)
          {
            if (metadata[probe - probe_back] & (1 << thing_to_relocate))
            {
              //printf("moving item %08X that was in bucket #%d (as item %d of key #%d) into bucket #%d (as item %d of key #%d)\n",
              //h->buckets[probe - probe_back + thing_to_relocate],
              //probe - probe_back + thing_to_relocate, thing_to_relocate, probe - probe_back,
              //probe, probe_back, probe - probe_back);
              h->buckets[probe] = h->buckets[probe - probe_back + thing_to_relocate];
              metadata[probe - probe_back] &= ~(1 << thing_to_relocate);
              metadata[probe - probe_back] |= (1 << probe_back);
              probe = probe - probe_back + thing_to_relocate;
              goto next_hop;
            }
          }
        }
        goto failed_to_find_space;
      next_hop:
        ;
      }
      while (probe - key >= h->neighborhood_size);
      neighborhood_i = probe - key;
      goto place_in_keys_neighborhood;
    has_placed:
      ;
    }
    free(metadata);
    destroy_stats(&stats);
    return;
  failed_to_find_space:
    free(metadata);
    free(h->buckets);
    needed_bits++;
  }
}