aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/hashmap.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-07-08 13:55:57 -0700
committerRuss Cox <rsc@golang.org>2009-07-08 13:55:57 -0700
commit764b6ec1aaa832650bd0c65aab749fc811a419c8 (patch)
tree56e0d2c7fc4f6ca11dfa71f59ae63e0c34c9b21a /src/pkg/runtime/hashmap.c
parent0ae7882b5c31991b8e9c2971c733f456ceec1d68 (diff)
downloadgo-764b6ec1aaa832650bd0c65aab749fc811a419c8.tar.xz
reflection for maps
R=r DELTA=304 (248 added, 34 deleted, 22 changed) OCL=31345 CL=31347
Diffstat (limited to 'src/pkg/runtime/hashmap.c')
-rw-r--r--src/pkg/runtime/hashmap.c124
1 files changed, 77 insertions, 47 deletions
diff --git a/src/pkg/runtime/hashmap.c b/src/pkg/runtime/hashmap.c
index 1c8dd09cce..91be38443a 100644
--- a/src/pkg/runtime/hashmap.c
+++ b/src/pkg/runtime/hashmap.c
@@ -662,16 +662,14 @@ donothing(uint32 s, void *a, void *b)
USED(b);
}
-typedef struct hash Hmap;
static int32 debug = 0;
// newmap(keysize uint32, valsize uint32,
// keyalg uint32, valalg uint32,
// hint uint32) (hmap *map[any]any);
-void
-sys·newmap(uint32 keysize, uint32 valsize,
- uint32 keyalg, uint32 valalg, uint32 hint,
- Hmap* ret)
+Hmap*
+makemap(uint32 keysize, uint32 valsize,
+ uint32 keyalg, uint32 valalg, uint32 hint)
{
Hmap *h;
@@ -721,13 +719,39 @@ sys·newmap(uint32 keysize, uint32 valsize,
h->vo2 = rnd(h->ko2+keysize, valsize);
h->po2 = rnd(h->vo2+valsize, 1);
- ret = h;
- FLUSH(&ret);
-
if(debug) {
printf("newmap: map=%p; keysize=%d; valsize=%d; keyalg=%d; valalg=%d; offsets=%d,%d; %d,%d,%d; %d,%d,%d\n",
h, keysize, valsize, keyalg, valalg, h->ko0, h->vo0, h->ko1, h->vo1, h->po1, h->ko2, h->vo2, h->po2);
}
+
+ return h;
+}
+
+// newmap(keysize uint32, valsize uint32,
+// keyalg uint32, valalg uint32,
+// hint uint32) (hmap *map[any]any);
+void
+sys·newmap(uint32 keysize, uint32 valsize,
+ uint32 keyalg, uint32 valalg, uint32 hint,
+ Hmap *ret)
+{
+ ret = makemap(keysize, valsize, keyalg, valalg, hint);
+ FLUSH(&ret);
+}
+
+void
+mapaccess(Hmap *h, byte *ak, byte *av, bool *pres)
+{
+ byte *res;
+
+ res = nil;
+ if(hash_lookup(h, ak, (void**)&res)) {
+ *pres = true;
+ h->valalg->copy(h->valsize, av, res+h->datavo);
+ } else {
+ *pres = false;
+ h->valalg->copy(h->valsize, av, nil);
+ }
}
// mapaccess1(hmap *map[any]any, key any) (val any);
@@ -735,17 +759,14 @@ void
sys·mapaccess1(Hmap *h, ...)
{
byte *ak, *av;
- byte *res;
- int32 hit;
+ bool pres;
ak = (byte*)&h + h->ko1;
av = (byte*)&h + h->vo1;
- res = nil;
- hit = hash_lookup(h, ak, (void**)&res);
- if(!hit)
+ mapaccess(h, ak, av, &pres);
+ if(!pres)
throw("sys·mapaccess1: key not in map");
- h->valalg->copy(h->valsize, av, res+h->datavo);
if(debug) {
prints("sys·mapaccess1: map=");
@@ -754,10 +775,8 @@ sys·mapaccess1(Hmap *h, ...)
h->keyalg->print(h->keysize, ak);
prints("; val=");
h->valalg->print(h->valsize, av);
- prints("; hit=");
- sys·printint(hit);
- prints("; res=");
- sys·printpointer(res);
+ prints("; pres=");
+ sys·printbool(pres);
prints("\n");
}
}
@@ -767,22 +786,12 @@ void
sys·mapaccess2(Hmap *h, ...)
{
byte *ak, *av, *ap;
- byte *res;
- int32 hit;
ak = (byte*)&h + h->ko1;
av = (byte*)&h + h->vo1;
ap = (byte*)&h + h->po1;
- res = nil;
- hit = hash_lookup(h, ak, (void**)&res);
- if(!hit) {
- *ap = false;
- h->valalg->copy(h->valsize, av, nil);
- } else {
- *ap = true;
- h->valalg->copy(h->valsize, av, res+h->datavo);
- }
+ mapaccess(h, ak, av, ap);
if(debug) {
prints("sys·mapaccess2: map=");
@@ -791,23 +800,24 @@ sys·mapaccess2(Hmap *h, ...)
h->keyalg->print(h->keysize, ak);
prints("; val=");
h->valalg->print(h->valsize, av);
- prints("; hit=");
- sys·printint(hit);
- prints("; res=");
- sys·printpointer(res);
prints("; pres=");
sys·printbool(*ap);
prints("\n");
}
}
-static void
+void
mapassign(Hmap *h, byte *ak, byte *av)
{
byte *res;
int32 hit;
res = nil;
+ if(av == nil) {
+ hash_remove(h, ak, (void**)&res);
+ return;
+ }
+
hit = hash_insert(h, ak, (void**)&res);
h->keyalg->copy(h->keysize, res, ak);
h->valalg->copy(h->valsize, res+h->datavo, av);
@@ -844,31 +854,21 @@ void
sys·mapassign2(Hmap *h, ...)
{
byte *ak, *av, *ap;
- byte *res;
- int32 hit;
ak = (byte*)&h + h->ko2;
av = (byte*)&h + h->vo2;
ap = (byte*)&h + h->po2;
- if(*ap == true) {
- // assign
- mapassign(h, ak, av);
- return;
- }
+ if(*ap == false)
+ av = nil; // delete
- // delete
- hit = hash_remove(h, ak, (void**)&res);
+ mapassign(h, ak, av);
if(debug) {
prints("mapassign2: map=");
sys·printpointer(h);
prints("; key=");
h->keyalg->print(h->keysize, ak);
- prints("; hit=");
- sys·printint(hit);
- prints("; res=");
- sys·printpointer(res);
prints("\n");
}
}
@@ -894,6 +894,16 @@ sys·mapiterinit(Hmap *h, struct hash_iter *it)
}
}
+struct hash_iter*
+mapiterinit(Hmap *h)
+{
+ struct hash_iter *it;
+
+ it = mal(sizeof *it);
+ sys·mapiterinit(h, it);
+ return it;
+}
+
// mapiternext(hiter *any);
void
sys·mapiternext(struct hash_iter *it)
@@ -908,6 +918,12 @@ sys·mapiternext(struct hash_iter *it)
}
}
+void
+mapiternext(struct hash_iter *it)
+{
+ sys·mapiternext(it);
+}
+
// mapiter1(hiter *any) (key any);
void
sys·mapiter1(struct hash_iter *it, ...)
@@ -933,6 +949,20 @@ sys·mapiter1(struct hash_iter *it, ...)
}
}
+bool
+mapiterkey(struct hash_iter *it, void *ak)
+{
+ Hmap *h;
+ byte *res;
+
+ h = it->h;
+ res = it->data;
+ if(res == nil)
+ return false;
+ h->keyalg->copy(h->keysize, ak, res);
+ return true;
+}
+
// mapiter2(hiter *any) (key any, val any);
void
sys·mapiter2(struct hash_iter *it, ...)