From 50b794f17e8ea267277bcffa4c1859102a1803b4 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Thu, 22 Nov 2012 18:54:25 +0400 Subject: [PATCH] Update tarantool_checksum to use new mhash.h --- client/tarantool_checksum/mhash-val.h | 443 --------------------- client/tarantool_checksum/tc_file.c | 30 +- client/tarantool_checksum/tc_generate.c | 29 +- client/tarantool_checksum/tc_hash.h | 38 +- client/tarantool_checksum/tc_space.c | 35 +- client/tarantool_checksum/tc_space.h | 4 +- client/tarantool_checksum/tc_verify.c | 16 +- client/tarantool_checksum/tnt_checksum.cbp | 221 ++++++++++ 8 files changed, 310 insertions(+), 506 deletions(-) delete mode 100644 client/tarantool_checksum/mhash-val.h create mode 100644 client/tarantool_checksum/tnt_checksum.cbp diff --git a/client/tarantool_checksum/mhash-val.h b/client/tarantool_checksum/mhash-val.h deleted file mode 100644 index e17ae60002..0000000000 --- a/client/tarantool_checksum/mhash-val.h +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* The MIT License - - Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef MH_INCREMENTAL_RESIZE -#define MH_INCREMENTAL_RESIZE 1 -#endif - -#include <stdlib.h> -#include <stdint.h> -#include <math.h> -#include <string.h> - -#define mh_cat(a, b) mh##a##_##b -#define mh_ecat(a, b) mh_cat(a, b) -#define _mh(x) mh_ecat(mh_name, x) - -#define mh_unlikely(x) __builtin_expect((x),0) - -#ifndef MH_TYPEDEFS -#define MH_TYPEDEFS -typedef uint32_t mh_int_t; -#endif /* MH_TYPEDEFS */ - -#ifndef __ac_HASH_PRIME_SIZE -#define __ac_HASH_PRIME_SIZE 31 -static const mh_int_t __ac_prime_list[__ac_HASH_PRIME_SIZE] = { - 3ul, 11ul, 23ul, 53ul, - 97ul, 193ul, 389ul, 769ul, - 1543ul, 3079ul, 6151ul, 12289ul, - 24593ul, 49157ul, 98317ul, 196613ul, - 393241ul, 786433ul, 1572869ul, 3145739ul, - 6291469ul, 12582917ul, 25165843ul, 50331653ul, - 100663319ul, 201326611ul, 402653189ul, 805306457ul, - 1610612741ul, 3221225473ul, 4294967291ul -}; -#endif /* __ac_HASH_PRIME_SIZE */ - -#ifndef MH_HEADER -#define MH_HEADER - -struct _mh(pair) { - mh_val_t val; -}; - -struct _mh(t) { - struct _mh(pair) * p; - mh_int_t *b; - mh_int_t n_buckets; - mh_int_t n_dirty; - mh_int_t size; - mh_int_t upper_bound; - mh_int_t prime; - - mh_int_t resize_cnt; - mh_int_t resize_position; - mh_int_t batch; - struct _mh(t) *shadow; -}; - -#define mh_exist(h, i) ({ h->b[i >> 4] & (1 << (i % 16)); }) -#define mh_dirty(h, i) ({ h->b[i >> 4] & (1 << (i % 16 + 16)); }) - -#define mh_setfree(h, i) ({ h->b[i >> 4] &= ~(1 << (i % 16)); }) -#define mh_setexist(h, i) ({ h->b[i >> 4] |= (1 << (i % 16)); }) -#define mh_setdirty(h, i) ({ h->b[i >> 4] |= (1 << (i % 16 + 16)); }) - -#define mh_value(h, i) (h)->p[(i)].val -#define mh_size(h) ({ (h)->size; }) -#define mh_capacity(h) ({ (h)->n_buckets; }) -#define mh_begin(h) ({ 0; }) -#define mh_end(h) ({ (h)->n_buckets; }) - -#define MH_DENSITY 0.7 - -void _mh(init)(struct _mh(t) *h); -void _mh(clear)(struct _mh(t) *h); -void _mh(destroy)(struct _mh(t) *h); -void _mh(resize)(mh_arg_t arg, struct _mh(t) *h); -int _mh(start_resize)(mh_arg_t arg, struct _mh(t) *h, mh_int_t buckets, mh_int_t batch); -void _mh(reserve)(mh_arg_t arg, struct _mh(t) *h, mh_int_t size); -void __attribute__((noinline)) _mh(del_resize)(mh_arg_t arg, struct _mh(t) *h, mh_int_t x); -void _mh(dump)(struct _mh(t) *h); - -#define put_slot(arg, h, key) _mh(put_slot)(arg, h, key) - -static inline mh_int_t -_mh(next_slot)(mh_int_t slot, mh_int_t inc, mh_int_t size) -{ - slot += inc; - return slot >= size ? slot - size : slot; -} - -static inline mh_int_t -_mh(get)(mh_arg_t arg, struct _mh(t) *h, mh_val_t key) -{ - mh_int_t k = mh_hash(arg, key); - mh_int_t i = k % h->n_buckets; - mh_int_t inc = 1 + k % (h->n_buckets - 1); - for (;;) { - if ((mh_exist(h, i) && mh_eq(arg, key, h->p[i].val))) - return i; - - if (!mh_dirty(h, i)) - return h->n_buckets; - - i = _mh(next_slot)(i, inc, h->n_buckets); - } -} - -static inline mh_int_t -_mh(put_slot)(mh_arg_t arg, struct _mh(t) *h, mh_val_t key) -{ - mh_int_t k = mh_hash(arg, key); /* hash key */ - mh_int_t i = k % h->n_buckets; /* offset in the hash table. */ - mh_int_t inc = 1 + k % (h->n_buckets - 1); /* overflow chain increment. */ - - /* Skip through all collisions. */ - while (mh_exist(h, i)) { - if (mh_eq(arg, key, h->p[i].val)) - return i; /* Found a duplicate. */ - /* - * Mark this link as part of a collision chain. The - * chain always ends with a non-marked link. - * Note: the collision chain for this key may share - * links with collision chains of other keys. - */ - mh_setdirty(h, i); - i = _mh(next_slot)(i, inc, h->n_buckets); - } - /* - * Found an unused, but possibly dirty slot. Use it. - * However, if this is a dirty slot, first check that - * there are no duplicates down the collision chain. The - * current link can also be from a collision chain of some - * other key, but this is can't be established, so check - * anyway. - */ - mh_int_t save_i = i; - while (mh_dirty(h, i)) { - i = _mh(next_slot)(i, inc, h->n_buckets); - - if (mh_exist(h, i) && mh_eq(arg, key, h->p[i].val)) - return i; /* Found a duplicate. */ - } - /* Reached the end of the collision chain: no duplicates. */ - return save_i; -} - -static inline mh_int_t -_mh(put)(mh_arg_t arg, struct _mh(t) *h, mh_val_t val, int * ret) -{ - mh_int_t x = mh_end(h); - if (h->size == h->n_buckets) - /* no one free elements in the hash table */ - goto put_done; - -#if MH_INCREMENTAL_RESIZE - if (mh_unlikely(h->resize_position > 0)) - _mh(resize)(arg, h); - else if (mh_unlikely(h->n_dirty >= h->upper_bound)) { - if (_mh(start_resize)(arg, h, h->n_buckets + 1, 0)) - goto put_done; - } - if (h->resize_position) - _mh(put)(arg, h->shadow, val, NULL); -#else - if (mh_unlikely(h->n_dirty >= h->upper_bound)) { - if (_mh(start_resize)(arg, h, h->n_buckets + 1, h->size)) - goto put_done; - } -#endif - - x = put_slot(arg, h, val); - int exist = mh_exist(h, x); - if (ret) - *ret = !exist; - - if (!exist) { - /* add new */ - mh_setexist(h, x); - h->size++; - if (!mh_dirty(h, x)) - h->n_dirty++; - - h->p[x].val = val; - } else { - /* replace old */ - h->p[x].val = val; - } - -put_done: - return x; -} - -static inline void -_mh(del)(mh_arg_t arg, struct _mh(t) *h, mh_int_t x) -{ - if (x != h->n_buckets && mh_exist(h, x)) { - mh_setfree(h, x); - h->size--; - if (!mh_dirty(h, x)) - h->n_dirty--; -#if MH_INCREMENTAL_RESIZE - if (mh_unlikely(h->resize_position)) - _mh(del_resize)(arg, h, x); -#endif - } -} -#endif - - -#ifdef MH_SOURCE - -void __attribute__((noinline)) -_mh(del_resize)(mh_arg_t arg, struct _mh(t) *h, mh_int_t x) -{ - struct _mh(t) *s = h->shadow; - uint32_t y = _mh(get)(arg, s, h->p[x].val); - _mh(del)(arg, s, y); - _mh(resize)(arg, h); -} - -void -_mh(init)(struct _mh(t) *h) -{ - memset(h, 0, sizeof(struct _mh(t))); - h->shadow = calloc(1, sizeof(*h)); - h->prime = 0; - h->n_buckets = __ac_prime_list[h->prime]; - h->p = calloc(h->n_buckets, sizeof(struct _mh(pair))); - h->b = calloc(h->n_buckets / 16 + 1, sizeof(unsigned)); - h->upper_bound = h->n_buckets * MH_DENSITY; -} - -void -_mh(clear)(struct _mh(t) *h) -{ - free(h->p); - h->prime = 0; - h->n_buckets = __ac_prime_list[h->prime]; - h->p = calloc(h->n_buckets, sizeof(struct _mh(pair))); - h->upper_bound = h->n_buckets * MH_DENSITY; -} - -void -_mh(destroy)(struct _mh(t) *h) -{ - free(h->shadow); - free(h->b); - free(h->p); -} - -void -_mh(resize)(mh_arg_t arg, struct _mh(t) *h) -{ - struct _mh(t) *s = h->shadow; -#if MH_INCREMENTAL_RESIZE - mh_int_t batch = h->batch; -#endif - for (mh_int_t i = h->resize_position; i < h->n_buckets; i++) { -#if MH_INCREMENTAL_RESIZE - if (batch-- == 0) { - h->resize_position = i; - return; - } -#endif - if (!mh_exist(h, i)) - continue; - mh_int_t n = put_slot(arg, s, h->p[i].val); - s->p[n] = h->p[i]; - mh_setexist(s, n); - s->n_dirty++; - } - free(h->p); - free(h->b); - s->size = h->size; - memcpy(h, s, sizeof(*h)); - h->resize_cnt++; -} - -int -_mh(start_resize)(mh_arg_t arg, struct _mh(t) *h, mh_int_t buckets, mh_int_t batch) -{ - if (h->resize_position) { - /* resize has already been started */ - return 0; - } - if (buckets < h->n_buckets) { - /* hash size is already greater than requested */ - return 0; - } - while (h->prime < __ac_HASH_PRIME_SIZE) { - if (__ac_prime_list[h->prime] >= buckets) - break; - h->prime += 1; - } - - h->batch = batch > 0 ? batch : h->n_buckets / (256 * 1024); - if (h->batch < 256) { - /* - * Minimal batch must be greater or equal to - * 1 / (1 - f), where f is upper bound percent - * = MH_DENSITY - */ - h->batch = 256; - } - - struct _mh(t) *s = h->shadow; - memcpy(s, h, sizeof(*h)); - s->resize_position = 0; - s->n_buckets = __ac_prime_list[h->prime]; - s->upper_bound = s->n_buckets * MH_DENSITY; - s->n_dirty = 0; - s->p = malloc(s->n_buckets * sizeof(struct _mh(pair))); - if (s->p == NULL) - return -1; - s->b = calloc(s->n_buckets / 16 + 1, sizeof(unsigned)); - if (s->b == NULL) { - free(s->p); - s->p = NULL; - return -1; - } - _mh(resize)(arg, h); - - return 0; -} - -void -_mh(reserve)(mh_arg_t arg, struct _mh(t) *h, mh_int_t size) -{ - _mh(start_resize)(arg, h, size/MH_DENSITY, h->size); -} - -#ifndef mh_stat -#define mh_stat(buf, h) ({ \ - tbuf_printf(buf, " n_buckets: %"PRIu32 CRLF \ - " n_dirty: %"PRIu32 CRLF \ - " size: %"PRIu32 CRLF \ - " resize_cnt: %"PRIu32 CRLF \ - " resize_position: %"PRIu32 CRLF, \ - h->n_buckets, \ - h->n_dirty, \ - h->size, \ - h->resize_cnt, \ - h->resize_position); \ - }) -#endif - -#ifdef MH_DEBUG -void -_mh(dump)(struct _mh(t) *h) -{ - printf("slots:\n"); - int k = 0; - for(int i = 0; i < h->n_buckets; i++) { - if (mh_dirty(h, i) || mh_exist(h, i)) { - printf(" [%i] ", i); - if (mh_exist(h, i)) { - printf(" -> %i", (int)h->p[i].key); - k++; - } - if (mh_dirty(h, i)) - printf(" dirty"); - printf("\n"); - } - } - printf("end(%i)\n", k); -} -#endif - -#endif - -#if defined(MH_SOURCE) || defined(MH_UNDEF) -#undef MH_HEADER -#undef mh_key_t -#undef mh_val_t -#undef mh_name -#undef mh_hash -#undef mh_eq -#undef mh_dirty -#undef mh_place -#undef mh_setdirty -#undef mh_setexist -#undef mh_setvalue -#undef mh_unlikely -#undef slot -#undef slot_and_dirty -#undef MH_DENSITY -#endif - -#undef mh_cat -#undef mh_ecat -#undef _mh diff --git a/client/tarantool_checksum/tc_file.c b/client/tarantool_checksum/tc_file.c index 458b2bb24b..3e69249628 100644 --- a/client/tarantool_checksum/tc_file.c +++ b/client/tarantool_checksum/tc_file.c @@ -71,26 +71,26 @@ int tc_file_save_space(struct tc_space *s, FILE *f) { struct tc_file_header_space h = { .space = s->id, - .count_log = s->hash_log.size, - .count_snap = s->hash_snap.size, + .count_log = s->hash_log->size, + .count_snap = s->hash_snap->size, .data_offset = 0 }; fwrite(&h, sizeof(struct tc_file_header_space), 1, f); mh_int_t pos = 0; - while (pos != mh_end(&s->hash_log)) { - if (mh_exist((&s->hash_log), pos)) { - struct tc_key *k = mh_value(&s->hash_log, pos); + while (pos != mh_end(s->hash_log)) { + if (mh_exist((s->hash_log), pos)) { + const struct tc_key *k = *mh_pk_node(s->hash_log, pos); if (fwrite((char*)k, sizeof(struct tc_key) + k->size, 1, f) != 1) return -1; } pos++; } pos = 0; - while (pos != mh_end(&s->hash_snap)) { - if (mh_exist((&s->hash_snap), pos)) { - struct tc_key *k = mh_value(&s->hash_snap, pos); + while (pos != mh_end(s->hash_snap)) { + if (mh_exist((s->hash_snap), pos)) { + const struct tc_key *k = *mh_pk_node(s->hash_snap, pos); if (fwrite((char*)k, sizeof(struct tc_key) + k->size, 1, f) != 1) return -1; } @@ -124,7 +124,7 @@ int tc_file_save(struct tc_spaces *s, mh_int_t pos = 0; while (pos != mh_end(s->t)) { if (mh_exist((s->t), pos)) { - struct tc_space *space = mh_value(s->t, pos); + struct tc_space *space = mh_u32ptr_node(s->t, pos)->val; int rc = tc_file_save_space(space, f); if (rc == -1) { fclose(f); @@ -192,8 +192,10 @@ int tc_file_load(struct tc_spaces *s, char *file, fclose(f); return -1; } - mh_int_t pos = mh_pk_put(space, &space->hash_log, k, NULL); - if (pos == mh_end(&space->hash_log)) { + const struct tc_key *node = k; + mh_int_t pos = mh_pk_put(space->hash_log, &node, + space, space, NULL); + if (pos == mh_end(space->hash_log)) { fclose(f); return -1; } @@ -207,8 +209,10 @@ int tc_file_load(struct tc_spaces *s, char *file, fclose(f); return -1; } - mh_int_t pos = mh_pk_put(space, &space->hash_snap, k, NULL); - if (pos == mh_end(&space->hash_log)) { + const struct tc_key *node = k; + mh_int_t pos = mh_pk_put(space->hash_snap, &node, + space, space, NULL); + if (pos == mh_end(space->hash_log)) { fclose(f); return -1; } diff --git a/client/tarantool_checksum/tc_generate.c b/client/tarantool_checksum/tc_generate.c index 35a64c1c77..3ee329393b 100644 --- a/client/tarantool_checksum/tc_generate.c +++ b/client/tarantool_checksum/tc_generate.c @@ -55,9 +55,8 @@ #include "tc_file.h" uint32_t -search_hash(void *x, const struct tc_key *k) +search_hash(const struct tc_key *k, struct tc_space *s) { - struct tc_space *s = x; uint32_t h = 13; int i; for (i = 0; i < s->pk.count; i++) { @@ -87,12 +86,12 @@ search_hash(void *x, const struct tc_key *k) } int -search_equal(void *x, const struct tc_key *a, - const struct tc_key *b) +search_equal(const struct tc_key *a, + const struct tc_key *b, struct tc_space *s) { if (a->size != b->size) return 0; - struct tc_space *s = x; + int i; for (i = 0; i < s->pk.count; i++) { switch (s->pk.fields[i].type) { @@ -226,8 +225,9 @@ tc_generate_entry(struct tc_spaces *s, struct tnt_request *r) return -1; } /* 3. put into hash */ - mh_int_t pos = mh_pk_put(space, &space->hash_log, k, NULL); - if (pos == mh_end(&space->hash_log)) { + const struct tc_key *node = k; + mh_int_t pos = mh_pk_put(space->hash_log, &node, space, space, NULL); + if (pos == mh_end(space->hash_log)) { free(k); return -1; } @@ -372,14 +372,17 @@ tc_generate_snaprow(struct tc_spaces *s, struct tnt_iter_storage *is, /* foreach snapshot row which does not exist in index dump: * calculate crc and add to the index */ - mh_int_t pos = mh_pk_get(space, &space->hash_log, k); - struct tc_key *v = NULL; - if (pos != mh_end(&space->hash_log)) - v = mh_value(&space->hash_log, pos); + const struct tc_key *node = k; + mh_int_t pos = mh_pk_get(space->hash_log, &node, space, space); + const struct tc_key *v = NULL; + if (pos != mh_end(space->hash_log)) + v = *mh_pk_node(space->hash_log, pos); if (v == NULL) { k->crc = crc32c(0, (unsigned char*)is->t.data, is->t.size); - mh_int_t pos = mh_pk_put(space, &space->hash_snap, k, NULL); - if (pos == mh_end(&space->hash_snap)) { + const struct tc_key *node = k; + mh_int_t pos = mh_pk_put(space->hash_snap, &node, + space, space, NULL); + if (pos == mh_end(space->hash_snap)) { free(k); return -1; } diff --git a/client/tarantool_checksum/tc_hash.h b/client/tarantool_checksum/tc_hash.h index 2da7d339ae..3f8694a56d 100644 --- a/client/tarantool_checksum/tc_hash.h +++ b/client/tarantool_checksum/tc_hash.h @@ -5,25 +5,37 @@ #define MH_UNDEF #endif -typedef void* ptr_t; +#include <stdint.h> #define mh_name _u32ptr -#define mh_key_t uint32_t -#define mh_val_t ptr_t -#define mh_hash(a) (a) -#define mh_eq(a, b) ((a) == (b)) +struct mh_u32ptr_node_t { + uint32_t key; + void *val; +}; + +#define mh_node_t struct mh_u32ptr_node_t +#define mh_hash_arg_t void * +#define mh_hash(a, arg) (a->key) +#define mh_eq_arg_t void * +#define mh_eq(a, b, arg) ((a->key) == (b->key)) #include <mhash.h> -uint32_t search_hash(void *x, const struct tc_key *k); -int search_equal(void *x, const struct tc_key *a, const struct tc_key *b); -#undef put_slot +struct tc_space; + +uint32_t +search_hash(const struct tc_key *k, struct tc_space *s); + +int +search_equal(const struct tc_key *a, const struct tc_key *b, + struct tc_space *s); #define mh_name _pk -#define mh_arg_t void* -#define mh_val_t struct tc_key* -#define mh_hash(x, k) search_hash((x), (k)) -#define mh_eq(x, ka, kb) search_equal((x), (ka), (kb)) -#include "mhash-val.h" +#define mh_node_t struct tc_key * +#define mh_hash_arg_t struct tc_space * +#define mh_hash(a, arg) search_hash(*(a), arg) +#define mh_eq_arg_t struct tc_space * +#define mh_eq(a, b, arg) search_equal(*(a), *(b), arg) +#include <mhash.h> #endif diff --git a/client/tarantool_checksum/tc_space.c b/client/tarantool_checksum/tc_space.c index fdd0301090..cf015c29d8 100644 --- a/client/tarantool_checksum/tc_space.c +++ b/client/tarantool_checksum/tc_space.c @@ -53,28 +53,30 @@ void tc_space_free(struct tc_spaces *s) { mh_int_t i; mh_foreach(s->t, i) { - struct tc_space *space = mh_value(s->t, i); - mh_u32ptr_del(s->t, i); + struct tc_space *space = mh_u32ptr_node(s->t, i)->val; + mh_u32ptr_del(s->t, i, NULL, NULL); mh_int_t pos = 0; - while (pos != mh_end(&space->hash_log)) { - if (mh_exist((&space->hash_log), pos)) { - struct tc_key *k = mh_value(&space->hash_log, pos); + while (pos != mh_end(space->hash_log)) { + if (mh_exist((space->hash_log), pos)) { + struct tc_key *k = (struct tc_key *) + *mh_pk_node(space->hash_log, pos); free(k); } pos++; } pos = 0; - while (pos != mh_end(&space->hash_snap)) { - if (mh_exist((&space->hash_snap), pos)) { - struct tc_key *k = mh_value(&space->hash_snap, pos); + while (pos != mh_end(space->hash_snap)) { + if (mh_exist((space->hash_snap), pos)) { + struct tc_key *k = (struct tc_key *) + *mh_pk_node(space->hash_snap, pos); free(k); } pos++; } - mh_pk_destroy(&space->hash_log); - mh_pk_destroy(&space->hash_snap); + mh_pk_destroy(space->hash_log); + mh_pk_destroy(space->hash_snap); free(space->pk.fields); free(space); @@ -88,18 +90,21 @@ struct tc_space *tc_space_create(struct tc_spaces *s, uint32_t id) { return NULL; memset(space, 0, sizeof(struct tc_space)); space->id = id; - mh_pk_init(&space->hash_log); - mh_pk_init(&space->hash_snap); + space->hash_log = mh_pk_init(); + space->hash_snap = mh_pk_init(); int ret; - mh_u32ptr_put(s->t, space->id, space, &ret); + + const struct mh_u32ptr_node_t node = { .key = space->id, .val = space }; + mh_u32ptr_put(s->t, &node, space, space, &ret); return space; } struct tc_space *tc_space_match(struct tc_spaces *s, uint32_t id) { - mh_int_t k = mh_u32ptr_get(s->t, id); + const struct mh_u32ptr_node_t node = { .key = id }; + mh_int_t k = mh_u32ptr_get(s->t, &node, NULL, NULL); struct tc_space *space = NULL; if (k != mh_end(s->t)) - space = mh_value(s->t, k); + space = mh_u32ptr_node(s->t, k)->val; return space; } diff --git a/client/tarantool_checksum/tc_space.h b/client/tarantool_checksum/tc_space.h index 4febba66ee..7c08701e04 100644 --- a/client/tarantool_checksum/tc_space.h +++ b/client/tarantool_checksum/tc_space.h @@ -20,8 +20,8 @@ struct tc_space_key { struct tc_space { uint32_t id; - struct mh_pk_t hash_log; - struct mh_pk_t hash_snap; + struct mh_pk_t *hash_log; + struct mh_pk_t *hash_snap; struct tc_space_key pk; }; diff --git a/client/tarantool_checksum/tc_verify.c b/client/tarantool_checksum/tc_verify.c index 2ed840c67e..18321a55a6 100644 --- a/client/tarantool_checksum/tc_verify.c +++ b/client/tarantool_checksum/tc_verify.c @@ -74,20 +74,22 @@ int tc_verify_cmp(struct tc_spaces *s, } /* 1. check in hash, if found then skip */ - mh_int_t pos = mh_pk_get(space, &space->hash_log, k); - struct tc_key *v = NULL; - if (pos != mh_end(&space->hash_log)) - v = mh_value(&space->hash_log, pos); + const struct tc_key *node = k; + mh_int_t pos = mh_pk_get(space->hash_log, &node, space, space); + const struct tc_key *v = NULL; + if (pos != mh_end(space->hash_log)) + v = *mh_pk_node(space->hash_log, pos); if (v) { rc = 0; goto done; } /* 2. if key was not found in xlog hash, then try snapshot hash */ - pos = mh_pk_get(space, &space->hash_snap, k); + node = k; + pos = mh_pk_get(space->hash_snap, &node, space, space); v = NULL; - if (pos != mh_end(&space->hash_snap)) - v = mh_value(&space->hash_snap, pos); + if (pos != mh_end(space->hash_snap)) + v = *mh_pk_node(space->hash_snap, pos); if (v) { /* generate and compare checksum */ uint32_t crc = crc32c(0, (unsigned char*)is->t.data, is->t.size); diff --git a/client/tarantool_checksum/tnt_checksum.cbp b/client/tarantool_checksum/tnt_checksum.cbp new file mode 100644 index 0000000000..bee452f1b7 --- /dev/null +++ b/client/tarantool_checksum/tnt_checksum.cbp @@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_project_file> + <FileVersion major="1" minor="6" /> + <Project> + <Option title="tnt_checksum" /> + <Option makefile_is_custom="1" /> + <Option compiler="gcc" /> + <Option virtualFolders="CMake Files\;CMake Files\cmake\;CMake Files\include\;CMake Files\doc\;CMake Files\doc\www-data.in\;CMake Files\doc\man\;CMake Files\third_party\;CMake Files\third_party\coro\;CMake Files\third_party\gopt\;CMake Files\cfg\;CMake Files\connector\;CMake Files\connector\c\;CMake Files\connector\c\tnt\;CMake Files\connector\c\tntsql\;CMake Files\connector\c\tntnet\;CMake Files\connector\c\tntrpl\;CMake Files\connector\c\include\;CMake Files\src\;CMake Files\src\box\;CMake Files\extra\;CMake Files\client\;CMake Files\client\tarantool_checksum\;CMake Files\test\;CMake Files\test\unit\;CMake Files\test\box\;CMake Files\test\connector_c\;" /> + <Build> + <Target title="all"> + <Option working_dir="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum" /> + <Option type="4" /> + <MakeCommands> + <Build command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 all" /> + <CompileFile command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 "$file"" /> + <Clean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + <DistClean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + </MakeCommands> + </Target> + <Target title="tarantool_checksum"> + <Option output="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tarantool_checksum" prefix_auto="0" extension_auto="0" /> + <Option working_dir="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum" /> + <Option object_output="./" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add directory="/data/work/tarantool-hashtable-refactoring" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/connector/c/include" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/include" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/third_party/libobjc" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/third_party/luajit/src" /> + <Add directory="/usr/include" /> + <Add directory="/usr/include/c++/4.7" /> + <Add directory="/usr/include/c++/4.7/backward" /> + <Add directory="/usr/include/c++/4.7/x86_64-linux-gnu" /> + <Add directory="/usr/include/x86_64-linux-gnu" /> + <Add directory="/usr/lib/gcc/x86_64-linux-gnu/4.7/include" /> + <Add directory="/usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed" /> + <Add directory="/usr/local/include" /> + </Compiler> + <MakeCommands> + <Build command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 tarantool_checksum" /> + <CompileFile command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 "$file"" /> + <Clean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + <DistClean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + </MakeCommands> + </Target> + <Target title="tarantool_checksum/fast"> + <Option output="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tarantool_checksum" prefix_auto="0" extension_auto="0" /> + <Option working_dir="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum" /> + <Option object_output="./" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add directory="/data/work/tarantool-hashtable-refactoring" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/connector/c/include" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/include" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/third_party/libobjc" /> + <Add directory="/data/work/tarantool-hashtable-refactoring/third_party/luajit/src" /> + <Add directory="/usr/include" /> + <Add directory="/usr/include/c++/4.7" /> + <Add directory="/usr/include/c++/4.7/backward" /> + <Add directory="/usr/include/c++/4.7/x86_64-linux-gnu" /> + <Add directory="/usr/include/x86_64-linux-gnu" /> + <Add directory="/usr/lib/gcc/x86_64-linux-gnu/4.7/include" /> + <Add directory="/usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed" /> + <Add directory="/usr/local/include" /> + </Compiler> + <MakeCommands> + <Build command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 tarantool_checksum/fast" /> + <CompileFile command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 "$file"" /> + <Clean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + <DistClean command="/usr/bin/make -f "/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/Makefile" VERBOSE=1 clean" /> + </MakeCommands> + </Target> + </Build> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_config.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_file.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_generate.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_main.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_options.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_space.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_verify.c"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_config.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_file.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_generate.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_options.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_space.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/tc_verify.h"> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/CMakeLists.txt"> + <Option virtualFolder="CMake Files\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/arch.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/os.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/compiler.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/check_objective_c_compiler.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/libobjc.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/luajit.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cmake/cpack.cmake"> + <Option virtualFolder="CMake Files\cmake\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/include/config.h.cmake"> + <Option virtualFolder="CMake Files\include\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/doc/tnt.ent.cmake"> + <Option virtualFolder="CMake Files\doc\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/doc/CMakeLists.txt"> + <Option virtualFolder="CMake Files\doc\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/doc/www-data.in/download.cmake"> + <Option virtualFolder="CMake Files\doc\www-data.in\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/doc/www-data.in/CMakeLists.txt"> + <Option virtualFolder="CMake Files\doc\www-data.in\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/doc/man/CMakeLists.txt"> + <Option virtualFolder="CMake Files\doc\man\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/third_party/CMakeLists.txt"> + <Option virtualFolder="CMake Files\third_party\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/third_party/coro/CMakeLists.txt"> + <Option virtualFolder="CMake Files\third_party\coro\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/third_party/gopt/CMakeLists.txt"> + <Option virtualFolder="CMake Files\third_party\gopt\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/cfg/CMakeLists.txt"> + <Option virtualFolder="CMake Files\cfg\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tnt/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tnt\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tnt/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tnt\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntsql/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntsql\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntsql/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntsql\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntnet/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntnet\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntnet/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntnet\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntrpl/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntrpl\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/tntrpl/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\tntrpl\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/connector/c/include/CMakeLists.txt"> + <Option virtualFolder="CMake Files\connector\c\include\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/src/CMakeLists.txt"> + <Option virtualFolder="CMake Files\src\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/src/box/CMakeLists.txt"> + <Option virtualFolder="CMake Files\src\box\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/extra/CMakeLists.txt"> + <Option virtualFolder="CMake Files\extra\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/CMakeLists.txt"> + <Option virtualFolder="CMake Files\client\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/CMakeLists.txt"> + <Option virtualFolder="CMake Files\client\tarantool_checksum\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/client/tarantool_checksum/CMakeLists.txt"> + <Option virtualFolder="CMake Files\client\tarantool_checksum\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/test/CMakeLists.txt"> + <Option virtualFolder="CMake Files\test\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/test/unit/CMakeLists.txt"> + <Option virtualFolder="CMake Files\test\unit\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/test/box/CMakeLists.txt"> + <Option virtualFolder="CMake Files\test\box\" /> + </Unit> + <Unit filename="/data/work/tarantool-hashtable-refactoring/test/connector_c/CMakeLists.txt"> + <Option virtualFolder="CMake Files\test\connector_c\" /> + </Unit> + </Project> +</CodeBlocks_project_file> -- GitLab