From e7583efae122b25fa35b8ffcb44f4d199f7d81d5 Mon Sep 17 00:00:00 2001 From: Per Cederqvist <ceder@lysator.liu.se> Date: Tue, 11 Jun 1991 05:42:24 +0000 Subject: [PATCH] Major rewrite. File splitted to simple-cache.c and cache-node.c. --- src/server/simple-cache.c | 741 +++++++++++++++++++++++++------------- 1 file changed, 494 insertions(+), 247 deletions(-) diff --git a/src/server/simple-cache.c b/src/server/simple-cache.c index f4af4164b..84ce980cf 100644 --- a/src/server/simple-cache.c +++ b/src/server/simple-cache.c @@ -9,12 +9,6 @@ * New save algorithm by ceder. */ -/* - * Things to implemet a.s.a.p: - * - * +++ Limit on lru. - * +++ Better allocation scheme of Cache-nodes. - */ /* * Possible improvements: +++ @@ -54,42 +48,15 @@ #include "exp.h" #include "limits.h" +#include "cache-node.h" -typedef struct cache_node { - struct { - u_int exists : 1; - u_int exists_b : 1; - u_int dirty : 1; /* [r *ptr modifierad? */ - } s; - void *snap_shot; /* Dirty data to be written to file B. */ - /* (Dirty relative to file A). */ - void *ptr; /* In-core data. */ - long pos; /* Position to element in file A. */ - long size; /* Size on disk. */ - long pos_b; /* Position to element in file B. */ - long size_b; /* Size in file B. */ - struct cache_node *lru; - struct cache_node *mru; - int lock_cnt; -} Cache_node; - -const Cache_node EMPTY_CACHE_NODE = - ((Cache_node){{ 0, 0, 0}, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0}); - -static Cache_node *pers_mru = NULL; -static Cache_node *pers_lru = NULL; -static Cache_node *conf_mru = NULL; -static Cache_node *conf_lru = NULL; -static Cache_node *text_mru = NULL; -static Cache_node *text_lru = NULL; - -static Cache_node * pers_arr[ MAX_CONF ]; -static Cache_node * conf_arr[ MAX_CONF ]; static Small_conf * small_conf_arr[ MAX_CONF ]; +static Cache_node_mcb * pers_mcb; +static Cache_node_mcb * conf_mcb; static int next_free_num = 1; -static Cache_node * text_arr[ MAX_TEXT ]; -static int next_text_num = 1; +static Cache_node_mcb * text_mcb; +static int next_text_num = 1; /* Defined in ramkomd.c */ extern char datafilename[1024]; @@ -193,77 +160,58 @@ read_text_stat(FILE *fp, return t; } - static void -unlink_lru(Cache_node *node, - Cache_node **lru, - Cache_node **mru) +pers_set_mru(Pers_no pers_no) { - Cache_node *link; - - link = node->lru; - - if ( node->lru != NULL ) - node->lru->mru = node->mru; - else if (*lru == node) - *lru = node->mru; - - if ( node->mru != NULL ) - node->mru->lru = link; - else if (*mru == node) - *mru = link; + set_mru(pers_mcb, pers_no); } static void -insert_mru(Cache_node *node, - Cache_node **lru, - Cache_node **mru) +text_set_mru(Text_no text_no) { - node->mru = NULL; - node->lru = *mru; - *mru = node; - if ( *lru == NULL ) - *lru = node; - - if ( node->lru != NULL ) - node->lru->mru = node; + set_mru(text_mcb, text_no); } static void -pers_set_mru(Pers_no pers_no) +conf_set_mru(Conf_no conf_no) { - Cache_node *node = pers_arr[ pers_no ]; - - if (node == NULL) - restart_kom("pers_set_mru(%d): nonexistent.\n", pers_no); + set_mru(conf_mcb, conf_no); +} - unlink_lru(node, &pers_lru, &pers_mru); - insert_mru(node, &pers_lru, &pers_mru); +static Cache_node * +get_pers_node(Pers_no pers_no) +{ + return get_cache_node(pers_mcb, pers_no); } static void -text_set_mru(Text_no text_no) +unlink_text_lru (Cache_node *node) { - Cache_node *node = text_arr[ text_no ]; - - if ( node == NULL ) - restart_kom("text_set_mru(%d): nonexistent.\n", text_no); - - unlink_lru(node, &text_lru, &text_mru); - insert_mru(node, &text_lru, &text_mru); + unlink_lru (node, &text_mcb->lru, &text_mcb->mru); } +static void +unlink_conf_lru (Cache_node *node) +{ + unlink_lru (node, &conf_mcb->lru, &conf_mcb->mru); +} static void -conf_set_mru(Conf_no conf_no) +unlink_pers_lru (Cache_node *node) { - Cache_node *node = conf_arr[ conf_no ]; + unlink_lru (node, &pers_mcb->lru, &pers_mcb->mru); +} - if ( node == NULL ) - restart_kom("conf_set_mru(%d): nonexistent.\n", conf_no); +static Cache_node * +get_conf_node(Conf_no conf_no) +{ + return get_cache_node(conf_mcb, conf_no); +} - unlink_lru(node, &conf_lru, &conf_mru); - insert_mru(node, &conf_lru, &conf_mru); +static Cache_node * +get_text_node(Text_no text_no) +{ + return get_cache_node(text_mcb, text_no); } @@ -307,7 +255,11 @@ cached_get_conf_type (Conf_no conf_no) if ( conf_no < 1 || conf_no >= next_free_num ) restart_kom("cached_get_conf_type(%d): next_free_num==%d", conf_no, next_free_num); - + + if ( small_conf_arr [ conf_no ] == NULL ) + restart_kom("cached_get_conf_type(%d): conference does not exist.\n", + conf_no); + return small_conf_arr [ conf_no ]->type; } @@ -320,11 +272,15 @@ cached_get_conf_type (Conf_no conf_no) void mark_person_as_changed(Pers_no pers_no) { + Cache_node *node; + + node = get_pers_node(pers_no); + TRACE2("Person %d is changed\n", pers_no); - if ( pers_arr[ pers_no ] == NULL || pers_arr[ pers_no ]->s.exists == 0) + if ( node == NULL || node->s.exists == 0) restart_kom("mark_person_as_changed(%d): nonexistent.\n", pers_no); - pers_arr[ pers_no ]->s.dirty = 1; + node->s.dirty = 1; pers_set_mru( pers_no ); } @@ -332,41 +288,40 @@ mark_person_as_changed(Pers_no pers_no) void mark_conference_as_changed(Conf_no conf_no) { + Cache_node *node; + + node = get_conf_node (conf_no); + TRACE2("Conf. %d is changed\n", conf_no); - if ( conf_arr[ conf_no ] == NULL || conf_arr[ conf_no ]->s.exists == 0) + if ( node == NULL || node->s.exists == 0) restart_kom("mark_conference_as_changed(%d): nonexistent.\n", conf_no); - conf_arr[ conf_no ]->s.dirty = 1; + node->s.dirty = 1; conf_set_mru( conf_no ); small_conf_arr[ conf_no ]->highest_local_no - = (((Conference *)conf_arr [ conf_no ]->ptr)->texts.first_local_no - 1 - + ((Conference *)conf_arr [ conf_no ]->ptr)->texts.no_of_texts ); + = (((Conference *)node->ptr)->texts.first_local_no - 1 + + ((Conference *)node->ptr)->texts.no_of_texts ); } void mark_text_as_changed( Text_no text_no ) { + Cache_node *node; + + node = get_text_node (text_no); + TRACE2("Text %d is changed.\n", text_no); if ( text_no < 1 || text_no >= next_text_num - || text_arr[ text_no ] == NULL || text_arr[ text_no ]->s.exists == 0) + || node == NULL || node->s.exists == 0) { restart_kom("mark_text_as_changed(%d): nonexistent.\n", text_no); } - text_arr[ text_no ]->s.dirty = 1; - text_set_mru( text_no ); + node->s.dirty = 1; + text_set_mru (text_no); } -static Cache_node * -alloc_cache_node(void) -{ - Cache_node *c; - - c = smalloc(sizeof(Cache_node)); - *c = EMPTY_CACHE_NODE; - return c; -} /* * Person-related calls @@ -376,6 +331,8 @@ alloc_cache_node(void) extern Success cached_create_person( Pers_no person ) { + Cache_node *node; + TRACE2("Person %d is being created.\n", person); if ( person < 1 || person >= next_free_num ) @@ -384,16 +341,21 @@ cached_create_person( Pers_no person ) person, next_free_num); } - if ( pers_arr[ person ] != NULL ) + if ( get_pers_node(person) != NULL ) { restart_kom("cached_create_person(%d): Person existed.\n", person); } - pers_arr[ person ] = alloc_cache_node(); - pers_arr[ person ]->ptr = alloc_person(); - pers_arr[ person ]->s.dirty = 1; - pers_arr[ person ]->s.exists = 1; + create_cache_node (pers_mcb, person); + node = get_pers_node (person); + + if ( node == NULL ) + restart_kom("cached_create_person(): couldn't get cache_node.\n"); + + node->ptr = alloc_person(); + node->s.dirty = 1; + node->s.exists = 1; pers_set_mru( person ); return OK; } @@ -402,6 +364,8 @@ cached_create_person( Pers_no person ) extern Person * cached_get_person_stat( Pers_no person ) { + Cache_node *node; + TRACE2("cached_get_person_stat %d\n", person); if ( person == 0 ) @@ -409,33 +373,33 @@ cached_get_person_stat( Pers_no person ) kom_errno = KOM_CONF_ZERO; return NULL; } - - if ( person >= next_free_num || pers_arr[ person ] == NULL - || pers_arr[ person ]->s.exists == 0 ) + + node = get_pers_node (person); + + if ( person >= next_free_num || node == NULL + || node->s.exists == 0 ) { kom_errno = KOM_UNDEF_PERS; return NULL; } - if ( pers_arr[ person ]->ptr != NULL ) + if ( node->ptr != NULL ) { pers_set_mru( person ); - return pers_arr[ person ]->ptr; + return node->ptr; } - if ( pers_arr[ person ]->snap_shot != NULL ) + if ( node->snap_shot != NULL ) { - pers_arr[ person ]->ptr = copy_person(pers_arr[ person ]->snap_shot); + node->ptr = copy_person (node->snap_shot); pers_set_mru (person); - return pers_arr[ person ]->ptr; + return node->ptr; } - pers_arr[ person ]->ptr = read_person(file_a, - pers_arr[ person ]->pos, - pers_arr[ person ]->size); + node->ptr = read_person(file_a, node->pos, node->size); pers_set_mru (person); - return pers_arr[ person ]->ptr; + return node->ptr; } @@ -447,6 +411,7 @@ cached_create_conf (String name) { Conference * conf_c; Conf_no conf_no; + Cache_node *node; TRACE1("cached_create_conf( "); TRACESTR(name); @@ -460,20 +425,25 @@ cached_create_conf (String name) conf_no = next_free_num++; - conf_arr[ conf_no ] = alloc_cache_node(); - conf_arr[ conf_no ]->s.exists = 1; - conf_arr[ conf_no ]->s.dirty = 1; - conf_arr[ conf_no ]->ptr = conf_c = alloc_conference(); + create_cache_node (conf_mcb, conf_no); + node = get_conf_node (conf_no); + + if ( node == NULL ) + restart_kom("cached_create_conf(): failed to allocate cache_node.\n"); + + node->s.exists = 1; + node->s.dirty = 1; + node->ptr = conf_c = alloc_conference(); conf_set_mru(conf_no); - pers_arr[ conf_no ] = NULL; + zero_init_cache_node (pers_mcb, conf_no); small_conf_arr[ conf_no ] = alloc_small_conf(); conf_c->name = EMPTY_STRING; s_strcpy(&conf_c->name, name); cached_change_name( conf_no, name); - TRACE2(" number %d\n", conf_no); + TRACE2("Created conference number %d\n", conf_no); return conf_no; } @@ -482,26 +452,29 @@ cached_create_conf (String name) extern Success cached_delete_conf( Conf_no conf ) { + Cache_node *node; + if ( conf == 0 ) { kom_errno = KOM_CONF_ZERO; return FAILURE; } - - if ( conf >= next_free_num || conf_arr[ conf ] == NULL - || conf_arr[ conf ]->s.exists == 0 ) + + node = get_conf_node (conf); + + if ( conf >= next_free_num || node == NULL || node->s.exists == 0 ) { kom_errno = KOM_UNDEF_CONF; return FAILURE; } - if ( conf_arr[ conf ]->lock_cnt > 0 ) - log("cached_delete_conf(%d): lock_cnt === %d\n", - conf, conf_arr[ conf ]->lock_cnt); + if ( node->lock_cnt > 0 ) + log("WNG: cached_delete_conf(%d): lock_cnt === %d\n", + conf, node->lock_cnt); - free_conference(conf_arr[ conf ]->ptr); - conf_arr[ conf ]->ptr = NULL; - conf_arr[ conf ]->s.exists = 0; + free_conference(node->ptr); + node->ptr = NULL; + node->s.exists = 0; return OK; } @@ -509,14 +482,17 @@ cached_delete_conf( Conf_no conf ) Success cached_delete_person(Pers_no pers) { + Cache_node *node; + if ( pers == 0 ) { kom_errno = KOM_CONF_ZERO; return FAILURE; } - - if ( pers >= next_free_num || pers_arr[ pers ] == NULL - || pers_arr[ pers ]->s.exists == 0 ) + + node = get_pers_node (pers); + + if ( pers >= next_free_num || node == NULL || node->s.exists == 0 ) { log("cached_delete_person(): attempt to" " delete non-existing person.\n"); @@ -524,27 +500,31 @@ cached_delete_person(Pers_no pers) return FAILURE; } - if ( pers_arr[ pers ]->lock_cnt > 0 ) + if ( node->lock_cnt > 0 ) log("cached_delete_pers(%d): lock_cnt === %d\n", - pers, pers_arr[ pers ]->lock_cnt); + pers, node->lock_cnt); - free_person(pers_arr[ pers ]->ptr); - pers_arr[ pers ]->ptr = NULL; - pers_arr[ pers ]->s.exists = 0; + free_person (node->ptr); + node->ptr = NULL; + node->s.exists = 0; return OK; } Success cached_delete_text(Text_no text) { + Cache_node *node; + if ( text == 0 ) { kom_errno = KOM_TEXT_ZERO; return FAILURE; } - - if ( text >= next_text_num || text_arr[ text ] == NULL - || text_arr[ text ]->s.exists == 0 ) + + node = get_text_node (text); + + if ( text >= next_text_num || node == NULL + || node->s.exists == 0 ) { log("cached_delete_text(): attempt to" " delete non-existing text %d.\n", text); @@ -552,22 +532,24 @@ cached_delete_text(Text_no text) return FAILURE; } - if ( text_arr[ text ]->lock_cnt > 0 ) + if ( node->lock_cnt > 0 ) log("cached_delete_text(%d): lock_cnt === %d\n", - text, text_arr[ text ]->lock_cnt); + text, node->lock_cnt); - free_text_stat(text_arr[ text ]->ptr); - text_arr[ text ]->ptr = NULL; - text_arr[ text ]->s.exists = 0; + free_text_stat(node->ptr); + node->ptr = NULL; + node->s.exists = 0; return OK; } extern Conference * -cached_get_conf_stat( Conf_no conf_no ) +cached_get_conf_stat (Conf_no conf_no) { + Cache_node *node; + TRACE2("cached_get_conf_stat %d\n", conf_no); if ( conf_no == 0 ) @@ -575,33 +557,32 @@ cached_get_conf_stat( Conf_no conf_no ) kom_errno = KOM_CONF_ZERO; return NULL; } - - if ( conf_no >= next_free_num || conf_arr[ conf_no ] == NULL - || conf_arr[ conf_no ]->s.exists == 0 ) + + node = get_conf_node (conf_no); + + if ( conf_no >= next_free_num || node == NULL || node->s.exists == 0 ) { kom_errno = KOM_UNDEF_CONF; return NULL; } - if ( conf_arr[ conf_no ]->ptr != NULL ) + if ( node->ptr != NULL ) { - conf_set_mru( conf_no ); - return conf_arr[ conf_no ]->ptr; + conf_set_mru (conf_no); + return node->ptr; } - if ( conf_arr[ conf_no ]->snap_shot != NULL ) + if ( node->snap_shot != NULL ) { - conf_arr[ conf_no ]->ptr = copy_conf(conf_arr[ conf_no ]->snap_shot); + node->ptr = copy_conf (node->snap_shot); conf_set_mru (conf_no); - return conf_arr[ conf_no ]->ptr; + return node->ptr; } - conf_arr[ conf_no ]->ptr - = read_conference(file_a, conf_arr[ conf_no ]->pos, - conf_arr[ conf_no ]->size); + node->ptr = read_conference(file_a, node->pos, node->size); conf_set_mru (conf_no); - return conf_arr[ conf_no ]->ptr; + return node->ptr; } /* @@ -610,8 +591,14 @@ cached_get_conf_stat( Conf_no conf_no ) Bool cached_conf_exists(Conf_no conf_no) { - return (conf_no > 0 && conf_no < next_free_num - && conf_arr[ conf_no ]->s.exists != 0) ? TRUE : FALSE; + Cache_node *node; + + if (conf_no == 0 || conf_no >= next_free_num ) + return FALSE; + + node = get_conf_node (conf_no); + + return node != NULL && node->s.exists != 0; } @@ -655,6 +642,8 @@ cached_get_text( Text_no text ) extern Text_stat * /* NULL on error */ cached_get_text_stat( Text_no text ) { + Cache_node *node; + TRACE2("cached_get_text_stat(%d); next_text_num == ", text); TRACE2("%d\n", next_text_num); @@ -663,37 +652,36 @@ cached_get_text_stat( Text_no text ) kom_errno = KOM_TEXT_ZERO; return NULL; } - - if ( text >= next_text_num || text_arr[ text ] == NULL - || text_arr[ text ]->s.exists == 0 ) + + node = get_text_node (text); + + if ( text >= next_text_num || node == NULL || node->s.exists == 0 ) { TRACE1("cached_get_text_stat: no such text.\n"); kom_errno = KOM_NO_SUCH_TEXT; return NULL; } - if ( text_arr[ text ]->ptr != NULL ) + if ( node->ptr != NULL ) { TRACE1("Found in ptr.\n"); text_set_mru( text ); - return text_arr[ text ]->ptr; + return node->ptr; } - if ( text_arr[ text ]->snap_shot != NULL ) + if ( node->snap_shot != NULL ) { TRACE1("Found in snap_shot\n"); - text_arr[ text ]->ptr = copy_text_stat(text_arr[ text ]->snap_shot); + node->ptr = copy_text_stat(node->snap_shot); text_set_mru (text); - return text_arr[ text ]->ptr; + return node->ptr; } TRACE1("Found in file A.\n"); - text_arr[ text ]->ptr - = read_text_stat(file_a, text_arr[ text ]->pos, - text_arr[ text ]->size); + node->ptr = read_text_stat(file_a, node->pos, node->size); text_set_mru (text); - return text_arr[ text ]->ptr; + return node->ptr; } @@ -707,6 +695,7 @@ extern Text_no cached_create_text( String message) { Text_no tno; + Cache_node *node; tno = next_text_num++; @@ -720,18 +709,22 @@ cached_create_text( String message) return 0; } - text_arr[ tno ] = alloc_cache_node(); + create_cache_node(text_mcb, tno); + node = get_text_node (tno); - text_arr[ tno ]->s.exists = 1; - text_arr[ tno ]->s.dirty = 1; - text_arr[ tno ]->ptr = alloc_text_stat(); - ((Text_stat *)text_arr[ tno ]->ptr)->no_of_misc = 0; - ((Text_stat *)text_arr[ tno ]->ptr)->misc_items = NULL; - ((Text_stat *)text_arr[ tno ]->ptr)->no_of_marks = 0; - ((Text_stat *)text_arr[ tno ]->ptr)->no_of_lines = 0; - ((Text_stat *)text_arr[ tno ]->ptr)->no_of_chars = 0; + if ( node == NULL ) + restart_kom("cached_create_text(): could'nt create cache-node.\n"); + + node->s.exists = 1; + node->s.dirty = 1; + node->ptr = alloc_text_stat(); + ((Text_stat *)node->ptr)->no_of_misc = 0; + ((Text_stat *)node->ptr)->misc_items = NULL; + ((Text_stat *)node->ptr)->no_of_marks = 0; + ((Text_stat *)node->ptr)->no_of_lines = 0; + ((Text_stat *)node->ptr)->no_of_chars = 0; fseek(text_file, 0, SEEK_END); - ((Text_stat *)text_arr[ tno ]->ptr)->file_pos = ftell(text_file); + ((Text_stat *)node->ptr)->file_pos = ftell(text_file); text_set_mru( tno ); @@ -752,12 +745,16 @@ cached_create_text( String message) Text_no traverse_text(Text_no seed) { + Cache_node *node; + seed++; - while ( seed < next_text_num - && (text_arr[ seed ] == NULL - || text_arr[ seed ]->s.exists == 0 ) ) + while ( seed < next_text_num ) { + node = get_text_node (seed); + if ( node != NULL && node->s.exists != 0 ) + break; + seed++; } @@ -767,12 +764,16 @@ traverse_text(Text_no seed) Pers_no traverse_person(Pers_no seed) { + Cache_node *node; + seed++; - while ( seed < next_free_num - && (pers_arr[ seed ] == NULL - | pers_arr[ seed ]->s.exists == 0 )) + while ( seed < next_free_num ) { + node = get_pers_node (seed); + if (node != NULL && node->s.exists != 0 ) + break; + seed++; } @@ -782,12 +783,16 @@ traverse_person(Pers_no seed) Conf_no traverse_conference(Conf_no seed) { + Cache_node *node; + seed++; - while ( seed < next_free_num - && (conf_arr[ seed ] == NULL - || conf_arr[ seed ]->s.exists == 0 )) + while ( seed < next_free_num ) { + node = get_conf_node (seed); + if (node != NULL && node->s.exists != 0 ) + break; + seed++; } @@ -811,41 +816,52 @@ cached_get_highest_local_no (Conf_no conf_no) void cached_lock_person(Pers_no pers_no) { - if ( pers_arr[ pers_no ]->s.exists == 0 ) + Cache_node *node; + + node = get_pers_node(pers_no); + + if ( node == NULL || node->s.exists == 0 ) restart_kom("cached_lock_person(%d): nonexistent.\n", pers_no); - if ( pers_arr[ pers_no ]->ptr == NULL ) + if ( node->ptr == NULL ) { - Person *ptr; + Person *pers_stat_ptr; - ptr = cached_get_person_stat( pers_no ); + pers_stat_ptr = cached_get_person_stat( pers_no ); - if ( ptr == NULL ) + if ( pers_stat_ptr == NULL ) restart_kom("cached_lock_person(%d): couldn't read in person.\n", pers_no); - if ( ptr != pers_arr[ pers_no ]->ptr ) - restart_kom("cached_lock_person(%d): ptr == %d, pers_arr[pers_no]" - "->ptr == %d.\n", pers_no, ptr, - pers_arr[ pers_no ]->ptr); + if ( pers_stat_ptr != node->ptr ) + restart_kom("cached_lock_person(%d): pers_stat_ptr == %d, node" + "->ptr == %d.\n", pers_no, pers_stat_ptr, + node->ptr); } - pers_arr[ pers_no ]->lock_cnt++; + node->lock_cnt++; } /* Decrease reference count. If zero, unlock person. */ void cached_unlock_person(Pers_no pers_no) { - if ( pers_arr[ pers_no ]->lock_cnt <= 0 ) + Cache_node *node; + + node = get_pers_node (pers_no); + + if ( node == NULL ) + restart_kom("cached_unlock_person(): couldn't get cache-node.\n"); + + if ( node->lock_cnt <= 0 ) { log("cached_unlock_person(%d): lock_cnt == %d.\n", - pers_no, pers_arr[ pers_no ]->lock_cnt); + pers_no, node->lock_cnt); - pers_arr[ pers_no ]->lock_cnt = 0; + node->lock_cnt = 0; } else - pers_arr[ pers_no ]->lock_cnt--; + node->lock_cnt--; } @@ -853,41 +869,54 @@ cached_unlock_person(Pers_no pers_no) void cached_lock_conf(Conf_no conf_no) { - if ( conf_arr[ conf_no ]->s.exists == 0 ) + Cache_node *node; + + node = get_conf_node(conf_no); + + if ( node == NULL) + restart_kom("cached_lock_conf(): can't get cache-node.\n"); + + if ( node->s.exists == 0 ) restart_kom("cached_lock_conf(%d): nonexistent.\n", conf_no); - if ( conf_arr[ conf_no ]->ptr == NULL ) + if ( node->ptr == NULL ) { - Conference *ptr; + Conference *conference_ptr; - ptr = cached_get_conf_stat( conf_no ); + conference_ptr = cached_get_conf_stat( conf_no ); - if ( ptr == NULL ) + if ( conference_ptr == NULL ) restart_kom("cached_lock_conf(%d): couldn't read in conf.\n", conf_no); - if ( ptr != conf_arr[ conf_no ]->ptr ) - restart_kom("cached_lock_conf(%d): ptr == %d, conf_arr[conf_no]" - "->ptr == %d.\n", conf_no, ptr, - conf_arr[ conf_no ]->ptr); + if ( conference_ptr != node->ptr ) + restart_kom("cached_lock_conf(%d): conference_ptr == %d, node" + "->ptr == %d.\n", conf_no, conference_ptr, + node->ptr); } - conf_arr[ conf_no ]->lock_cnt++; + node->lock_cnt++; } /* Decrease reference count. If zero, unlock conf. */ void cached_unlock_conf(Conf_no conf_no) { - if ( conf_arr[ conf_no ]->lock_cnt <= 0 ) + Cache_node *node; + + node = get_conf_node(conf_no); + if ( node == NULL ) + restart_kom("cached_unlock_conf(): can't get node.\n"); + + if ( node->lock_cnt <= 0 ) { log("cached_unlock_conf(%d): lock_cnt == %d.\n", - conf_no, conf_arr[ conf_no ]->lock_cnt); + conf_no, node->lock_cnt); - conf_arr[ conf_no ]->lock_cnt = 0; + node->lock_cnt = 0; } else - conf_arr[ conf_no ]->lock_cnt--; + node->lock_cnt--; } @@ -1041,7 +1070,7 @@ pre_sync(void) for ( i = 1; i < highest_conf_no; i++ ) { - node = conf_arr[i]; + node = get_conf_node(i); if ( node != NULL ) { @@ -1053,7 +1082,7 @@ pre_sync(void) if ( node->lock_cnt == 0 ) { - unlink_lru(node, &conf_lru, &conf_mru); + unlink_conf_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } @@ -1069,7 +1098,7 @@ pre_sync(void) for ( i = 1; i < highest_conf_no; i++ ) { - node = pers_arr[i]; + node = get_pers_node(i); if ( node != NULL ) { @@ -1081,7 +1110,7 @@ pre_sync(void) if ( node->lock_cnt == 0 ) { - unlink_lru(node, &pers_lru, &pers_mru); + unlink_pers_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } @@ -1098,7 +1127,7 @@ pre_sync(void) for ( i = 1; i < highest_text_no; i++ ) { - node = text_arr[i]; + node = get_text_node(i); if ( node != NULL ) { @@ -1110,7 +1139,7 @@ pre_sync(void) if ( node->lock_cnt == 0 ) { - unlink_lru(node, &text_lru, &text_mru); + unlink_text_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } @@ -1170,6 +1199,7 @@ copy_file(FILE *from, { sync_state = sync_error; log("sync: copy_file(): fseek failed.\n"); + sfree(buf); return; } @@ -1180,6 +1210,7 @@ copy_file(FILE *from, from_pos, len, result); sync_state = sync_error; + sfree(buf); return; } @@ -1187,6 +1218,7 @@ copy_file(FILE *from, { sync_state = sync_error; log("sync: copy_file(): second fseek failed.\n"); + sfree(buf); return; } @@ -1194,6 +1226,7 @@ copy_file(FILE *from, { sync_state = sync_error; log("sync: copy_file(): fwrite failed.\n"); + sfree(buf); return; } @@ -1207,7 +1240,7 @@ save_one_conf(void) if (sync_next < highest_conf_no) { - cn = conf_arr[ sync_next ]; + cn = get_conf_node (sync_next); if ( cn == NULL ) { @@ -1263,7 +1296,7 @@ save_one_pers(void) if (sync_next < highest_conf_no) { - cn = pers_arr[ sync_next ]; + cn = get_pers_node (sync_next); if ( cn == NULL ) { @@ -1325,37 +1358,40 @@ post_sync(void) for ( i = 1; i < highest_conf_no; i++ ) { - node = conf_arr[i]; + node = get_conf_node(i); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_conference(node->snap_shot); node->snap_shot = NULL; + /* +++ Delete if it no longer exists. */ } } for ( i = 1; i < highest_conf_no; i++ ) { - node = pers_arr[i]; + node = get_pers_node(i); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_person(node->snap_shot); node->snap_shot = NULL; + /* +++ Delete if it no longer exists. */ } } for ( i = 1; i < highest_text_no; i++ ) { - node = text_arr[i]; + node = get_text_node(i); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_text_stat(node->snap_shot); node->snap_shot = NULL; + /* +++ Delete if it no longer exists. */ } } } @@ -1369,7 +1405,7 @@ save_one_text(void) if (sync_next < highest_text_no) { - cn = text_arr[ sync_next ]; + cn = get_text_node(sync_next); if ( cn == NULL ) { @@ -1550,6 +1586,12 @@ init_cache(void) Person tmp_pers = EMPTY_PERSON; Text_stat tmp_text = EMPTY_TEXT_STAT; + pers_mcb = create_cache_node_mcb(100, MAX_CONF); + conf_mcb = create_cache_node_mcb(100, MAX_CONF); + text_mcb = create_cache_node_mcb(100, MAX_TEXT); + + + if ( (text_file = fopen(textfilename, "a+b")) == NULL ) { restart_kom("ERROR: init_cache: can't open text file.\n"); @@ -1589,11 +1631,12 @@ init_cache(void) switch(getc(file_a)) { case '@': - conf_arr[ i ] = NULL; + zero_init_cache_node(conf_mcb, i); break; case '+': - node = conf_arr[ i ] = alloc_cache_node(); + create_cache_node(conf_mcb, i); + node = get_conf_node(i); node->s.exists = 1; node->pos = ftell(file_a) - 1; /* Don't forget the '+' */ @@ -1618,11 +1661,12 @@ init_cache(void) switch(getc(file_a)) { case '@': - pers_arr[ i ] = NULL; + zero_init_cache_node(pers_mcb, i); break; case '+': - node = pers_arr[ i ] = alloc_cache_node(); + create_cache_node(pers_mcb, i); + node = get_pers_node(i); node->s.exists = 1; node->pos = ftell(file_a) - 1; /* Don't forget the '+' */ if ( fparse_person(file_a, &tmp_pers) != OK ) @@ -1643,11 +1687,12 @@ init_cache(void) switch(getc(file_a)) { case '@': - text_arr[ i ] = NULL; + zero_init_cache_node(text_mcb, i); break; case '+': - node = text_arr[ i ] = alloc_cache_node(); + create_cache_node(text_mcb, i); + node = get_text_node(i); node->s.exists = 1; node->pos = ftell(file_a) - 1; /* Don't forget the '+' */ @@ -1682,3 +1727,205 @@ cache_sync_all(void) while ( sync_part() != TRUE ) ; } + +void +free_all_cache (void) +{ + int i; + Cache_node *node; + + for ( i = 0; i < next_free_num; i++ ) + { + node = get_conf_node(i); + if ( node != NULL ) + { + if ( node->snap_shot != NULL ) + { + free_conference (node->snap_shot); + node->snap_shot = NULL; + } + + if ( node->ptr != NULL ) + { + free_conference (node->ptr); + node->ptr = NULL; + } + } + + destruct_cache_node (conf_mcb, i); + + node = get_pers_node(i); + if ( node != NULL ) + { + if ( node->snap_shot != NULL ) + { + free_person (node->snap_shot); + node->snap_shot = NULL; + } + + if ( node->ptr != NULL ) + { + free_person (node->ptr); + node->ptr = NULL; + } + } + + destruct_cache_node (pers_mcb, i); + + s_clear ( &small_conf_arr[i]->name ); + } + + for ( i = 0; i < next_text_num; i++ ) + { + node = get_text_node(i); + if ( node != NULL ) + { + if ( node->snap_shot != NULL ) + { + free_text_stat (node->snap_shot); + node->snap_shot = NULL; + } + + if ( node->ptr != NULL ) + { + free_text_stat (node->ptr); + node->ptr = NULL; + } + } + + destruct_cache_node (text_mcb, i); + } + + free_match_table(match_table); + + sfree (match_table); + sfree (conf_table); +} + + +static void +limit_pers() +{ + Cache_node *node; + int i; + + node = pers_mcb->mru; + + /* Skip first CACHE_PERSONS clean persons. */ + for ( i = 0; node != NULL && i < CACHE_PERSONS; i++ ) + { + while ( node != NULL && node->s.dirty == 0 + && node->snap_shot == NULL && node->lock_cnt == 0 ) + { + node = node->next; + } + + if ( node != NULL ) + node = node->next; + } + + /* Delete any remaining clean persons */ + while ( node != NULL ) + { + if ( node->s.dirty == 0 && node->snap_shot == NULL + && node->lock_cnt == 0 ) + { + unlink_pers_lru(node); + free_person (node->ptr); + node->ptr = NULL; + /* +++ delete cache-node if non-existent. */ + } + + node = node->next; + } +} + +static void +limit_conf() +{ + Cache_node *node; + int i; + + node = conf_mcb->mru; + + /* Skip first CACHE_CONFERENCES clean confs. */ + for ( i = 0; node != NULL && i < CACHE_CONFERENCES; i++ ) + { + while ( node != NULL && node->s.dirty == 0 + && node->snap_shot == NULL && node->lock_cnt == 0 ) + { + node = node->next; + } + + if ( node != NULL ) + node = node->next; + } + + /* Delete any remaining clean confs. */ + while ( node != NULL ) + { + if ( node->s.dirty == 0 && node->snap_shot == NULL + && node->lock_cnt == 0 ) + { + unlink_conf_lru(node); + free_conference (node->ptr); + node->ptr = NULL; + /* +++ delete if non-existent. */ + } + + node = node->next; + } +} + + +static void +limit_text_stat() +{ + Cache_node *node; + int i; + + node = text_mcb->mru; + + /* Skip first CACHE_TEXT_STATS clean text_stats. */ + for ( i = 0; node != NULL && i < CACHE_TEXT_STATS; i++ ) + { + while ( node != NULL && node->s.dirty == 0 + && node->snap_shot == NULL && node->lock_cnt == 0 ) + { + node = node->next; + } + + if ( node != NULL ) + node = node->next; + } + + /* Delete any remaining clean text_stats. */ + while ( node != NULL ) + { + if ( node->s.dirty == 0 && node->snap_shot == NULL + && node->lock_cnt == 0 ) + { + unlink_text_lru(node); + free_text_stat (node->ptr); + node->ptr = NULL; + /* +++ delete if non-existent. */ + } + + node = node->next; + } +} + + + +/* + * Limit the number of 'clean' cache entries. + */ +void +cache_limit_size(void) +{ + limit_pers(); + limit_conf(); + limit_text_stat(); +} + + -- GitLab