rev 398 - in trunk: include/prothon modules/Prosist src

SVN User <[email protected]> Wed, 21 Apr 2004 04:16:25 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-21 04:16:22 -0400 (Wed, 21 Apr 2004)
New Revision: 398

Modified:
   trunk/include/prothon/prothon.h
   trunk/modules/Prosist/Prosist.c
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.c
   trunk/src/builtins-int.c
   trunk/src/dict.h
   trunk/src/object.h
   trunk/src/src.vcproj
Log:
prosist storing to disk is coded but still not working

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/include/prothon/prothon.h	2004-04-21 08:16:22 UTC (rev 398)
@@ -661,8 +661,9 @@
 size_t dict_len(isp ist, obj_p dict);
 
 // DICT_ITEM:  Look up a value in the dictionary for the given key.
-// Find a key using the same __eq__QUES match criteria given for dict_add and return the
-// corresponding value object.  If no key matches then return null.
+// Find a key using the same __eq__QUES match criteria given for 
+// dict_add and return the corresponding value object.  If no key 
+// matches then return null.
 obj_p dict_item(isp ist, obj_p dict, obj_p key);
 
 // DICT_VALUE: Identical to dict_item, provided for consistency in naming.
@@ -696,9 +697,6 @@
 // Minimum value is 1.
 #define HASH_MASK 0x7fffffff
 
-// HASH_VALUE: Integer value of a hash object returned by __hash__ function.
-#define hash_value(hash_obj)  (hash_obj->data.i32[0])
-
 // SET_OBJ_ID: Mark an object as a identity object with a name
 // This is used by Prosist, the persistence engine and other documentation.
 // Any object that occupies a constant attribute slot at all times

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/modules/Prosist/Prosist.c	2004-04-21 08:16:22 UTC (rev 398)
@@ -62,21 +62,22 @@
 
 typedef apr_dbm_t* apr_dbm_p;
 
+typedef i32_t psid_t;
+
 typedef struct {
 	apr_dbm_p	db;
 	obj_p		root;
-	i32_t		nextid;
+	psid_t		nextid;
 	obj_p		id_to_idobj;
 	obj_p		idobj_to_id;
 	obj_p		id_to_obj;
 	obj_p		obj_to_id;
 	obj_p		proxies;
-} dbrec_t;
+} psrec_t;
 
-typedef dbrec_t* dbrec_p;
+typedef psrec_t* psrec_p;
 
 MODULE_DECLARE(Prosist);
-MODULE_DECLARE(DB);
 MODULE_DECLARE(ProsistExc);
 
 MODULE_CONSTANT_DECLARE(Prosist, READONLY ); 
@@ -84,26 +85,40 @@
 MODULE_CONSTANT_DECLARE(Prosist, RWCREATE ); 
 MODULE_CONSTANT_DECLARE(Prosist, RWTRUNCATE  ); 
 
+
+#define IF_APR_DBM_ERR(db, msg1, msg2)													\
+	if (aprerr != APR_SUCCESS){															\
+		char *msg3, buf[256], errbuf[256];												\
+		msg3 = apr_dbm_geterror((db), NULL,  errbuf,  sizeof(errbuf));					\
+		if (msg2)																		\
+			apr_snprintf(buf, sizeof(buf), "dbm error %s%s: %s", (msg1), (msg2), msg3);	\
+		else																			\
+			apr_snprintf(buf, sizeof(buf), "dbm error %s: %s", (msg1), msg3);			\
+	}if (aprerr != APR_SUCCESS)	
+
+//******************************** ADD_BUF macros *****************************
+
 #define BUF_BLOCK_SIZE 1024
 
-#define IF_APR_DBM_ERR(db, msg1)											\
-	if (aprerr != APR_SUCCESS){												\
-		char *msg2, buf[256], errbuf[256];									\
-		msg2 = apr_dbm_geterror((db), NULL,  errbuf,  sizeof(errbuf));		\
-		apr_snprintf(buf, sizeof(buf), "dbm error in %s: %s", (msg1), msg2);\
-	}if (aprerr != APR_SUCCESS)
+#define ADD_BUF_DECLARE			\
+	int _idx, _buf_size;		\
+	char* _buf = pr_malloc(1)
 
+#define ADD_BUF_START()						\
+	_idx=0; _buf_size = BUF_BLOCK_SIZE;		\
+    _buf = pr_realloc(_buf, BUF_BLOCK_SIZE)
+
 #define ADD_CHR(c)											\
-{if (idx == buf_size) {										\
-		buf_size += BUF_BLOCK_SIZE;							\
-		buf = pr_realloc(buf, buf_size);					\
-} (buf[idx++] = (c)); }
+{if (_idx == _buf_size) {									\
+		_buf_size += BUF_BLOCK_SIZE;						\
+		_buf = pr_realloc(_buf, _buf_size);					\
+} (_buf[_idx++] = (c)); }
 
