// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"

static	int32	debug	= 0;

typedef	struct	Link	Link;
typedef	struct	Hmap	Hmap;

struct	Link
{
	Link*	link;
	byte	data[8];
};

struct	Hmap
{
	uint32	len;		// must be first
	uint32	keysize;
	uint32	valsize;
	uint32	hint;
	uint32	valoffset;
	uint32	ko;
	uint32	vo;
	uint32	po;
	Alg*	keyalg;
	Alg*	valalg;
	Link*	link;
};

// 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 *m;

	if(keyalg >= 2 ||
	   valalg >= 3) {
		prints("0<=");
		sys·printint(keyalg);
		prints("<");
		sys·printint(nelem(algarray));
		prints("\n0<=");
		sys·printint(valalg);
		prints("<");
		sys·printint(nelem(algarray));
		prints("\n");

		throw("sys·newmap: key/val algorithm out of range");
	}

	m = mal(sizeof(*m));

	m->len = 0;
	m->keysize = keysize;
	m->valsize = valsize;
	m->keyalg = &algarray[keyalg];
	m->valalg = &algarray[valalg];
	m->hint = hint;

	// these calculations are compiler dependent
	m->valoffset = rnd(keysize, valsize);
	m->ko = rnd(sizeof(m), keysize);
	m->vo = rnd(m->ko+keysize, valsize);
	m->po = rnd(m->vo+valsize, 1);

	ret = m;
	FLUSH(&ret);

	if(debug) {
		prints("newmap: map=");
		sys·printpointer(m);
		prints("; keysize=");
		sys·printint(keysize);
		prints("; valsize=");
		sys·printint(valsize);
		prints("; keyalg=");
		sys·printint(keyalg);
		prints("; valalg=");
		sys·printint(valalg);
		prints("; valoffset=");
		sys·printint(m->valoffset);
		prints("; ko=");
		sys·printint(m->ko);
		prints("; vo=");
		sys·printint(m->vo);
		prints("; po=");
		sys·printint(m->po);
		prints("\n");
	}
}

// mapaccess1(hmap *map[any]any, key any) (val any);
void
sys·mapaccess1(Hmap *m, ...)
{
	Link *l;
	byte *ak, *av;

	ak = (byte*)&m + m->ko;
	av = (byte*)&m + m->vo;

	for(l=m->link; l!=nil; l=l->link) {
		if(m->keyalg->equal(m->keysize, ak, l->data)) {
			m->valalg->copy(m->valsize, av, l->data+m->valoffset);
			goto out;
		}
	}

	m->valalg->copy(m->valsize, av, 0);

out:
	if(debug) {
		prints("sys·mapaccess1: map=");
		sys·printpointer(m);
		prints("; key=");
		m->keyalg->print(m->keysize, ak);
		prints("; val=");
		m->valalg->print(m->valsize, av);
		prints("\n");
	}
}

// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
void
sys·mapaccess2(Hmap *m, ...)
{
	Link *l;
	byte *ak, *av, *ap;

	ak = (byte*)&m + m->ko;
	av = (byte*)&m + m->vo;
	ap = (byte*)&m + m->po;

	for(l=m->link; l!=nil; l=l->link) {
		if(m->keyalg->equal(m->keysize, ak, l->data)) {
			*ap = true;
			m->valalg->copy(m->valsize, av, l->data+m->valoffset);
			goto out;
		}
	}

	*ap = false;
	m->valalg->copy(m->valsize, av, nil);

out:
	if(debug) {
		prints("sys·mapaccess2: map=");
		sys·printpointer(m);
		prints("; key=");
		m->keyalg->print(m->keysize, ak);
		prints("; val=");
		m->valalg->print(m->valsize, av);
		prints("; pres=");
		sys·printbool(*ap);
		prints("\n");
	}
}

static void
sys·mapassign(Hmap *m, byte *ak, byte *av)
{
	Link *l;

	// mapassign(hmap *map[any]any, key any, val any);

	for(l=m->link; l!=nil; l=l->link) {
		if(m->keyalg->equal(m->keysize, ak, l->data))
			goto out;
	}

	l = mal((sizeof(*l)-8) + m->keysize + m->valsize);
	l->link = m->link;
	m->link = l;
	m->keyalg->copy(m->keysize, l->data, ak);
	m->len++;

out:
	m->valalg->copy(m->valsize, l->data+m->valoffset, av);

	if(debug) {
		prints("mapassign: map=");
		sys·printpointer(m);
		prints("; key=");
		m->keyalg->print(m->keysize, ak);
		prints("; val=");
		m->valalg->print(m->valsize, av);
		prints("\n");
	}
}

// mapassign1(hmap *map[any]any, key any, val any);
void
sys·mapassign1(Hmap *m, ...)
{
	Link **ll;
	byte *ak, *av;

	ak = (byte*)&m + m->ko;
	av = (byte*)&m + m->vo;

	sys·mapassign(m, ak, av);
}

// mapassign2(hmap *map[any]any, key any, val any, pres bool);
void
sys·mapassign2(Hmap *m, ...)
{
	Link **ll;
	byte *ak, *av, *ap;

	ak = (byte*)&m + m->ko;
	av = (byte*)&m + m->vo;
	ap = (byte*)&m + m->po;

	if(*ap == true) {
		// assign
		sys·mapassign(m, ak, av);
		return;
	}

	// delete
	for(ll=&m->link; (*ll)!=nil; ll=&(*ll)->link) {
		if(m->keyalg->equal(m->keysize, ak, (*ll)->data)) {
			m->valalg->copy(m->valsize, (*ll)->data+m->valoffset, nil);
			(*ll) = (*ll)->link;
			m->len--;
			if(debug) {
				prints("mapdelete (found): map=");
				sys·printpointer(m);
				prints("; key=");
				m->keyalg->print(m->keysize, ak);
				prints("\n");
			}
			return;
		}
	}

	if(debug) {
		prints("mapdelete (not found): map=");
		sys·printpointer(m);
		prints("; key=");
		m->keyalg->print(m->keysize, ak);
		prints(" *** not found\n");
	}
}
