Hash CORE no longer depends on ITER and moved some other things to EXT
This commit is contained in:
1 parent
63eb525406
commit
90a6b4ef0d
4 files changed
+150
-129
No files matched your search
@@ -120,7 +120,6 @@
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _deque_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _deque_); \
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
@@ -234,21 +233,6 @@
|
||||
_deque_->alloc->free(_deque_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_) \
|
||||
{ \
|
||||
if (_deque_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \
|
||||
{ \
|
||||
_deque_.f_val->free(_deque_.buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_.capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_.alloc->free(_deque_.buffer); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
|
||||
+66
-67
@@ -154,7 +154,6 @@
|
||||
struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _map_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _map_); \
|
||||
void CMC_(PFX, _release)(struct SNAME _map_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _map_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
@@ -294,27 +293,6 @@
|
||||
_map_->alloc->free(_map_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _map_) \
|
||||
{ \
|
||||
if (_map_.f_key->free || _map_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_.capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_.f_key->free) \
|
||||
_map_.f_key->free(entry->key); \
|
||||
if (_map_.f_val->free) \
|
||||
_map_.f_val->free(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_map_.alloc->free(_map_.buffer); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _map_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
@@ -472,23 +450,29 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
|
||||
K max_key; \
|
||||
V max_val; \
|
||||
size_t first = 0; \
|
||||
\
|
||||
K max_key = CMC_(PFX, _iter_key)(&iter); \
|
||||
V max_val = CMC_(PFX, _iter_value)(&iter); \
|
||||
\
|
||||
CMC_(PFX, _iter_next)(&iter); \
|
||||
\
|
||||
/* TODO Turn this into a normal loop */ \
|
||||
for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
|
||||
for (; first < _map_->capacity; first++) \
|
||||
{ \
|
||||
K iter_key = CMC_(PFX, _iter_key)(&iter); \
|
||||
V iter_val = CMC_(PFX, _iter_value)(&iter); \
|
||||
\
|
||||
if (_map_->f_key->cmp(iter_key, max_key) > 0) \
|
||||
if (_map_->buffer[first].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
max_key = iter_key; \
|
||||
max_val = iter_val; \
|
||||
max_key = _map_->buffer[first].key; \
|
||||
max_val = _map_->buffer[first].value; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = first + 1; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \
|
||||
{ \
|
||||
max_key = _map_->buffer[first].key; \
|
||||
max_val = _map_->buffer[first].value; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -511,23 +495,29 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
|
||||
K min_key; \
|
||||
V min_val; \
|
||||
size_t first = 0; \
|
||||
\
|
||||
K min_key = CMC_(PFX, _iter_key)(&iter); \
|
||||
V min_val = CMC_(PFX, _iter_value)(&iter); \
|
||||
\
|
||||
CMC_(PFX, _iter_next)(&iter); \
|
||||
\
|
||||
/* TODO Turn this into a normal loop */ \
|
||||
for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
|
||||
for (; first < _map_->capacity; first++) \
|
||||
{ \
|
||||
K iter_key = CMC_(PFX, _iter_key)(&iter); \
|
||||
V iter_val = CMC_(PFX, _iter_value)(&iter); \
|
||||
\
|
||||
if (_map_->f_key->cmp(iter_key, min_key) < 0) \
|
||||
if (_map_->buffer[first].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
min_key = iter_key; \
|
||||
min_val = iter_val; \
|
||||
min_key = _map_->buffer[first].key; \
|
||||
min_val = _map_->buffer[first].value; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = first + 1; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \
|
||||
{ \
|
||||
min_key = _map_->buffer[first].key; \
|
||||
min_val = _map_->buffer[first].value; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -672,15 +662,16 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
|
||||
\
|
||||
/* TODO turn this into a normal loop */ \
|
||||
for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
K key = CMC_(PFX, _iter_key)(&iter); \
|
||||
V value = CMC_(PFX, _iter_value)(&iter); \
|
||||
if (_map_->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
K key = _map_->buffer[i].key; \
|
||||
V value = _map_->buffer[i].value; \
|
||||
\
|
||||
CMC_(PFX, _insert)(_new_map_, key, value); \
|
||||
/* TODO check this for possible errors */ \
|
||||
CMC_(PFX, _insert)(_new_map_, key, value); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* Unlikely */ \
|
||||
@@ -776,20 +767,28 @@
|
||||
if (_map1_->count != _map2_->count) \
|
||||
return false; \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \
|
||||
/* Optimize loop using the smallest hashtable */ \
|
||||
struct SNAME *_map_a_; \
|
||||
struct SNAME *_map_b_; \
|
||||
\
|
||||
/* TODO optimize this loop */ \
|
||||
for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
|
||||
_map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \
|
||||
_map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \
|
||||
\
|
||||
for (size_t i = 0; i < _map_a_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \
|
||||
_map2_, CMC_(PFX, _iter_key)(&iter)); \
|
||||
if (_map_a_->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \
|
||||
\
|
||||
if (entry == NULL) \
|
||||
return false; \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry_b = \
|
||||
CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \
|
||||
\
|
||||
if (_map1_->f_val->cmp(entry->value, \
|
||||
CMC_(PFX, _iter_value)(&iter)) != 0) \
|
||||
return false; \
|
||||
if (!entry_b) \
|
||||
return false; \
|
||||
\
|
||||
if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
|
||||
+61
-45
@@ -36,52 +36,68 @@
|
||||
CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks);
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_);
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
struct SNAME _deque_ = { 0 }; \
|
||||
\
|
||||
if (capacity < 1) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_.buffer) \
|
||||
return _deque_; \
|
||||
\
|
||||
_deque_.capacity = capacity; \
|
||||
_deque_.count = 0; \
|
||||
_deque_.front = 0; \
|
||||
_deque_.back = 0; \
|
||||
_deque_.flag = CMC_FLAG_OK; \
|
||||
_deque_.f_val = f_val; \
|
||||
_deque_.alloc = alloc; \
|
||||
_deque_.callbacks = callbacks; \
|
||||
\
|
||||
return _deque_; \
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
struct SNAME _deque_ = { 0 }; \
|
||||
\
|
||||
if (capacity < 1) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_.buffer) \
|
||||
return _deque_; \
|
||||
\
|
||||
_deque_.capacity = capacity; \
|
||||
_deque_.count = 0; \
|
||||
_deque_.front = 0; \
|
||||
_deque_.back = 0; \
|
||||
_deque_.flag = CMC_FLAG_OK; \
|
||||
_deque_.f_val = f_val; \
|
||||
_deque_.alloc = alloc; \
|
||||
_deque_.callbacks = callbacks; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_) \
|
||||
{ \
|
||||
if (_deque_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \
|
||||
{ \
|
||||
_deque_.f_val->free(_deque_.buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_.capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_.alloc->free(_deque_.buffer); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+23
-1
@@ -46,7 +46,8 @@
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks);
|
||||
struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _release)(struct SNAME _map_);
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
@@ -97,6 +98,27 @@
|
||||
_map_.callbacks = callbacks; \
|
||||
\
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _map_) \
|
||||
{ \
|
||||
if (_map_.f_key->free || _map_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_.capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_.f_key->free) \
|
||||
_map_.f_key->free(entry->key); \
|
||||
if (_map_.f_val->free) \
|
||||
_map_.f_val->free(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_map_.alloc->free(_map_.buffer); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user