go-map-delete.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* go-map-delete.c -- delete an entry from a map.
  2. Copyright 2009 The Go Authors. All rights reserved.
  3. Use of this source code is governed by a BSD-style
  4. license that can be found in the LICENSE file. */
  5. #include <stddef.h>
  6. #include <stdlib.h>
  7. #include "runtime.h"
  8. #include "malloc.h"
  9. #include "go-alloc.h"
  10. #include "go-assert.h"
  11. #include "map.h"
  12. /* Delete the entry matching KEY from MAP. */
  13. void
  14. __go_map_delete (struct __go_map *map, const void *key)
  15. {
  16. const struct __go_map_descriptor *descriptor;
  17. const struct __go_type_descriptor *key_descriptor;
  18. uintptr_t key_offset;
  19. _Bool (*equalfn) (const void*, const void*, uintptr_t);
  20. size_t key_hash;
  21. size_t key_size;
  22. size_t bucket_index;
  23. void **pentry;
  24. if (map == NULL)
  25. return;
  26. descriptor = map->__descriptor;
  27. key_descriptor = descriptor->__map_descriptor->__key_type;
  28. key_offset = descriptor->__key_offset;
  29. key_size = key_descriptor->__size;
  30. if (key_size == 0)
  31. return;
  32. __go_assert (key_size != -1UL);
  33. equalfn = key_descriptor->__equalfn;
  34. key_hash = key_descriptor->__hashfn (key, key_size);
  35. bucket_index = key_hash % map->__bucket_count;
  36. pentry = map->__buckets + bucket_index;
  37. while (*pentry != NULL)
  38. {
  39. char *entry = (char *) *pentry;
  40. if (equalfn (key, entry + key_offset, key_size))
  41. {
  42. *pentry = *(void **) entry;
  43. if (descriptor->__entry_size >= TinySize)
  44. __go_free (entry);
  45. map->__element_count -= 1;
  46. break;
  47. }
  48. pentry = (void **) entry;
  49. }
  50. }