📄 dbbureaucrat.c
字号:
#include <glib.h>#include "dbbureaucrat.h"#include "debug.h"#include "db.h"#include "dbtoliet.h"#include "dblog.h"#include "dbbirth.h"#include "dbobject.h"DbBureaucrat *globaldbbureaucrat;/* TODO, do beureaucrat changed list append like, *//* and make multi-threaded. */static voiddb_bureaucrat_create() { if (globaldbbureaucrat != NULL) return ; globaldbbureaucrat = (DbBureaucrat *) mem_alloc(sizeof(DbBureaucrat)); globaldbbureaucrat->obj = (Object **) mem_alloc(sizeof(Object *) * 1); globaldbbureaucrat->num = 0; globaldbbureaucrat->obj_instances = 1; globaldbbureaucrat->lastobjchanged = -1; }static voiddb_bureaucrat_extend(gint newnum) { DbBureaucrat *db = globaldbbureaucrat; g_assert(db); db->obj = (Object **) mem_realloc(db->obj, sizeof(Object *) * newnum); }static voiddb_bureaucrat_delete(gint position) { gint i; DbBureaucrat *db = globaldbbureaucrat; g_assert(db); g_assert(db->obj); for (i = position; i < db->num - 1; i++) { g_assert(db->obj[i]); /* move each item along */ db->obj[i] = db->obj[i + 1]; } db->num--; }/** * db_bureaucrat_generateinstance: * * Returns a unique interger number to be assigned to a new object created. * * Returns: object instance */gintdb_bureaucrat_generateinstance(void) { if (globaldbbureaucrat == NULL) db_bureaucrat_create(); /* should return 1 on first time */ return globaldbbureaucrat->obj_instances++; }/** * db_bureaucrat_deleteinstance: * @instance: instanceid generated by db_generateinstance() * * Deletes an instance of an object from the repositry. * * Returns: non-zero on error */gintdb_bureaucrat_deleteinstance(gint instance) { gint i; DbBureaucrat *db = globaldbbureaucrat; g_assert(db); for (i = 0; i < db->num; i++) { if (db->obj[i]->objectinstance == instance) { db_bureaucrat_delete(i); return 0; } } return -1; }/** * db_bureaucrat_deleteinstance_byobject: * * A wrapper around the db_bureucrat_deleteinstance() where you specify an * object, not an object instance. * * Returns: black hole */gintdb_bureaucrat_deleteinstance_byobject(Object *obj){ g_assert(obj); return db_bureaucrat_deleteinstance(obj->objectinstance); }/** * db_bureaucrat_cleanup: * * Cleans up all globally allocated memory. */voiddb_bureaucrat_cleanup() { gint i; DbBureaucrat *db = globaldbbureaucrat; if (db == NULL) return ; for (i = 0; i < db->num; i++) { g_assert(db->obj[i]); warningmsg("Object %s instance %d hasn't properly been cleaned up", db->obj[i]->name, db->obj[i]->objectinstance); db_freeobject(db->obj[i]); } mem_free(db->obj); mem_free(db); }/** * db_bureaucrat_add: * @obj: Database Object * * Generate an instance for @obj and puts it in the bureaucrat global structure. This will * be called on db_createobject(). * * Returns: non-zero on failure */gintdb_bureaucrat_add(Object * obj) { g_assert(obj); /* now work damn it */ obj->objectinstance = db_bureaucrat_generateinstance(); g_assert(globaldbbureaucrat); db_bureaucrat_extend(globaldbbureaucrat->num + 1); globaldbbureaucrat->obj[globaldbbureaucrat->num] = obj; globaldbbureaucrat->num++; return 0; }/** * db_bureaucrat_find: * @instance: object instance * * Find and return an object in the bureaucrat global structure based on the @instance, else return NULL * if no object by that instance exists. * * Returns: Database Object or NULL on failure */Object *db_bureaucrat_find(gint instance) { gint i; DbBureaucrat *db = globaldbbureaucrat; g_assert(db); for (i = 0; i < db->num; i++) { g_assert(db->obj[i]); if (db->obj[i]->objectinstance == instance) return db->obj[i]; } return NULL; }/** * db_bureaucrat_changedobjects: * * Returns: GList of all objects that have changed in the object list. */GList *db_bureaucrat_changedobjects() { gint i; GList *retlist = NULL; DbFlush *f; DbBureaucrat *db = globaldbbureaucrat; if (!db) return NULL; for (i = 0; i < db->num; i++) { f = db_bureaucrat_createflush(db->obj[i]); if (f != NULL) retlist = g_list_append(retlist, f); } return retlist; }/** * db_bureaucrat_createflush: * @obj: database object to check. * * Check to see if an object has any changes, and if it does return a DbFlush object detailing * what has changed in the object. This can then be used to beginning flushing. * * Returns: %NULL if the object hasn't changed else a DbFlush detailing of how object has changed. */DbFlush *db_bureaucrat_createflush(Object * obj) { gint i; DbCache *c; DbFlush *flush; g_assert(obj); if (db_isobjectchanged(obj) == FALSE) return NULL; flush = (DbFlush *) mem_alloc(sizeof(DbFlush)); flush->cachelist = NULL; flush->obj = obj; /* find out which objects changed. */ for (i = 0; i < obj->numcache; i++) { if (obj->cache[i] != NULL) if (obj->cache[i]->changed == TRUE) { c = obj->cache[i]; flush->cachelist = g_list_append(flush->cachelist, c); db_obj_test(obj); } } return flush; }/** * db_bureaucrat_freeflush: * @flushlist: glist of change objects generated by db_bureaucrat_changedobjects() * * Free memory allocated. */voiddb_bureaucrat_freeflush(GList * flushlist) { DbFlush *f; GList *walk; if (flushlist == NULL) return ; for (walk = g_list_first(flushlist); walk != NULL; walk = walk->next) { f = walk->data; g_list_free(f->cachelist); mem_free(f); } g_list_free(flushlist); }/** * db_bureaucrat_recordwrite: * @instance: database object instance (obj->objectinstance) * * Record that an object has like changed. If enough objects change then i better write stuff back to * database incase of a crash. Its important to not write to early as you might have half entered stuff. * * returns: non-zero on error */gintdb_bureaucrat_recordwrite(gint instance) { DbBureaucrat *db = globaldbbureaucrat; g_assert(db); db_log_add(instance); if (db->lastobjchanged < 0) { db->lastobjchanged = instance; return 0; } if (db->lastobjchanged != instance) db_toliet_flushall(); db->lastobjchanged = instance; return 0; }/** * db_bureaucrat_checkpendingwrites: * @obj: database object about to be used for a read * * From the @obj given, check to see if this will be selecting any data * that is currently in bonddb pending to be written back to the backend * sql statement. This is to ensure your data is the most uptodate. * * Returns: Neigitive on error, else a count of how many items were wrotten back to sql db. */gintdb_bureaucrat_checkpendingwrites(Object *obj){ gint retval=0; DbCache *cache; DbFlush *flush; GList *changedlist, *walk, *cachewalk; //debugwin ("db_bureaucrat_checkpendingwrites() was called"); g_assert(obj); if (obj->birth == NULL) return -1; changedlist = db_bureaucrat_changedobjects(); for(walk = g_list_first(changedlist);walk!=NULL;walk=walk->next) { flush = walk->data; g_assert(flush); for(cachewalk = g_list_first(flush->cachelist);cachewalk!=NULL;cachewalk=cachewalk->next) { cache = cachewalk->data; if (db_birth_iseffected(obj, flush->obj, cache)==TRUE) { message("Object %s is effected by %s so %s.%d is written", obj->name,flush->obj->name,flush->obj->name,cache->id->pg_oid); /*db_toliet_flush*/debugwrap(flush->obj, cache, "db_bureaucrat_checkpendingwrites"); retval ++; } } } return retval;}/** * db_bureaucrat_debug: * * Display a list of everything in the bureaucrat. */gintdb_bureaucrat_debug(){ gint i; DbBureaucrat *db = globaldbbureaucrat; fprintf(debug_stream,"==================== Bureucrat Debug ========================\n"); for (i=0;i<db->num;i++) fprintf(debug_stream,"%d: Name: %s",i,db->obj[i]->name); fprintf(debug_stream,"=============================================================\n"); return 0;}/** * db_bureaucrat_checkmisticconnections: * * * */gintdb_bureaucrat_checkmisticconnections(Object *objchanged, DbCache *cache){ gint i, retval=0; Object *obj; DbBureaucrat *db = globaldbbureaucrat; g_assert(cache); g_assert(objchanged); for(i=0;i<db->num;i++) { obj = db->obj[i]; g_assert(obj); if (obj == objchanged) continue;/* message("seeing if %s effected %s",obj->name,objchanged->name); */ if (db_birth_iseffected(obj, objchanged, cache)==TRUE) { message("refreshing object %s because its out of date",obj->name); db_obj_refresh(obj); retval++; } } return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -