134 lines · 2.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "xml.h" #define Roundup(x, g)	(((x) + (unsigned)(g-1)) & ~((unsigned)(g-1))) struct Xtree {	Xtree *left;	Xtree *right;	char *str;	int hits;}; struct Xblock {	Xblock *next;	char *free;	char *end;}; static int Strdups, Commons, Unique, Memblocks; static void *getmem(Xml *xp, int len){	int sz;	Xblock *b;	char *ret; 	len = Roundup(len, sizeof(long long)); 	sz = xp->alloc.blksiz;		/* shorthand */	b = xp->alloc.active; 	if(len > sz)		sysfatal("store: object too big (%d > %d)\n", len, sz); 	if(xp->alloc.active == nil || b->free + len >= b->end){		Memblocks++;		b = mallocz(sizeof(Xblock) + sz, 0);		b->free = (char *)&b[1];		b->end = (char *)&b->free[sz]; 		b->next = xp->alloc.active;		xp->alloc.active = b;	} 	ret = b->free;	b->free += len;	return ret;} static Xtree *lookadd(Xml *xp, Xtree *t, char *str, Xtree **match){	int n; 	if(t == nil){		Unique++;		t = getmem(xp, sizeof(Xtree) + strlen(str)+1);		t->left = nil;		t->right = nil;		t->str = (char *)&t[1];		strcpy(t->str, str);		*match = t;		t->hits = 1;		return t;	} 	if((n = strcmp(str, t->str)) == 0){		*match = t;		t->hits++;	}	if(n < 0)		t->left = lookadd(xp, t->left, str, match);	if(n > 0)		t->right = lookadd(xp, t->right, str, match);	return t;} char *xmlstrdup(Xml *xp, char *str, int iscommon){	char *s;	Xtree *t; 	Strdups++;	if(iscommon){		Commons++;		xp->alloc.root = lookadd(xp, xp->alloc.root, str, &t);		return t->str;	} 	s = getmem(xp, strlen(str)+1);	return strcpy(s, str);} void *xmlcalloc(Xml *xp, int n, int m){	void *v; 	v = getmem(xp, n * m);	memset(v, 0, n * m);	return v;} void *xmlmalloc(Xml *xp, int n){	return getmem(xp, n);}  void_Xheapstats(void){	fprint(2, "total=%d common=%d -> unique=%d rare=%d memblocks=%d\n",		Strdups, Commons, Unique, Strdups - Commons, Memblocks);} void_Xheapfree(Xml *xp){	Xblock *b, *n; 	for(b = xp->alloc.active; b; b = n){		n = b->next;		if(xmldebug)			memset(b, 0x7e, xp->alloc.blksiz);		free(b);	} }