-#define ADD_MEM(ptr, len)						\
-	if (idx+len > buf_size) {					\
-			buf_size = idx+len+BUF_BLOCK_SIZE;	\
-			buf = pr_realloc(buf, buf_size);	\
-	} memcpy(buf+idx, ptr, len); idx += len
+#define ADD_MEM(ptr, len)							\
+	if (_idx+len > _buf_size) {						\
+			_buf_size = _idx+len+BUF_BLOCK_SIZE;	\
+			_buf = pr_realloc(_buf, _buf_size);		\
+	} memcpy(_buf+_idx, ptr, len); _idx += len
 
 #define ADD_STR(str) { int slen = (int) strlen(str); ADD_MEM(str, slen); }	
 
@@ -113,9 +128,19 @@
 	ADD_STR(numbuf);									\
 }
 
-#define ADD_REF(obj) ADD_NUM(obj_to_id_f(ist, dbrecp, (obj)))
+#define ADD_REF(obj) ADD_NUM(obj_to_id(ist, psrecp, (obj)))
 
+#define ADD_BUF_TO_DATUM(datum)	{	\
+	char* buf = pr_malloc(_idx+1);	\
+	memcpy(buf, _buf, _idx);		\
+	buf[_idx] = 0;					\
+	datum.dptr  = buf;				\
+	datum.dsize = _idx;				\
+	_buf = pr_realloc(_buf, 1);		\
+}
 
+#define ADD_BUF_END()   pr_free(_buf)
+
 //******************************** load_dbm_int *******************************
 i32_t load_dbm_int(char* key) {
 	return 0;
@@ -126,145 +151,129 @@
 
 }
 
