/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
#include <stdlib.h>

#include <stdio.h>
#include <parlib/parlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <iplib/iplib.h>
#include <ndblib/ndb.h>
#include <ndblib/ndbhf.h>

enum {
	Dptr,	/* pointer to database file */
	Cptr,	/* pointer to first chain entry */
	Cptr1,	/* pointer to second chain entry */
};

/*
 *  generate a hash value for an ascii string (val) given
 *  a hash table length (hlen)
 */
uint32_t
ndbhash(char *vp, int hlen)
{
	uint32_t hash;
	uint8_t *val = (uint8_t*)vp;

	for(hash = 0; *val; val++)
		hash = (hash*13) + *val-'a';
	return hash % hlen;
}

/*
 *  read a hash file with buffering
 */
static uint8_t*
hfread(struct ndbhf *hf, long off, int len)
{
	if(off < hf->off || off + len > hf->off + hf->len){
		if(lseek(hf->fd, off, 0) < 0
		|| (hf->len = read(hf->fd, hf->buf, sizeof(hf->buf))) < len){
			hf->off = -1;
			return 0;
		}
		hf->off = off;
	}
	return &hf->buf[off-hf->off];
}

/*
 *  return an opened hash file if one exists for the
 *  attribute and if it is current vis-a-vis the data
 *  base file
 */
