rev 397 - in trunk: include/prothon modules/Prosist src
SVN User <[email protected]> Tue, 20 Apr 2004 20:13:27 -0400
| Newsgroups | gmane.comp.lang.prothon.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mark
Date: 2004-04-20 20:13:24 -0400 (Tue, 20 Apr 2004)
New Revision: 397
Modified:
trunk/include/prothon/prothon.h
trunk/include/prothon/prothon_dll.h
trunk/modules/Prosist/Prosist.c
trunk/src/builtins-list.c
trunk/src/object.c
Log:
more work on prosist, added list_item_set
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h 2004-04-19 21:12:55 UTC (rev 396)
+++ trunk/include/prothon/prothon.h 2004-04-21 00:13:24 UTC (rev 397)
@@ -633,6 +633,9 @@
// LIST_ITEM: Access object i from list
obj_p list_item(isp ist, obj_p list, int i);
+// LIST_ITEM_SET: Set object i in list
+void list_item_set(isp ist, obj_p list, int i, obj_p new_item);
+
// LISTn: Convenience list create functions
// list1, list2, ... are convenience functions that allow you to create
// new list objects that contain 1 to 8 item objects.
@@ -1063,6 +1066,17 @@
void clr_unclonable(obj_p obj);
int is_unclonable(obj_p obj);
+//************************** ARCHIVED BIT ***********************************
+// Each object has a bit called archived. This bit tells whether an object has
+// been write-locked (modified) since the last time it was stored via whatever
+// perstistance storage system is controlling this bit, such as prosist. The
+// interpreter sets this bit to false when the object is created and when the
+// object is write locked and never sets it to true. The persistence application
+// is responsbile for maintaining this bit otherwise.
+void set_archived(obj_p obj);
+void clr_archived(obj_p obj);
+int is_archived(obj_p obj);
+
//************************** DELETE LOCKING ***********************************
// The garbage collection process in the memory manager will delete any object
// that isn't recursively contained in the root globals container. This means
Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h 2004-04-19 21:12:55 UTC (rev 396)
+++ trunk/include/prothon/prothon_dll.h 2004-04-21 00:13:24 UTC (rev 397)
@@ -76,6 +76,7 @@
void (*switch_proto)(isp ist, obj_p obj, obj_p new_proto);
obj_p (*list_append)(isp ist, obj_p list_obj, obj_p item);
obj_p (*list_item)(isp ist, obj_p list, int i);
+ void (*list_item_set)(isp ist, obj_p list_obj, int i, obj_p new_item);
size_t (*list_len)(isp ist, obj_p list);
void (*list_clear)(isp ist, obj_p list_obj);
obj_p (*list1)(isp ist, obj_p p1);
@@ -131,6 +132,9 @@
void (*del_unlock)(obj_p obj);
void (*set_immutable)(obj_p obj);
void (*clr_immutable)(obj_p obj);
+ void (*set_archived)(obj_p obj);
+ void (*clr_archived)(obj_p obj);
+ int (*is_archived)(obj_p obj);
void (*set_obj_rdacc)(obj_p obj, int access);
void (*set_obj_wracc)(obj_p obj, int access);
@@ -229,6 +233,7 @@
#define switch_proto (*services->switch_proto)
#define list_append (*services->list_append)
#define list_item (*services->list_item)
+#define list_item_set (*services->list_item_set)
#define list_len (*services->list_len)
#define list_clear (*services->list_clear)
#define new_hash_obj (*services->new_hash_obj)
@@ -285,6 +290,9 @@
#define new_dict_obj (*services->new_dict_obj)
#define proto_len (*services->proto_len)
#define proto_item (*services->proto_item)
+#define set_archived (*services->set_archived)
+#define clr_archived (*services->clr_archived)
+#define is_archived (*services->is_archived)
#endif // OBJECT_H
Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c 2004-04-19 21:12:55 UTC (rev 396)
+++ trunk/modules/Prosist/Prosist.c 2004-04-21 00:13:24 UTC (rev 397)
@@ -70,6 +70,7 @@
obj_p idobj_to_id;
obj_p id_to_obj;
obj_p obj_to_id;
+ obj_p proxies;
} dbrec_t;
typedef dbrec_t* dbrec_p;
@@ -114,14 +115,18 @@
#define ADD_REF(obj) ADD_NUM(obj_to_id_f(ist, dbrecp, (obj)))
+
+//******************************** load_dbm_int *******************************
i32_t load_dbm_int(char* key) {
return 0;
}
+//******************************** store_dbm_int ******************************
void store_dbm_int(char* key, i32_t val) {
}
+//******************************** 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);
if (!id_obj) {
@@ -132,6 +137,19 @@
return (int) 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);
+ 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);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//******************************** obj_to_datum *******************************
apr_datum_t obj_to_datum(isp ist, dbrec_p dbrecp, obj_p obj) {
obj_p id_tuple, proxy_obj;
int bad_proxy = FALSE;
@@ -223,6 +241,19 @@
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;
+ }
+ aprerr = apr_dbm_store(dbrecp->db, apr_str("0"), root_datum);
+ IF_APR_DBM_ERR(dbrecp->db, "storing root object") return;
+*/
+}
+
//******************************** apr_str ************************************
apr_datum_t apr_str(char* str){
apr_datum_t apr_str;
@@ -236,22 +267,105 @@
return NULL;
}
+//******************************** unlock_list ********************************
+void unlock_list(isp ist, obj_p olst) {
+ int i, llen = (int) list_len(ist, olst);
+ for(i=0; i < llen; i++) {
+ obj_p item = list_item(ist, olst, i);
+ if (item != OBJ(NONE))
+ read_unlock(ist, item);
+ }
+ del_unlock(olst);
+}
-//******************************** store_object *******************************
-void store_object(isp ist, dbrec_p dbrecp) {
- apr_status_t aprerr;
- apr_datum_t root_datum;
+//******************************** rdlock_append ******************************
+int rdlock_append(isp ist, dbrec_p dbrecp, 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))
+ return FALSE;
+
+ 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) {
+ 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);
+ (*loidx)++;
+ return;
+ }
+ proxy_obj = call_func0(ist, obj, SYM(__TOSTORPROXY__));
+ if (ist->exception_obj) { unlock_list(ist, locked_objs); return; }
+
+ if (proxy_obj == OBJ(NONE) || is_unclonable(proxy_obj)) {
+ del_unlock(proxy_obj);
+ read_unlock(ist, obj);
+ list_item_set(ist, locked_objs, *loidx, OBJ(NONE));
+ (*loidx)++;
+ return;
+ }
+ if (proxy_obj->data_type == DATA_TYPE_DATAPTR) {
+ tuple_type = has_proto_QUES(ist, proxy_obj, OBJ(TUPLE_PROTO));
+ if (!tuple_type && !has_proto_QUES(ist, proxy_obj, OBJ(STRING_PROTO))) {
+ raise_exception(ist, ProsistExc_OBJ, "unstorable object (data ptr) found in tree");
+ unlock_list(ist, locked_objs);
+ return;
+ }
+ }
+ dict_add(ist, dbrecp->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 (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;
+ key = attr_next_key(ist, proxy_obj, key);
+ }
+ }
+ if (tuple_type) {
+ 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;
+ }
+ }
+}
+
+//******************************** store_new_db *******************************
+void store_new_db(isp ist, dbrec_p dbrecp) {
+ obj_p locked_objs;
+ int idx = 0;
if (apr_dbm_exists(dbrecp->db, apr_str("0"))) {
raise_exception(ist, ProsistExc_OBJ, "Database already exists");
return;
}
- root_datum = obj_to_datum(ist, dbrecp, dbrecp->root); if_exc_return;
- if (!root_datum.dptr) {
+ if (is_unclonable(dbrecp->root)){
raise_exception(ist, ProsistExc_OBJ, "root object is not storable");
return;
}
- aprerr = apr_dbm_store(dbrecp->db, apr_str("0"), root_datum);
- IF_APR_DBM_ERR(dbrecp->db, "storing root object") return;
+ // use ist->lockstack for this?
+ locked_objs = new_list_obj(ist, 20);
+ if (rdlock_append(ist, dbrecp, locked_objs, dbrecp->root)) return;
+ while (idx < (int) list_len(ist, locked_objs)) {
+ add_locked_objs(ist, dbrecp, &idx, locked_objs);
+ if_exc_return;
+ }
+ commit(ist, dbrecp);
}
@@ -328,14 +442,15 @@
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);
if (root_obj == OBJ(NONE)) {
dbrecp->nextid = load_dbm_int("!nextid");
dbrecp->root = load_object(ist, dbrecp);
} else {
dbrecp->root = root_obj;
- dbrecp->nextid = 1;
- store_object(ist, dbrecp);
+ dbrecp->nextid = 0;
+ store_new_db(ist, dbrecp); if_exc_return NULL;
store_dbm_int("!nextid", dbrecp->nextid);
}
return OBJ(NONE);
Modified: trunk/src/builtins-list.c
===================================================================
--- trunk/src/builtins-list.c 2004-04-19 21:12:55 UTC (rev 396)
+++ trunk/src/builtins-list.c 2004-04-21 00:13:24 UTC (rev 397)
@@ -136,6 +136,13 @@
return res;
}
+//********************************* list_item_set *****************************
+void list_item_set(isp ist, obj_p list_obj, int i, obj_p new_item){
+ wrlock_rtrn(list_obj);
+ listitem(list_obj, i) = new_item;
+ write_unlock(ist, list_obj);
+}
+
//********************************* list_append *******************************
obj_p list_append(isp ist, obj_p list_obj, obj_p item){
list_p lstp;
Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c 2004-04-19 21:12:55 UTC (rev 396)
+++ trunk/src/object.c 2004-04-21 00:13:24 UTC (rev 397)
@@ -133,6 +133,7 @@
dll_services.switch_proto = switch_proto;
dll_services.list_append = list_append;
dll_services.list_item = list_item;
+ dll_services.list_item_set = list_item_set;
dll_services.list_len = list_len;
dll_services.list_clear = list_clear;
dll_services.new_hash_obj = new_hash_obj;
@@ -172,6 +173,9 @@
dll_services.del_unlock = del_unlock;
dll_services.set_immutable = set_immutable;
dll_services.clr_immutable = clr_immutable;
+ dll_services.set_archived = set_archived;
+ dll_services.clr_archived = clr_archived;
+ dll_services.is_archived = is_archived;
dll_services.get_pr_head_pool = get_pr_head_pool;
dll_services.dict_keys_values = dict_keys_values;
dll_services.set_obj_rdacc = set_obj_rdacc;
@@ -323,6 +327,29 @@
return res;
}
+//********************************* set_archived ****************************
+void set_archived(obj_p obj){
+ get_wrlock(obj, NO_WAIT);
+ obj->archived = TRUE;
+ free_wrlock(obj);
+}
+
+//********************************* clr_archived ****************************
+void clr_archived(obj_p obj){
+ get_wrlock(obj, NO_WAIT);
+ obj->archived = FALSE;
+ free_wrlock(obj);
+}
+
+//********************************* is_archived *****************************
+int is_archived(obj_p obj) {
+ int res;
+ get_wrlock(obj, NO_WAIT);
+ res = obj->archived;
+ free_wrlock(obj);
+ return res;
+}
+
//********************************* set_obj_rdacc *****************************
void set_obj_rdacc(obj_p obj, int access) {
get_wrlock(obj, NO_WAIT);