int32_t drn_val_hash_cmp(const void * valA, const void * valB)
{
    drn_writer_key_t * v1 = (drn_writer_key_t * ) valA;
    drn_writer_key_t * v2 = (drn_writer_key_t * ) valB;
    uint32_t h1 = drn_oat_hash(v1->value, (uint32_t) strlen(v1->value))%DRN_HASH_MAP_SIZE;
    uint32_t h2 = drn_oat_hash(v2->value, (uint32_t) strlen(v2->value))%DRN_HASH_MAP_SIZE;
    if (h1 > h2) return 1;
    if (h1 < h2) return -1;
    return 0;
}
Beispiel #2
0
uint64_t drn_count_matching_chunks(drn_t * cache,
                                   drn_map_id_t map_id, const char * key_value)
{
    const drn_map_t * h = cache->maps + map_id;
    const drn_hash_cell_t * hash_map = h->hash;
    const drn_hash_desc_t * hash_descriptors = h->descriptors;
    const char * hash_values = h->value_strings;
    uint32_t cell_idx = drn_oat_hash((void * )key_value, (uint32_t) strlen(key_value))%DRN_HASH_MAP_SIZE;
    uint64_t count = 0;
    uint64_t d_idx;
    for (d_idx = 0; d_idx < hash_map[cell_idx].count; ++d_idx)
    {
        if (!strcmp(hash_values + hash_descriptors[hash_map[cell_idx].offset + d_idx].key_value_offset, key_value))
            ++count;
    }
    return count;
}
int32_t drn_close_writer(drn_writer_t *cache)
{
    drn_header_container_t header;
    drn_map_container_t * maps = (drn_map_container_t *) ALLOCATE(sbcount(cache->maps) * sizeof(drn_map_container_t));
    uint64_t m_idx;
    uint64_t i;
    size_t bytes;

    for (m_idx=0; m_idx < sbcount(cache->maps); ++m_idx)
    {
        drn_writer_map_t * map = cache->maps + m_idx;
        drn_hash_cell_t * hash_map = (drn_hash_cell_t *) ALLOCATE(DRN_HASH_MAP_SIZE * sizeof (drn_hash_cell_t));
        uint64_t hc_idx;
        uint64_t chunk_count = 0;
        uint64_t values_size = 0;
        drn_writer_key_t * key_array = map->keys;
        uint64_t k_idx;
        drn_hash_desc_t * descriptors;
        char * values_string_array;
        uint32_t desc_offset_cntr;
        uint32_t value_strings_offset_cntr;

        for (hc_idx = 0; hc_idx < DRN_HASH_MAP_SIZE; ++hc_idx)
        {
            hash_map[hc_idx].offset = 0;
            hash_map[hc_idx].count = 0;
        }
        /* count Es + sum VV lengths */
        for (k_idx = 0; k_idx < sbcount(map->keys); ++k_idx)
        {
            drn_writer_key_t * value = map->keys + k_idx;
            chunk_count += sbcount(value->descriptors);
            values_size += strlen(value->value)+1;
        }
        /* Allocate Es */
        descriptors = (drn_hash_desc_t*) ALLOCATE((size_t) chunk_count * sizeof(drn_hash_desc_t));
        /* Allocate Vv */
        values_string_array = (char *) ALLOCATE((size_t) values_size * sizeof(char));
        /* Sort Vs */
        qsort(key_array, sbcount(map->keys), sizeof(drn_writer_key_t), drn_val_hash_cmp);
        /* For each V */
        desc_offset_cntr = 0;
        value_strings_offset_cntr = 0;
        for (k_idx = 0; k_idx < sbcount(map->keys); ++k_idx)
        {
            uint32_t hash = drn_oat_hash(key_array[k_idx].value, (uint32_t) strlen(key_array[k_idx].value))%DRN_HASH_MAP_SIZE;
            uint64_t * chunk_ids = key_array[k_idx].descriptors;
            uint64_t d_idx;

            /* Fill H */
            hash_map[hash].offset = desc_offset_cntr;
            hash_map[hash].count = sbcount(key_array[k_idx].descriptors);
            /* Fill Vv */
            memcpy(values_string_array + value_strings_offset_cntr, key_array[k_idx].value, strlen(key_array[k_idx].value)+1);
            /*  fill E */
            qsort(chunk_ids, sbcount(key_array[k_idx].descriptors), sizeof(uint64_t), drn_uint64_cmp);
            for (d_idx = 0; d_idx < sbcount(key_array[k_idx].descriptors); ++d_idx)
            {
                descriptors[desc_offset_cntr].chunk_id = chunk_ids[d_idx];
                descriptors[desc_offset_cntr].key_value_offset = value_strings_offset_cntr;
                ++desc_offset_cntr;
            }
            /* Increment offsets */
            value_strings_offset_cntr += (uint32_t) strlen(key_array[k_idx].value)+1;
        }
        /*  Write hash array as desc */
        drn_writer_add_chunk(cache, hash_map, sizeof(drn_hash_cell_t) * DRN_HASH_MAP_SIZE);
        maps[m_idx].hash_chunk_id = drn_writer_get_last_chunk_id(cache);
        /*  Write hash name as desc */
        drn_writer_add_chunk(cache, map->name, strlen(map->name) + 1);
        maps[m_idx].name_chunk_id = drn_writer_get_last_chunk_id(cache);
        /*  Write value string array as desc */
        drn_writer_add_chunk(cache, descriptors, sizeof(drn_hash_desc_t) * chunk_count);
        maps[m_idx].descriptors_chunk_id = drn_writer_get_last_chunk_id(cache);
        /*  Write desc array as desc */
        drn_writer_add_chunk(cache, values_string_array, values_size);
        maps[m_idx].value_strings_chunk_id = drn_writer_get_last_chunk_id(cache);
        FREE(hash_map);
        FREE(descriptors);
        FREE(values_string_array);
    }
    drn_writer_add_chunk(cache, maps, sizeof(drn_map_container_t) * sbcount(cache->maps));
    FREE(maps);
    header.version = cache->version;
    memcpy(header.description, cache->description, 256);
    header.index_offset = cache->desc_start_offset + cache->desc_end_offset;
    header.chunk_count = cache->chunk_count;
    header.maps_chunk_id = drn_writer_get_last_chunk_id(cache);
    LSEEK(cache->fd, 0L, SEEK_SET);
    bytes = WRITE(cache->fd, &header, sizeof(drn_header_container_t));
    if (bytes !=  sizeof(drn_header_container_t))
        return -1;
    LSEEK(cache->fd, cache->desc_start_offset + cache->desc_end_offset, SEEK_SET);
    bytes = WRITE(cache->fd, cache->descriptors, WRITE_COUNT_CAST (sizeof(drn_desc_t) * cache->chunk_count));
    if (bytes !=  sizeof(drn_desc_t) * cache->chunk_count)
        return -1;
    if (CLOSE(cache->fd) == -1)
        return -1;
    for (i = 0; i < sbcount(cache->maps); ++i)
    {
        drn_writer_map_t * map = cache->maps + i;
        uint64_t j;
        for (j = 0; j < sbcount(map->keys); ++j)
        {
            drn_writer_key_t * value = map->keys + j;
            sbfree(value->descriptors);
            FREE(value->value);
        }
        sbfree(map->keys);
        FREE(map->name);
    }
    sbfree(cache->maps);
    sbfree(cache->descriptors);
    return 0;
}