static struct ndbhf*
hfopen(struct ndb *db, char *attr)
{
	static int beenhere = 0;
	struct ndbhf *hf;
	char buf[sizeof(hf->attr)+sizeof(db->file)+2];
	uint8_t *p;
	struct dir *d;

	/* try opening the data base if it's closed */
	if(db->mtime==0 && ndbreopen(db) < 0)
		return 0;

	/* if the database has changed, throw out hash files and reopen db */
#if 0
	if((d = dirfstat(Bfildes(&db->b))) == NULL || db->qid.path != d->qid.path
	|| db->qid.vers != d->qid.vers){
#else
	if (! beenhere){
#endif
		if(ndbreopen(db) < 0){
			free(d);
			return 0;
		}
		beenhere = 1;
		db->mtime = 1;
	}
	free(d);

	if(db->nohash)
		return 0;

	/* see if a hash file exists for this attribute */
	for(hf = db->hf; hf; hf= hf->next){
		if(strcmp(hf->attr, attr) == 0)
			return hf;
	}

	/* create a new one */
	hf = (struct ndbhf*)calloc(sizeof(struct ndbhf), 1);
	if(hf == 0)
		return 0;
	memset(hf, 0, sizeof(struct ndbhf));

	/* compare it to the database file */
	strncpy(hf->attr, attr, sizeof(hf->attr)-1);
	sprintf(buf, "%s.%s", db->file, hf->attr);
	hf->fd = open(buf, O_RDONLY);
	if(hf->fd >= 0){
		hf->len = 0;
		hf->off = 0;
		p = hfread(hf, 0, 2*NDBULLEN);
		if(p){
			hf->dbmtime = NDBGETUL(p);
			hf->hlen = NDBGETUL(p+NDBULLEN);
			if(hf->dbmtime == db->mtime){
				hf->next = db->hf;
				db->hf = hf;
				return hf;
			}
		}
		close(hf->fd);
	}

	free(hf);
	return 0;
}

/*
 *  return the first matching entry
 */
struct ndbtuple*
ndbsearch(struct ndb *db, struct ndbs *s, char *attr, char *val)
{
	uint8_t *p;
	struct ndbtuple *t;
	struct ndbhf *hf;
	hf = hfopen(db, attr);

	memset(s, 0, sizeof(*s));
	if(_ndbcachesearch(db, s, attr, val, &t) == 0){
		/* found in cache */
		if(t != NULL){
			ndbsetmalloctag(t, getcallerpc(&db));
			return t;	/* answer from this file */
		}
		if(db->next == NULL)
			return NULL;
		t = ndbsearch(db->next, s, attr, val);
		ndbsetmalloctag(t, getcallerpc(&db));
		return t;
	}

	s->db = db;
	s->hf = hf;
	if(s->hf){
		s->ptr = ndbhash(val, s->hf->hlen)*NDBPLEN;
		p = hfread(s->hf, s->ptr+NDBHLEN, NDBPLEN);
		if(p == 0){
			t = _ndbcacheadd(db, s, attr, val, NULL);
			ndbsetmalloctag(t, getcallerpc(&db));
			return t;
		}
		s->ptr = NDBGETP(p);
		s->type = Cptr1;
	} else if(db->length > 128*1024){
		printf("Missing or out of date hash file %s.%s.\n", db->file, attr);
		//syslog(0, "ndb", "Missing or out of date hash file %s.%s.", db->file, attr);

		/* advance search to next db file */
		s->ptr = NDBNAP;
		_ndbcacheadd(db, s, attr, val, NULL);
		if(db->next == 0)
			return NULL;
		t = ndbsearch(db->next, s, attr, val);
		ndbsetmalloctag(t, getcallerpc(&db));
		return t;
	} else {
		s->ptr = 0;
		s->type = Dptr;
	}
	t = ndbsnext(s, attr, val);
	_ndbcacheadd(db, s, attr, val, (t != NULL && s->db == db)?t:NULL);
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}

static struct ndbtuple*
match(struct ndbtuple *t, char *attr, char *val)
{
	struct ndbtuple *nt;

	for(nt = t; nt; nt = nt->entry)
		if(strcmp(attr, nt->attr) == 0
		&& strcmp(val, nt->val) == 0)
			return nt;
	return 0;
}

/*
 *  return the next matching entry in the hash chain
 */
struct ndbtuple*
ndbsnext(struct ndbs *s, char *attr, char *val)
{
	struct ndbtuple *t;
	struct ndb *db;
	uint8_t *p;

	db = s->db;
	if(s->ptr == NDBNAP)
		goto nextfile;

	for(;;){
		if(s->type == Dptr){
			if(fseek(db->b, s->ptr, 0) < 0)
				break;
			t = ndbparse(db);
			s->ptr = ftell(db->b);
			if(t == 0)
				break;
			if(s->t = match(t, attr, val)){
				ndbsetmalloctag(t, getcallerpc(&s));
				return t;
			}
			ndbfree(t);
		} else if(s->type == Cptr){
			if(fseek(db->b, s->ptr, 0) < 0)
				break; 
			s->ptr = s->ptr1;
			s->type = Cptr1;
			t = ndbparse(db);
			if(t == 0)
				break;
			if(s->t = match(t, attr, val)){
				ndbsetmalloctag(t, getcallerpc(&s));
				return t;
			}
			ndbfree(t);
		} else if(s->type == Cptr1){
			if(s->ptr & NDBCHAIN){	/* hash chain continuation */
				s->ptr &= ~NDBCHAIN;
				p = hfread(s->hf, s->ptr+NDBHLEN, 2*NDBPLEN);
				if(p == 0)
					break;
				s->ptr = NDBGETP(p);
				s->ptr1 = NDBGETP(p+NDBPLEN);
				s->type = Cptr;
			} else {		/* end of hash chain */
				if(fseek(db->b, s->ptr, 0) < 0)
					break; 
				s->ptr = NDBNAP;
				t = ndbparse(db);
				if(t == 0)
					break;
				if(s->t = match(t, attr, val)){
					ndbsetmalloctag(t, getcallerpc(&s));
					return t;
				}
				ndbfree(t);
				break;
			}
		}
	}

nextfile:

	/* nothing left to search? */
	s->ptr = NDBNAP;
	if(db->next == 0)
		return 0;

	/* advance search to next db file */
	t = ndbsearch(db->next, s, attr, val);
	ndbsetmalloctag(t, getcallerpc(&s));
	return t;
}
