示例#1
0
文件: fast_set.c 项目: Meijuh/ltsmin
static int
fset_locate (fset_t *dbs, mem_hash_t *mem, void *key, size_t *ref, size_t *tomb)
{
    size_t              k = dbs->key_length;
    for (int i = 1; *mem == EMPTY || *mem == TOMB; i++) {
        *mem = MurmurHash32(key, k, i);
    }
    size_t              h = home_loc (*mem);
    *tomb = NONE;
    dbs->lookups++;
    //Debug ("Locating key %zu,%zu with hash %u", ((size_t*)data)[0], ((size_t*)data)[1], mem);
    for (size_t rh = 0; rh <= 1000; rh++) {
        *ref = h & dbs->mask;
        size_t              line_begin = *ref & CACHE_LINE_MEM_MASK;
        size_t              line_end = line_begin + CACHE_LINE_MEM_SIZE;
        for (size_t i = 0; i < CACHE_LINE_MEM_SIZE; i++) {
            dbs->probes++;
            if (*memoized(dbs,*ref) == TOMB) {
                if (*tomb == NONE)
                    *tomb = *ref; // first found tombstone
            } else if (*memoized(dbs,*ref) == EMPTY) {
                return 0;
            } else if ( *mem == *memoized(dbs,*ref) &&
                        memcmp (key, bucket(dbs,dbs->data,*ref), k) == 0 ) {
                return 1;
            }
            *ref = (*ref+1 == line_end ? line_begin : *ref+1); // next in line
        }
        h = rehash (h, *mem);
    }
    return FSET_FULL;
}
示例#2
0
文件: fast_set.c 项目: Meijuh/ltsmin
/**
 * If we delete a bucket before an empty bucket on the probe line, we
 * may delete the entire chain of tomb stones leading to the bucket.
 * This will not break any probe sequence as the line already contained at least
 * one empty bucket (no rehashes could have occurred from this probe line).
 */
