diff options
| author | Tyge Løvset <[email protected]> | 2023-01-03 17:22:47 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-01-03 17:22:47 +0100 |
| commit | bb754d1e0e728c6b0f41efff16e512af04a0b3b8 (patch) | |
| tree | e5ef7293059aee287d3513593fb93c9fadda9a16 | |
| parent | 611b45c379af5d690b3a01d1847950411ebce2bd (diff) | |
| download | STC-modified-bb754d1e0e728c6b0f41efff16e512af04a0b3b8.tar.gz STC-modified-bb754d1e0e728c6b0f41efff16e512af04a0b3b8.zip | |
- Removed nomem_error member in csmap and cmap_X_result; test for res.ref == NULL instead!
- Corrected handling of malloc/realloc failure in both csmap/cmap.
| -rw-r--r-- | include/stc/cmap.h | 23 | ||||
| -rw-r--r-- | include/stc/csmap.h | 64 | ||||
| -rw-r--r-- | include/stc/forward.h | 4 |
3 files changed, 48 insertions, 43 deletions
diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 1d0583f4..86f551aa 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -312,11 +312,12 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { STC_DEF _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) { _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto((&_key))); + _cx_mapped* _mp = _res.ref ? &_res.ref->second : &_mapped; if (_res.inserted) _res.ref->first = _key; - else - { i_keydrop((&_key)); i_valdrop((&_res.ref->second)); } - _res.ref->second = _mapped; + else + { i_keydrop((&_key)); i_valdrop(_mp); } + *_mp = _mapped; return _res; } @@ -326,8 +327,10 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { _cx_result _res = _cx_memb(_insert_entry_)(self, rkey); if (_res.inserted) _res.ref->first = i_keyfrom(rkey); - else - { i_valdrop((&_res.ref->second)); } + else { + if (!_res.ref) return _res; + i_valdrop((&_res.ref->second)); + } _res.ref->second = i_valfrom(rmapped); return _res; } @@ -354,12 +357,14 @@ _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) { STC_DEF _cx_result _cx_memb(_insert_entry_)(_cx_self* self, _cx_rawkey rkey) { - bool nomem = false; + _cx_result res = {NULL}; if (self->size + 2 > (i_size)((float)self->bucket_count * (i_max_load_factor))) - nomem = !_cx_memb(_reserve)(self, self->size*3/2); + if (!_cx_memb(_reserve)(self, self->size*3/2)) + return res; + chash_bucket_t b = _cx_memb(_bucket_)(self, &rkey); - _cx_result res = {&self->table[b.idx], !self->_hashx[b.idx], nomem}; - if (res.inserted) { + res.ref = &self->table[b.idx]; + if ((res.inserted = !self->_hashx[b.idx])) { self->_hashx[b.idx] = b.hx; ++self->size; } diff --git a/include/stc/csmap.h b/include/stc/csmap.h index e3b82fea..efaca91a 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -276,13 +276,13 @@ _cx_memb(_new_node_)(_cx_self* self, int level) { static _cx_result _cx_memb(_insert_entry_)(_cx_self* self, _cx_rawkey rkey); STC_DEF _cx_result -_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (res.inserted) - { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} +_cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) { + _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto((&_key))); + if (_res.inserted) + { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )} else - { i_keydrop((&key)); _i_MAP_ONLY( i_valdrop((&mapped)); )} - return res; + { i_keydrop((&_key)); _i_MAP_ONLY( i_valdrop((&_mapped)); )} + return _res; } STC_DEF _cx_result @@ -297,30 +297,29 @@ _cx_memb(_push)(_cx_self* self, _cx_value _val) { #ifndef _i_isset STC_DEF _cx_result - _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (!res.nomem_error) { - if (res.inserted) - res.ref->first = key; - else - { i_keydrop((&key)); i_valdrop((&res.ref->second)); } - res.ref->second = mapped; - } - return res; + _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) { + _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto((&_key))); + _cx_mapped* _mp = _res.ref ? &_res.ref->second : &_mapped; + if (_res.inserted) + _res.ref->first = _key; + else + { i_keydrop((&_key)); i_valdrop(_mp); } + *_mp = _mapped; + return _res; } #if !defined i_no_emplace STC_DEF _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, _cx_rawkey rkey, i_valraw rmapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (!res.nomem_error) { - if (res.inserted) - res.ref->first = i_keyfrom(rkey); - else - { i_valdrop((&res.ref->second)); } - res.ref->second = i_valfrom(rmapped); + _cx_result _res = _cx_memb(_insert_entry_)(self, rkey); + if (_res.inserted) + _res.ref->first = i_keyfrom(rkey); + else { + if (!_res.ref) return _res; + i_valdrop((&_res.ref->second)); } - return res; + _res.ref->second = i_valfrom(rmapped); + return _res; } #endif // !i_no_emplace #endif // !_i_isset @@ -331,8 +330,8 @@ _cx_memb(_find_it)(const _cx_self* self, _cx_rawkey rkey, _cx_iter* out) { _cx_node *d = out->_d = self->nodes; out->_top = 0; while (tn) { - int c; const _cx_rawkey raw = i_keyto(_i_keyref(&d[tn].value)); - if ((c = i_cmp_functor(self, (&raw), (&rkey))) < 0) + int c; const _cx_rawkey _raw = i_keyto(_i_keyref(&d[tn].value)); + if ((c = i_cmp_functor(self, (&_raw), (&rkey))) < 0) tn = d[tn].link[1]; else if (c > 0) { out->_st[out->_top++] = tn; tn = d[tn].link[0]; } @@ -393,22 +392,23 @@ _cx_memb(_split_)(_cx_node *d, i_size tn) { } static i_size -_cx_memb(_insert_entry_i_)(_cx_self* self, i_size tn, const _cx_rawkey* rkey, _cx_result* res) { +_cx_memb(_insert_entry_i_)(_cx_self* self, i_size tn, const _cx_rawkey* rkey, _cx_result* _res) { i_size up[64], tx = tn; _cx_node* d = self->nodes; int c, top = 0, dir = 0; while (tx) { up[top++] = tx; - const _cx_rawkey raw = i_keyto(_i_keyref(&d[tx].value)); - if (!(c = i_cmp_functor(self, (&raw), rkey))) - { res->ref = &d[tx].value; return tn; } + const _cx_rawkey _raw = i_keyto(_i_keyref(&d[tx].value)); + if (!(c = i_cmp_functor(self, (&_raw), rkey))) + { _res->ref = &d[tx].value; return tn; } dir = (c < 0); tx = d[tx].link[dir]; } if ((tx = _cx_memb(_new_node_)(self, 1)) == 0) - { res->nomem_error = true; return 0; } + return 0; d = self->nodes; - res->ref = &d[tx].value, res->inserted = true; + _res->ref = &d[tx].value; + _res->inserted = true; if (top == 0) return tx; d[up[top - 1]].link[dir] = tx; diff --git a/include/stc/forward.h b/include/stc/forward.h index 45a68e3a..cc690064 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -116,7 +116,7 @@ typedef union { \ typedef struct { \ SELF##_value *ref; \ - bool inserted, nomem_error; \ + bool inserted; \ } SELF##_result; \ \ typedef struct { \ @@ -169,7 +169,7 @@ typedef union { \ typedef struct { \ SELF##_value *ref; \ - bool inserted, nomem_error; \ + bool inserted; \ } SELF##_result; \ \ typedef struct { \ |
