Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libutils/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ libutils_la_SOURCES = \
platform.h condition_macros.h \
printsize.h \
proc_keyvalue.c proc_keyvalue.h \
proc_manager.c proc_manager.h \
queue.c queue.h \
rb-tree.c rb-tree.h \
refcount.c refcount.h \
Expand Down
20 changes: 20 additions & 0 deletions libutils/array_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ bool ArrayMapRemove(ArrayMap *map, const void *key)
return false;
}

bool ArrayMapRemoveSoft(ArrayMap *map, const void *key)
{
assert(map != NULL);

for (int i = 0; i < map->size; ++i)
{
if (map->equal_fn(map->values[i].key, key))
{
map->destroy_key_fn(map->values[i].key);

memmove(map->values + i, map->values + i + 1,
sizeof(MapKeyValue) * (map->size - i - 1));
Comment on lines +99 to +100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Especially because of the memmove(), I think this function should have unit tests (which would be running using ASAN).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a copy-pasted code from ArrayMapRemove().

Copy link
Contributor Author

@vpodzime vpodzime Apr 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we don't have any unit tests doing ArrayMapRemove(). I created CFE-3643 instead of trying to save the world in this PR.


map->size--;
return true;
}
}
return false;
}

MapKeyValue *ArrayMapGet(const ArrayMap *map, const void *key)
{
for (int i = 0; i < map->size; ++i)
Expand Down
1 change: 1 addition & 0 deletions libutils/array_map_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ ArrayMap *ArrayMapNew(MapKeyEqualFn equal_fn,
int ArrayMapInsert(ArrayMap *map, void *key, void *value);

bool ArrayMapRemove(ArrayMap *map, const void *key);
bool ArrayMapRemoveSoft(ArrayMap *map, const void *key);
MapKeyValue *ArrayMapGet(const ArrayMap *map, const void *key);
void ArrayMapClear(ArrayMap *map);
void ArrayMapSoftDestroy(ArrayMap *map);
Expand Down
33 changes: 33 additions & 0 deletions libutils/hash_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,39 @@ bool HashMapRemove(HashMap *map, const void *key)
return false;
}

bool HashMapRemoveSoft(HashMap *map, const void *key)
{
assert(map != NULL);

unsigned bucket = HashMapGetBucket(map, key);

/*
* prev points to a previous "next" pointer to rewrite it in case value need
* to be deleted
*/

for (BucketListItem **prev = &map->buckets[bucket];
*prev != NULL;
prev = &((*prev)->next))
{
BucketListItem *cur = *prev;
if (map->equal_fn(cur->value.key, key))
{
map->destroy_key_fn(cur->value.key);
*prev = cur->next;
free(cur);
map->load--;
if ((map->load < map->min_threshold) && (map->size > map->init_size))
{
HashMapResize(map, map->size >> 1);
}
return true;
}
}

return false;
}

MapKeyValue *HashMapGet(const HashMap *map, const void *key)
{
unsigned bucket = HashMapGetBucket(map, key);
Expand Down
1 change: 1 addition & 0 deletions libutils/hash_map_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ HashMap *HashMapNew(MapHashFn hash_fn, MapKeyEqualFn equal_fn,

bool HashMapInsert(HashMap *map, void *key, void *value);
bool HashMapRemove(HashMap *map, const void *key);
bool HashMapRemoveSoft(HashMap *map, const void *key);
MapKeyValue *HashMapGet(const HashMap *map, const void *key);
void HashMapClear(HashMap *map);
void HashMapSoftDestroy(HashMap *map);
Expand Down
14 changes: 14 additions & 0 deletions libutils/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,20 @@ bool MapRemove(Map *map, const void *key)
}
}

bool MapRemoveSoft(Map *map, const void *key)
{
assert(map != NULL);

if (IsArrayMap(map))
{
return ArrayMapRemoveSoft(map->arraymap, key);
}
else
{
return HashMapRemoveSoft(map->hashmap, key);
}
}

void MapClear(Map *map)
{
assert(map != NULL);
Expand Down
6 changes: 6 additions & 0 deletions libutils/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ void *MapGet(Map *map, const void *key);
*/
bool MapRemove(Map *map, const void *key);

/*
* Remove key/value pair from the map without destroying the value. Returns
* 'true' if key was present in the map.
*/
bool MapRemoveSoft(Map *map, const void *key);

size_t MapSize(const Map *map);

/*
Expand Down
Loading