OSDN Git Service

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