-//******************************** obj_to_id_f ********************************
-i32_t obj_to_id_f(isp ist, dbrec_p dbrecp, obj_p obj) {
-	obj_p id_obj = dict_item(ist, dbrecp->obj_to_id, obj);
+//******************************** obj_to_id ********************************
+psid_t obj_to_id(isp ist, psrec_p psrecp, obj_p obj) {
+	obj_p id_obj = dict_item(ist, psrecp->obj_to_id, obj); if_exc_return -1;
 	if (!id_obj) {
-		id_obj = NEW_INT(dbrecp->nextid++);
-		dict_add(ist, dbrecp->obj_to_id, obj, id_obj);
-		dict_add(ist, dbrecp->id_to_obj, id_obj, obj);
+		raise_exception(ist, ProsistExc_OBJ, "obj_to_id called on obj with no id");
+		return -1;
 	}
-	return (int) id_obj->data.i64;
+	return (psid_t) id_obj->data.i64;
 }
 
 //******************************** obj_registered_QUES ************************
-int obj_registered_QUES(isp ist, dbrec_p dbrecp, obj_p obj) {
-	obj_p id_obj = dict_item(ist, dbrecp->obj_to_id, obj);
+int obj_registered_QUES(isp ist, psrec_p psrecp, obj_p obj) {
+	obj_p id_obj = dict_item(ist, psrecp->obj_to_id, obj);
+	if_exc_return FALSE;
 	if (!id_obj) {
-		id_obj = NEW_INT(dbrecp->nextid++);
-		dict_add(ist, dbrecp->obj_to_id, obj, id_obj);
-		dict_add(ist, dbrecp->id_to_obj, id_obj, obj);
+		id_obj = NEW_INT(psrecp->nextid++);
+		dict_add(ist, psrecp->obj_to_id, obj, id_obj); if_exc_return FALSE;
+		dict_add(ist, psrecp->id_to_obj, id_obj, obj); 
 		return FALSE;
 	}
 	return TRUE;
 }
 
-//******************************** obj_to_datum *******************************
-apr_datum_t obj_to_datum(isp ist, dbrec_p dbrecp, obj_p obj) {
+//******************************** apr_str ************************************
+apr_datum_t apr_str(char* str){
+	apr_datum_t apr_str;
+	apr_str.dptr  = str;
+	apr_str.dsize = strlen(str);
+	return apr_str;
+}
+
+//******************************** load_object ********************************
+obj_p load_object(isp ist, psrec_p psrecp ) {
+	return NULL;
+}
+
+//******************************** write_obj **********************************
+void write_obj(isp ist, psrec_p psrecp, obj_p obj) {
+	apr_status_t aprerr;
+	apr_datum_t key, value;
 	obj_p id_tuple, proxy_obj;
-	int bad_proxy = FALSE;
-	apr_datum_t datum;
-	char *buf;
+	psid_t id;
+	int i, plen, added_attr;
+	ADD_BUF_DECLARE;
 
-	datum.dptr  = NULL;
-	datum.dsize = 0;
-	if (id_tuple = get_attr(ist, obj, SYM(__ID__))) {
+	id = obj_to_id(ist, psrecp, obj); if_exc_return;
+	ADD_BUF_START();
+	ADD_NUM(id); 
+	ADD_BUF_TO_DATUM(key);
+
+	id_tuple = dict_item(ist, psrecp->idobj_to_id, obj);
+	if (id_tuple) {
 		size_t slen;
 		char* s1 = pr_strptr(list_item(ist, id_tuple, 0));
 		char* s2 = pr_strptr(list_item(ist, id_tuple, 1));
-		if_exc_return datum;
+		if_exc_return;
 		slen = strlen(s1)+strlen(s2)+2;
-		datum.dptr  = buf = pr_malloc(slen+1);
-		datum.dsize = slen;
-		strcpy(buf, "*");
-		strcat(buf, s1);
-		strcat(buf, "*");
-		strcat(buf, s2);
-		dict_add(ist, dbrecp->id_to_idobj, id_tuple, obj);
-		dict_add(ist, dbrecp->idobj_to_id, obj, id_tuple);
-	} else {
-		proxy_obj = call_func0(ist, obj, SYM(__TOSTORPROXY__));
-		if_exc_return datum;
-		if (!proxy_obj) bad_proxy = TRUE;
-		else if (proxy_obj != OBJ(NONE) && !is_unclonable(proxy_obj)) {
-			int i, idx=0, plen, buf_size;
-			int added_attr = FALSE;
-			char* buf = pr_malloc(BUF_BLOCK_SIZE);
+		ADD_BUF_START();
+		ADD_CHR('`');
+		ADD_STR(s1);
+		ADD_CHR('.');
+		ADD_STR(s2);
+		ADD_BUF_TO_DATUM(value);
+		aprerr = apr_dbm_store(psrecp->db, key, value);
 
-			rdlock_rtrn(proxy_obj) datum;
-			plen = proto_len(ist, obj), buf_size = BUF_BLOCK_SIZE;
-			for(i=0; i < plen; i++) {
-				i32_t id = obj_to_id_f(ist, dbrecp, proto_item(ist, obj, i));
-				if(ist->exception_obj) {
-					read_unlock(ist, proxy_obj);
-					pr_free(buf);
-					return datum;
-				}
-				ADD_CHR('p');
-				ADD_NUM(id);
-				if (i < plen-1) ADD_CHR(',') 
-				else            ADD_CHR(';'); 
-			}
-			if (!obj->has_attrs) {
-				attr_key_t key = attr_first_key(ist, obj);
-				while(key) {
-					ADD_CHR('a');
-					ADD_STR(key_to_symstr(ist, key));
-					ADD_CHR(':');
-					ADD_REF(attr_value_by_key(ist, obj, key));
-					ADD_CHR(',');
-					added_attr = TRUE;
-					key = attr_next_key(ist, obj, key);
-				}
-			}
-			if (added_attr) { idx--; ADD_CHR(';'); }
-			if (obj->data_type == DATA_TYPE_IMMDATA) {
-				ADD_CHR('i');
-				ADD_NUM(obj->imm_data_len);
-				ADD_CHR(':');
-				ADD_MEM(&(obj->data), 8);
-			}
-			if (has_proto_QUES(ist, obj, OBJ(STRING_PROTO))) {
-				ADD_CHR('s');
-				ADD_MEM(pr_strptr(obj), (int) pr_strlen(obj));
-			} else if (has_proto_QUES(ist, obj, OBJ(TUPLE_PROTO))) {
-				int llen = (int) list_len(ist, obj);
-				ADD_CHR('l');
-				for (i=0; i < llen; i++) {
-					ADD_REF(list_item(ist, obj, i));
-					if (i < llen-1) ADD_CHR(','); 
-				}
-			} else if (obj->data_type == DATA_TYPE_DATAPTR) 
-				bad_proxy = TRUE;
-			read_unlock(ist, proxy_obj);
+printf("key: %s\n", key.dptr);
+printf("val: %s\n\n", value.dptr);
 
-			datum.dptr  = buf;
-			datum.dsize = idx;
+		ADD_BUF_END();
+		return;
+	}
+	proxy_obj = dict_item(ist, psrecp->proxies, obj);
+	if (!proxy_obj) {
+		raise_exception(ist, ProsistExc_OBJ, "write_obj called with unknown obj");
+		return;
+	}
+	ADD_BUF_START();
+	plen = proto_len(ist, obj);
+	for(i=0; i < plen; i++) {
+		psid_t id = obj_to_id(ist, psrecp, proto_item(ist, obj, i)); if_exc_return;
+		ADD_CHR('p');
+		ADD_NUM(id);
+		if (i < plen-1) ADD_CHR(',') 
+		else            ADD_CHR(';'); 
+	}
+	if (!obj->has_attrs) {
+		attr_key_t akey = attr_first_key(ist, obj);
+		while(akey) {
+			ADD_CHR('a');
+			ADD_STR(key_to_symstr(ist, akey));
+			ADD_CHR(':');
+			ADD_REF(attr_value_by_key(ist, obj, akey));
+			ADD_CHR(',');
+			added_attr = TRUE;
+			akey = attr_next_key(ist, obj, akey);
 		}
 	}
-	if (bad_proxy) {
-		if (datum.dptr) pr_free(datum.dptr);
-		raise_exception(ist, ProsistExc_OBJ, "unstorable object found in tree");
-		datum.dptr  = NULL;
-		datum.dsize = 0;
+	if (added_attr) { _idx--; ADD_CHR(';'); }
+	if (obj->data_type == DATA_TYPE_IMMDATA) {
+		ADD_CHR('i');
+		ADD_NUM(obj->imm_data_len);
+		ADD_CHR(':');
+		ADD_MEM(&(obj->data), 8);
 	}
-	return datum;
-}
-
-//******************************** commit *************************************
-void commit(ist, dbrecp) {
-/*
-	root_datum = obj_to_datum(ist, dbrecp, dbrecp->root); if_exc_return;
-	if (!root_datum.dptr) {
-		raise_exception(ist, ProsistExc_OBJ, "root object is not storable");
-		return;
+	if (has_proto_QUES(ist, obj, OBJ(STRING_PROTO))) {
+		ADD_CHR('s');
+		ADD_MEM(pr_strptr(obj), (int) pr_strlen(obj));
+	} else if (has_proto_QUES(ist, obj, OBJ(TUPLE_PROTO))) {
+		int llen = (int) list_len(ist, obj);
+		ADD_CHR('l');
+		for (i=0; i < llen; i++) {
+			ADD_REF(list_item(ist, obj, i));
+			if (i < llen-1) ADD_CHR(','); 
+		}
 	}
-	aprerr = apr_dbm_store(dbrecp->db, apr_str("0"), root_datum);
-	IF_APR_DBM_ERR(dbrecp->db, "storing root object") return;
-*/
-}
+	ADD_BUF_TO_DATUM(value);
+	aprerr = apr_dbm_store(psrecp->db, key, value);
+	IF_APR_DBM_ERR(psrecp->db, "storing proxy object ", key.dptr);
 
-//******************************** apr_str ************************************
-apr_datum_t apr_str(char* str){
-	apr_datum_t apr_str;
-	apr_str.dptr  = str;
-	apr_str.dsize = strlen(str);
-	return apr_str;
-}
+printf("key: %s\n", key.dptr);
+printf("val: %s\n\n", value.dptr);
 
-//******************************** load_object ********************************
-obj_p load_object(isp ist, dbrec_p dbrecp ) {
-	return NULL;
+	ADD_BUF_END();
 }
 
 //******************************** unlock_list ********************************
@@ -279,27 +288,29 @@
 }
 
 //******************************** rdlock_append ******************************
-int rdlock_append(isp ist, dbrec_p dbrecp, obj_p olst, obj_p obj) {
+int rdlock_append(isp ist, psrec_p psrecp, obj_p olst, obj_p obj) {
 	if_rdlock(obj) {								
 		unlock_list(ist, olst);
 		return TRUE;
 	}
-	if (is_unclonable(obj) || obj_registered_QUES(ist, dbrecp, obj))
+	if (is_unclonable(obj) || obj_registered_QUES(ist, psrecp, obj))
 		return FALSE;
 
+	if_exc_return TRUE;
+
 	list_append(ist, olst, obj);
 	return FALSE;
 }
 
 //******************************** add_locked_objs ****************************
-void add_locked_objs(isp ist, dbrec_p dbrecp, int *loidx, obj_p locked_objs) {
+void add_locked_objs(isp ist, psrec_p psrecp, int *loidx, obj_p locked_objs) {
 	obj_p id_tuple, proxy_obj;
 	int i, idx=0, plen, tuple_type=FALSE;
 	obj_p obj = list_item(ist, locked_objs, *loidx);
 	
 	if (id_tuple = get_attr(ist, obj, SYM(__ID__))) {
-		dict_add(ist, dbrecp->id_to_idobj, id_tuple, obj);
-		dict_add(ist, dbrecp->idobj_to_id, obj, id_tuple);
+		dict_add(ist, psrecp->id_to_idobj, id_tuple, obj);
+		dict_add(ist, psrecp->idobj_to_id, obj, id_tuple);
 		(*loidx)++;
 		return;
 	}
@@ -321,19 +332,19 @@
 			return;
 		}
 	}
-	dict_add(ist, dbrecp->proxies, obj, proxy_obj);
+	dict_add(ist, psrecp->proxies, obj, proxy_obj);
 	(*loidx)++;
 
 	plen = proto_len(ist, proxy_obj);
 	for(i=0; i < plen; i++) {
 		obj_p proto = proto_item(ist, proxy_obj, i);
-		if (rdlock_append(ist, dbrecp, locked_objs, proto)) return;
+		if (rdlock_append(ist, psrecp, locked_objs, proto)) return;
 	}
 	if (proxy_obj->has_attrs) {
 		attr_key_t key = attr_first_key(ist, proxy_obj);
 		while(key) {
 			obj_p attr = attr_value_by_key(ist, proxy_obj, key);
-			if (rdlock_append(ist, dbrecp, locked_objs, attr)) return;
+			if (rdlock_append(ist, psrecp, locked_objs, attr)) return;
 			key = attr_next_key(ist, proxy_obj, key);
 		}
 	}
@@ -341,31 +352,45 @@
 		int llen = (int) list_len(ist, proxy_obj);
 		for (i=0; i < llen; i++) {
 			obj_p item = list_item(ist, proxy_obj, i);
-			if (rdlock_append(ist, dbrecp, locked_objs, item)) return;
+			if (rdlock_append(ist, psrecp, locked_objs, item)) return;
 		}
 	}
 }
 
+#define IF_EXC_UNLKLIST_RTRN()			\
+	if (ist->exception_obj) {			\
+		unlock_list(ist, locked_objs);	\
+		return;							\
+	}
+
 //******************************** store_new_db *******************************
-void store_new_db(isp ist, dbrec_p dbrecp) {
+void store_new_db(isp ist, psrec_p psrecp) {
 	obj_p locked_objs;
-	int idx = 0;
-	if (apr_dbm_exists(dbrecp->db, apr_str("0"))) {
+	int i, idx = 0, llen;
+	if (apr_dbm_exists(psrecp->db, apr_str("0"))) {
 		raise_exception(ist, ProsistExc_OBJ, "Database already exists");
 		return;
 	}
-	if (is_unclonable(dbrecp->root)){
+	if (is_unclonable(psrecp->root)){
 		raise_exception(ist, ProsistExc_OBJ, "root object is not storable");
 		return;
 	}
 	// use ist->lockstack for this?
 	locked_objs = new_list_obj(ist, 20); 
-	if (rdlock_append(ist, dbrecp, locked_objs, dbrecp->root)) return;
+	if (rdlock_append(ist, psrecp, locked_objs, psrecp->root)) return;
 	while (idx < (int) list_len(ist, locked_objs)) {
-		add_locked_objs(ist, dbrecp, &idx, locked_objs);
-		if_exc_return;
+		add_locked_objs(ist, psrecp, &idx, locked_objs);
+		IF_EXC_UNLKLIST_RTRN();
 	}
-	commit(ist, dbrecp);
+	llen = (int) list_len(ist, locked_objs);
+	for (i=0; i < llen; i++) {
+		obj_p item = list_item(ist, locked_objs, i);
+		if (item != OBJ(NONE)) {
+			write_obj(ist, psrecp, item);
+			IF_EXC_UNLKLIST_RTRN();
+		}
+	}
+	unlock_list(ist, locked_objs);
 }
 
 
@@ -376,16 +401,12 @@
 	MODULE_SET_DOC(Prosist, "persistant database module for Prothon objects");
 	MODULE_ADD_TO_BASE(Prosist);
 
-	DB_OBJ = NEW_OBJ(NULL);
-	MODULE_SET_DOC(DB, "Prosist.DB database object prototype");
-	MODULE_ADD_TO_OBJ(DB, Prosist_OBJ, "DB");
-
 	ProsistExc_OBJ = NEW_OBJ(OBJ(EXCEPTION));
 	MODULE_SET_DOC(ProsistExc, "Prosist module error");
 	MODULE_ADD_TO_OBJ(ProsistExc, Prosist_OBJ, "ProsistException");
 
-	DB_OBJ->unclonable = TRUE;
-	set_obj_rdacc(DB_OBJ, ACC_USER1);
+	Prosist_OBJ->unclonable = TRUE;
+	set_obj_rdacc(Prosist_OBJ, ACC_USER1);
 	
 	MODULE_CONSTANT_INT(Prosist, READONLY,   APR_DBM_READONLY ); // read-only access
 	MODULE_CONSTANT_INT(Prosist, READWRITE,  APR_DBM_READWRITE); // read-write access
@@ -393,7 +414,7 @@
 	MODULE_CONSTANT_INT(Prosist, RWTRUNCATE, APR_DBM_RWTRUNC  ); // r/w, truncate if already there
 }
 
-DEF( DB, __init__, FPARM4( name,  NULL, 
+DEF( Prosist, __init__, FPARM4( name,  NULL, 
                            root,  OBJ(NONE), 
                            mode,  Prosist_RWCREATE, 
                            uperm, NEW_INT(APR_UREAD|APR_UWRITE) ) ) {
@@ -401,7 +422,7 @@
 	apr_status_t aprerr;
 	apr_pool_t* cntxt;
 	apr_dbm_p db;
-	dbrec_p dbrecp;
+	psrec_p psrecp;
 	char *name;
     obj_p root_obj;
     int mode, uperm;
@@ -436,22 +457,22 @@
 	read_lock(ist, self);
 
 	self->data_type = DATA_TYPE_DATAPTR;
-	self->data.ptr  = dbrecp = pr_malloc(sizeof(dbrec_t));
-	dbrecp->db = db;
-	dbrecp->id_to_idobj = NEW_DICT(4*INITIAL_OBJ_COUNT);
-	dbrecp->idobj_to_id = NEW_DICT(4*INITIAL_OBJ_COUNT);
-	dbrecp->id_to_obj   = NEW_DICT(4*INITIAL_OBJ_COUNT);
-	dbrecp->obj_to_id   = NEW_DICT(4*INITIAL_OBJ_COUNT);
-	dbrecp->proxies     = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	self->data.ptr  = psrecp = pr_malloc(sizeof(psrec_t));
+	psrecp->db = db;
+	psrecp->id_to_idobj = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	psrecp->idobj_to_id = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	psrecp->id_to_obj   = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	psrecp->obj_to_id   = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	psrecp->proxies     = NEW_DICT(4*INITIAL_OBJ_COUNT);
 
 	if (root_obj == OBJ(NONE)) {
-		dbrecp->nextid = load_dbm_int("!nextid");
-		dbrecp->root   = load_object(ist, dbrecp);  
+		psrecp->nextid = load_dbm_int("!nextid");
+		psrecp->root   = load_object(ist, psrecp);  
 	} else {
-		dbrecp->root   = root_obj;
-		dbrecp->nextid = 0;
-		store_new_db(ist, dbrecp);  if_exc_return NULL; 
-		store_dbm_int("!nextid", dbrecp->nextid);
+		psrecp->root   = root_obj;
+		psrecp->nextid = 0;
+		store_new_db(ist, psrecp);  if_exc_return NULL; 
+		store_dbm_int("!nextid", psrecp->nextid);
 	}
 	return OBJ(NONE);
 }
@@ -490,7 +511,7 @@
 MAIN_MODULE_INIT(Prosist)
 {
 	MODULE_SUB_INIT(Prosist);
-	MODULE_ADD_SYM(DB, __init__);
+	MODULE_ADD_SYM(Prosist, __init__);
 
 	check_exceptions(ist);
 }

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/builtins-core.c	2004-04-21 08:16:22 UTC (rev 398)
@@ -319,7 +319,7 @@
 	for (i=0; i < (int) asize; i++) {
 		if (attr_ap(attrp,i)->attr.key > 0)
 			dict_add( ist, dict_obj, 
-					  NEW_STRING(key_to_symstr(ist, attr_ap(attrp,i)->attr.key)), 
+					  NEW_STRING(key_to_symstr(ist, attr_ap(attrp,i)->attr.key)),
 			          attr_ap(attrp,i)->attr.value );
 	}
 	return dict_obj;
@@ -490,16 +490,22 @@
 	for (i = 0; i < len; i++) {
 		char* item_str;
 		obj_p item = list_item(ist, self,i);
-		int is_str = has_proto_QUES(ist, item, OBJ(STRING_PROTO));
+		int is_str;
 
-		if ((uintptr_t)item > 10) {
-			item_str = as_str(ist, item);
+		if (item) {
+			is_str = has_proto_QUES(ist, item, OBJ(STRING_PROTO));
+
+			if ((uintptr_t)item > 10) {
+				item_str = as_str(ist, item);
+			} else {
+				apr_snprintf(msg, sizeof(msg), "<objptr:%lx>", (unsigned long)(uintptr_t)item);
+				item_str = msg;
+				is_str = FALSE;
+			}
 		} else {
-			apr_snprintf(msg, sizeof(msg), "<objptr:%lx>", (unsigned long)(uintptr_t)item);
-			item_str = msg;
-			is_str = 0;
+			item_str = "<NULL>";
+			is_str = FALSE;
 		}
-
 		res = pr_realloc(res, strlen(res) + strlen(item_str) + strlen(rdelim) + 6);
 		if (is_str)
 			strcat(res, "'");

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/builtins-dict.c	2004-04-21 08:16:22 UTC (rev 398)
@@ -79,12 +79,6 @@
 	return dict_obj;
 }
 
-#define dict_wr_chk()				\
-if (ist->exception_obj) {			\
-	write_unlock(ist, dict_obj);	\
-	return FALSE;					\
-}
-
 //********************************* dict_realloc *****************************
 dict_p dict_realloc(dict_p dict) {
 	dict_p dp, old_dict = dict;
@@ -107,22 +101,32 @@
 	return dict;
 }
 
+//********************************* hash_value ********************************
+i32_t hash_value(isp ist, obj_p key_in) {
+	if (has_proto_QUES(ist, key_in, OBJ(INT_PROTO)))
+		return ((i32_t) key_in->data.i64);
+	else {
+		obj_p hash_obj = call_func(ist, key_in, SYM(__HASH__), 0, NULL, NULL);
+		if (ist->exception_obj) return 0;
+		return hash_obj->data.i32[0];
+	}
+}
+
 //********************************* dict_add **********************************
 int dict_add(isp ist, obj_p dict_obj, obj_p key_in, obj_p value_in) {
 	i32_t i, hash, hash_in, match=FALSE;
 	obj_p key, rp[2];
 	dict_p dict, dp, hole=NULL;
 	rp[0]=0; rp[1]=key_in;
-	if (has_proto_QUES(ist, key_in, OBJ(INT_PROTO)))
-		hash_in = ((i32_t) key_in->data.i64) & HASH_MASK;
-	else
-		hash_in = hash_value(call_func(ist, key_in, SYM(__HASH__), 0, NULL, NULL));
+
+	hash_in = hash_value(ist, key_in);
+	hash_in = hash_in & HASH_MASK;
 	if (!hash_in) hash_in++;
-	dict_wr_chk();
-	dict = (dict_p) obj_data_p(dict_obj);
 
+	dict = dict_d(dict_obj);
+
 	if (((dictlen(dict) * 100) / dictsize(dict)) > DICT_MAX_PERCENT_FULL)
-		dict_obj->data.ptr = dict = dict_realloc(dict);
+		dict_d(dict_obj) = dict = dict_realloc(dict);
 
 	for (i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
 		hash = dp->entry.hash;
@@ -132,9 +136,9 @@
 			match = PR_TRUE;
 			break;
 		}
-		dict_wr_chk();
+		if (ist->exception_obj) return FALSE;
 	}
-	dict_wr_chk();
+	if (ist->exception_obj) return FALSE;
 	if (!match) {
 		dictlen(dict)++;
 		if(hole) dp = hole;
@@ -166,13 +170,17 @@
 	obj_p key, res, rp[2];
 	dict_p dict, dp;
 	rp[0]=0; rp[1]=key_in;
+
+	//if ((unsigned long)(intptr_t)key_in == 0x009ab740)
+	//	dump(ist, "debug.txt", key_in);
+
 	rdlock_rtrn(dict_obj) NULL;
-	if (has_proto_QUES(ist, key_in, OBJ(INT_PROTO)))
-		hash_in = ((i32_t) key_in->data.i64) & HASH_MASK;
-	else
-		hash_in = hash_value(call_func(ist, key_in, SYM(__HASH__), 0, NULL, NULL));
+	hash_in = hash_value(ist, key_in); 
+	if (ist->exception_obj) {
+		read_unlock(ist, dict_obj);	
+		return NULL;				
+	}
 	if (!hash_in) hash_in++;
-	dict_rd_chk();
 	dict = (dict_p) obj_data_p(dict_obj);
 	for (i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
 		if ( dp->entry.hash == hash_in && 
@@ -367,9 +375,9 @@
 		raise_exception(ist, OBJ(INTERPRETER_EXC), "slice not allowed in dictionary indexing");	
 		return NULL;
 	}
-	if (!(res = dict_item(ist, self, list_item(ist, parms[1],0)))) {
+	if (!(res = dict_item(ist, self, list_item(ist, parms[1], 0)))) {
 		raise_exception(ist, OBJ(INDEX_EXC), "no entry found with key: %s",
-				as_str(ist, list_item(ist, parms[1],0)));
+				as_str(ist, list_item(ist, parms[1], 0)));
 		return NULL;
 	}
 	return res;
@@ -396,7 +404,7 @@
 		return NULL;
 	}
 	def_write_lock(self);
-	hash_in = hash_value(call_func(ist, key_in, SYM(__HASH__), 0, NULL, NULL));
+	hash_in = hash_value(ist, key_in);
 	if (ist->exception_obj) {	
 		def_write_unlock(self);
 		return NULL;
@@ -482,7 +490,7 @@
 }
 
 DEF(Dict, __toStorProxy__, NULL) {
-	obj_p proxy_obj = dict_keys_values(ist, self, 4 /*list*/);
+	obj_p proxy_obj = dict_keys_values(ist, self, 2 /*list*/);
 	switch_proto(ist, proxy_obj, DictRestore_OBJ);
 	return proxy_obj;
 }

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/builtins-int.c	2004-04-21 08:16:22 UTC (rev 398)
@@ -90,21 +90,22 @@
 MODULE_START(Int)
 {
 	Int_OBJ = OBJ(INT_PROTO);
-	MODULE_SET_DOC(Int, "number object prototype");
+	set_attr(ist, OBJ(OBJECT), sym(ist, "Int"), Int_OBJ);
+	MODULE_SET_DOC(Int, "integer object prototype");
 	set_obj_id(Int_OBJ, *, Int);
-	set_attr(ist, OBJ(OBJECT), sym(ist, "Int"), Int_OBJ);
+	Int_OBJ->data_type    = DATA_TYPE_IMMDATA;
+	Int_OBJ->imm_data_len = IMMEDIATE_DATA_LEN;
+	Int_OBJ->data.i64     = 0;
 
 	/* Dependent objects */
 	OBJ(ZERO_INT)		= NEW_INT(0);
 	OBJ(MAX_INT)		= NEW_INT(MAX_INT_VAL);
+
 	OBJ(LONG_PROTO)		= NEW_STRING("0");
 	clr_immutable(OBJ(LONG_PROTO));
-	set_obj_doc(OBJ(LONG_PROTO),	"Long integer number object prototype");
+	set_obj_doc(OBJ(LONG_PROTO),	"long integer number object prototype");
+	set_obj_id(OBJ(LONG_PROTO), *, Long);
 	set_immutable(OBJ(LONG_PROTO));
-
-	Int_OBJ->data_type    = DATA_TYPE_IMMDATA;
-	Int_OBJ->imm_data_len = IMMEDIATE_DATA_LEN;
-	Int_OBJ->data.i64     = 0;
 }
 
 DEF(Int, __init__, NULL) {
@@ -121,7 +122,7 @@
 
 DEF(Int, __hash__, NULL) { 
 	i32_t i32 = (i32_t) Int_value(self);
-	return new_hash_obj(ist, (((i32*i32)<<(i32 & 16))+i32)*17);
+	return new_hash_obj(ist, i32);
 }
 
 DEF(Int, __abs__, NULL){
@@ -245,8 +246,10 @@
 DEF(Int, __eq__QUES, FORM_RPARAM){
 	obj_p other = parms[1];
 	if (!is_Int(other)) {
-		if (covers(other, self))
-			return call_func1(ist, other, SYM(__EQ__QUES), self);
+		int c = covers(other, self);
+		if (catch_exception(ist, OBJ(FUNCNOTFOUND_EXC), NULL)) 
+			return FALSE;
+		if (c) return call_func1(ist, other, SYM(__EQ__QUES), self);
 		return OBJ(PR_FALSE);
 	}
 	if (Int_value(self) == Int_value(other)) return OBJ(PR_TRUE);
@@ -325,7 +328,8 @@
 MODULE_START(IntGen)
 {
 	IntGen_OBJ = NEW_OBJ(NULL);
-	MODULE_SET_DOC(Int, "number generator object prototype");
+	MODULE_SET_DOC(IntGen, "number generator object prototype");
+	set_obj_id(IntGen_OBJ, *, IntGen);
 }
 
 DEF(IntGen, next, NULL) {

Modified: trunk/src/dict.h
===================================================================
--- trunk/src/dict.h	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/dict.h	2004-04-21 08:16:22 UTC (rev 398)
@@ -54,12 +54,9 @@
 // dict.h
 
 #define DEFAULT_INITIAL_DICT_SIZE  8
-#define DICT_MAX_PERCENT_FULL  		40
+#define DICT_MAX_PERCENT_FULL  		66
 #define DICT_PAD_PERCENT_FACTOR		300
 
-#define ATTRS_MAX_PERCENT_FULL  		40
-#define ATTRS_PAD_PERCENT_FACTOR		300
-
 typedef struct {
 	size_t	size;
 	size_t	len;

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/object.h	2004-04-21 08:16:22 UTC (rev 398)
@@ -96,9 +96,9 @@
 // Use SYM(__XXX__) instead of sym(ist, "__xxx__") for speed.
 #define SYM(symenum)  (sym_id_table[symenum].id)
 
-#define ATTRS_MAX_PERCENT_FULL  		40
+#define ATTRS_MAX_PERCENT_FULL  		66
 #define ATTRS_PAD_PERCENT_FACTOR		300
-#define ATTRS_PROTO_PADDING				2
+#define ATTRS_PROTO_PADDING				1
 
 #define ATTRS_BSIZE_INDEX		0
 #define ATTRS_BLEN_INDEX		1

Modified: trunk/src/src.vcproj
===================================================================
--- trunk/src/src.vcproj	2004-04-21 00:13:24 UTC (rev 397)
+++ trunk/src/src.vcproj	2004-04-21 08:16:22 UTC (rev 398)
@@ -280,6 +280,9 @@
 				RelativePath="..\pr\oops.pr">
 			</File>
 			<File
+				RelativePath="..\pr\prosist.pr">
+			</File>
+			<File
 				RelativePath="prothon.y">
 			</File>
 			<File