void
wipe_chain (fset_t *dbs, size_t ref)
{
    size_t              line_begin = ref & CACHE_LINE_MEM_MASK;
    size_t              line_end = line_begin + CACHE_LINE_MEM_SIZE;
    size_t              next = (ref+1 == line_end ? line_begin : ref+1);

    if (*memoized (dbs, next) != EMPTY) {
        *memoized (dbs, ref) = TOMB; // wipe in chain
        dbs->tombs++;
        dbs->load--;
        return;
    }

    // chain end:
    do {
        *memoized (dbs, ref) = EMPTY; // wipe chain end
        ref = (ref == line_begin ? line_end-1 : ref-1);
        dbs->tombs--;
    } while (*memoized (dbs, ref) == TOMB);
    dbs->tombs++; // first wipe was ref itself (not a tomb stone)
    dbs->load--;
}
示例#3
0
int main(int argc, char* argv[]) {
    std::ifstream in {argv[1]};
    std::string line;
    std::getline(in, line);
    std::istringstream ss(line);

    std::size_t N, K, B;
    ss >> N >> K >> B;

    std::getline(in, line);
    ss.str(line);
    ss.clear();
    std::vector<std::size_t> steps;
    std::copy_n(std::istream_iterator<std::size_t>(ss), K, std::back_inserter(steps));

    std::getline(in, line);
    ss.str(line);
    ss.clear();
    std::vector<std::size_t> invalid_stairs;
    std::copy_n(std::istream_iterator<std::size_t>(ss), B, std::back_inserter(invalid_stairs));

    std::vector<bool> is_invalid_stair(N+1,false);
    for (auto& stair : invalid_stairs)
    {
        is_invalid_stair[stair] = true;
    }

    std::vector<std::vector<std::size_t>> valid_steps(N+1, steps);
    for (std::size_t i = 0; i != N+1; ++i)
    {
        valid_steps[i].erase(
                std::remove_if(valid_steps[i].begin(), valid_steps[i].end(), 
                    [i,&is_invalid_stair](std::size_t s) { return (s >= i || is_invalid_stair[i-s]); }),
                valid_steps[i].end());
    }

    std::vector<std::pair<bool,std::size_t>> memoized(N+1, std::make_pair(false, 0));

    for (std::size_t i = 1; i != N+1; ++i)
    {
        hopper(memoized,valid_steps,1000000009,i);
    }

    std::cout << hopper(memoized, valid_steps, 1000000009, N) << std::endl;

    return 0;
}
示例#4
0
文件: fast_set.c 项目: Meijuh/ltsmin
int
fset_find (fset_t *dbs, mem_hash_t *m, void *key, void **data,
           bool insert_absent)
{
    HREassert (dbs->data_length == 0 || data);
    size_t              ref;
    size_t              tomb = NONE;
    size_t              k = dbs->key_length;
    mem_hash_t          mem = m == NULL ? EMPTY : *m;
    int                 found = fset_locate (dbs, &mem, key, &ref, &tomb);

    if (insert_absent && !found) {
        // insert:
        if (tomb != NONE) {
            ref = tomb;
            dbs->tombs--;
        }
        if (dbs->key_length)
            memcpy (bucket(dbs, dbs->data, ref), key, k);
        *memoized(dbs, ref) = mem;
        dbs->load++;
        dbs->max_load = max (dbs->max_load, dbs->load);
        if (dbs->tombs << 1 > dbs->size) {
            bool res = resize (dbs, REHASH);                // >50% tombs ==> rehash
            HREassert (res, "Cannot rehash table?");
            fset_locate (dbs, &mem, key, &ref, &tomb); // update ref
        } else if (((dbs->load + dbs->tombs) << 2) > dbs->size3) {
            if (!resize(dbs, GROW)) {                       // > 75% full ==> grow
                Debug ("Hash table almost full (size = %zu, load = %zu, tombs = %zu)",
                       dbs->size, dbs->load, dbs->tombs);
            }
            fset_locate (dbs, &mem, key, &ref, &tomb); // update ref
        }
    }

    if (data)
        *data = bucket(dbs, dbs->data, ref) + k;
    return found;
}
示例#5
0
文件: fast_set.c 项目: Meijuh/ltsmin
static int
resize (fset_t *dbs, fset_resize_t mode)
{
    void               *key, *data;
    bool                res;
    if (dbs->resizing) return true;
    dbs->resizing = 1;

    size_t              old_size = dbs->size;
    switch (mode) {
    case GROW:
        if (dbs->size == dbs->size_max) {
            dbs->resizing = 0;
            return false;
        }
        memset (dbs->hash + dbs->size, 0, sizeof (mem_hash_t[dbs->size]));
        dbs->size <<= 1;
        dbs->size3 <<= 1;
        break;
    case SHRINK:
        if (dbs->size == dbs->init_size) {
            dbs->resizing = 0;
            return true;
        }
        dbs->size >>= 1;
        dbs->size3 >>= 1;
        break;
    case REHASH: break;
    }
    dbs->mask = dbs->size - 1;
    Debug ("%s %zu to %zu", fset_resize_names[mode], old_size, dbs->size);

    //RTstartTimer (dbs->timer);
    size_t              tombs = 0;
    size_t              todos = 0;
    for (size_t i = 0; i < old_size; i++) {
        mem_hash_t          h = *memoized(dbs,i);
        if (TOMB == h) {
            tombs++;
            *memoized(dbs, i) = EMPTY;
        } else if (h != EMPTY) {// && home_loc(h) & dbs->mask != i) {
            dbs->todo[todos] = *memoized(dbs,i);
            void               *tdata = bucket(dbs, dbs->todo_data, todos);
            void               *data  = bucket(dbs, dbs->data, i);
            memcpy (tdata, data, dbs->total_length);
            todos++;
            *memoized(dbs, i) = EMPTY;
        }
    }
    dbs->tombs -= tombs;
    dbs->load  -= todos;
    HREassert (dbs->tombs == 0);

    for (size_t i = 0; i < todos; i++) {
        mem_hash_t          h = dbs->todo[i];
        key = bucket(dbs, dbs->todo_data, i);
        res = fset_find (dbs, &h, key, &data, true); // load++
        HREassert (!res);
        memcpy (data, key + dbs->key_length, dbs->data_length);
    }

    //RTstopTimer (dbs->timer);
    Debug ("%s %zu to %zu took %zu/%zu todos and cleaned %zu/%zu tombstones in %.2f sec",
           fset_resize_names[mode], old_size, dbs->size, todos, dbs->load, tombs,
           dbs->load + tombs, RTrealTime(dbs->timer));
    dbs->max_todos = max (todos, dbs->max_todos);
    dbs->max_grow = max (dbs->max_grow, dbs->size);
    dbs->resizes++;
    dbs->resizing = 0;
    return true;
}