Commit c005c520 authored by Per Cederqvist's avatar Per Cederqvist

Integrated into the LysKOM environment. Fixed memory handling. Still

needs more work.
parent aa95e5e5
/*
* $Id: cache.c,v 1.1 1994/02/20 14:10:48 law Exp $
* $Id: cache.c,v 1.2 1994/02/20 17:01:31 ceder Exp $
* Copyright (C) 1991 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
......@@ -27,7 +27,7 @@
* (uses cache-database.c)
*/
/*static char *rcsid = "$Id: cache.c,v 1.1 1994/02/20 14:10:48 law Exp $";
/*static char *rcsid = "$Id: cache.c,v 1.2 1994/02/20 17:01:31 ceder Exp $";
#include "rcs.h"
USE(rcsid);*/
......@@ -39,16 +39,13 @@ USE(rcsid);*/
#include <string.h>
#include "s-string.h"
#include "kom-types.h"
#include "kom-memory.h"
#include "smalloc.h"
#include "lyskomd.h"
#include "cache-database.h"
#include "cache.h"
#define smalloc malloc
#define srealloc realloc
#define sfree free
void log(char *,...);
void restart_kom(char *,...);
#define TIME (time(NULL))
/******** constants ******************************************************/
......@@ -142,7 +139,7 @@ struct cache
/******** globals ********************************************************/
struct cache *textc; /* cache: text status */
struct cache *text_statc; /* cache: text status */
struct cache *textsc; /* cache: texts */
struct cache *persc; /* cache: person status */
struct cache *confc; /* cache: conference status */
......@@ -210,6 +207,46 @@ static void cache_insertnode(struct cache*c,struct cachenode *new)
new->nextwrite=NULL;
}
static void unlinknode(struct cache *c,struct cachenode*cn)
{
int i,j;
if (cn->prev) cn->prev->next=cn->next;
if (cn->next) cn->next->prev=cn->prev;
if (cn->prevused) cn->prevused->nextused=cn->nextused;
if (cn->nextused) cn->nextused->prevused=cn->prevused;
/* nextwrite - do-not-bother, this node isn't in that list */
i=(int)(cn->number/c->skipsize);
if (i>=SKIPTABLESIZE) i=SKIPTABLESIZE-1;
if (c->skiptable[i]==cn)
{
j=(int)(cn->next->number/c->skipsize);
if (j>=SKIPTABLESIZE) j=SKIPTABLESIZE-1;
if (i==j) c->skiptable[i]=cn->next;
else c->skiptable[i]=NULL;
}
c->free(cn->data);
c->cachesize-=cn->size;
log("debug: removed entry %lu in %s from memory\n",cn->number,c->cb->filename);
sfree(cn);
}
static int limit_cache(struct cache *c)
{
struct cachenode *cn;
struct cachenode *next;
if (c->cachesize<=c->cachemaxsize) return 0; /* still memory left */
log("debug: limit_cache '%s'\n",c->cb->filename);
cn=c->firstused;
while (c->cachesize>c->cachemaxsize&&cn)
{
next=cn->nextused;
if (!cn->lastwrite&&!cn->locked) unlinknode(c,cn);
}
return 1;
}
static void cache_write_node(struct cache *c,struct cachenode *cn)
{
void *temp;
......@@ -290,7 +327,7 @@ static void *cache_create(struct cache *c,unsigned long *id)
cn=(struct cachenode*)smalloc(sizeof(struct cachenode));
cn->number=*id;
cn->object=c->create(&(cn->size));
logf("debug: cache create node %ld (size %ld)\n",cn->number,cn->size);
log("debug: cache create node %ld (size %ld)\n",cn->number,cn->size);
cn->locked=0;
cn->lastwrite=1;
cn->readfromdisk=TIME;
......@@ -303,12 +340,14 @@ static void *cache_create_at_id(struct cache *c,unsigned long id)
{
struct cachenode *cn;
if (cn=cache_getnode(c,id)) unlinknode(c,cn); /* if it's there, it shouldn, anyway */
if (cn=cache_getnode(c,id))
restart_kom("cache_create_at_id(): %ld already existed in database %s\n",
id, c->cb->filename);
cn=(struct cachenode*)smalloc(sizeof(struct cachenode));
cn->number=id;
cn->object=c->create(&(cn->size));
logf("debug: cache create node at id %ld (size %ld)\n",cn->number,cn->size);
log("debug: cache create node at id %ld (size %ld)\n",cn->number,cn->size);
cn->locked=0;
cn->lastwrite=1;
cn->readfromdisk=TIME;
......@@ -331,6 +370,8 @@ static void *cache_create_at_id(struct cache *c,unsigned long id)
*
* free: frees "in" structure (same as returned by unpack)
*
* create: create a realstructure, calculates size.
*
*/
......@@ -353,12 +394,6 @@ static Misc_info *misc_info_unpack(void *source,unsigned long no)
return mi;
}
static void misc_info_free(void *source,unsigned long no)
{
sfree(source);
}
static unsigned long membership_list_size(Membership *ms,unsigned long no)
{
unsigned long size,i;
......@@ -435,48 +470,52 @@ static String *texts_unpack(unsigned char *in,unsigned long *size)
static void texts_free(String *s)
{
if (s->string) sfree(s->string);
s_clear(s);
sfree(s);
}
static void *texts_create(unsigned long *size)
static String *texts_create(unsigned long *size)
{
String *s;
s = smalloc(sizeof(String));
*s = EMPTY_STRING;
*size = sizeof(String);
return s;
}
/** text status database; datatype: Text_stat* **/
static void *text_pack(Text_stat *in,unsigned long *size)
static void *text_stat_pack(Text_stat *in,unsigned long *size)
{
unsigned char *out;
*size=sizeof(Text_stat)+misc_info_size(in->misc_items,in->no_of_misc);
out=(unsigned char*)smalloc(*size);
if (!out) { restart_kom("!!! out of memory in cache/text_pack\n"); return NULL; }
if (!out) { restart_kom("!!! out of memory in cache/text_stat_pack\n"); return NULL; }
memcpy(out,in,sizeof(Text_stat));
misc_info_pack(out+sizeof(Text_stat),in->misc_items,in->no_of_misc);
return out;
}
static Text_stat *text_unpack(void *in,unsigned long *size)
static Text_stat *text_stat_unpack(void *in,unsigned long *size)
{
Text_stat *ts;
ts=(Text_stat*)smalloc(sizeof(Text_stat));
if (!ts) { restart_kom("!!! out of memory in cache/text_unpack\n"); return NULL; }
if (!ts) { restart_kom("!!! out of memory in cache/text_stat_unpack\n"); return NULL; }
ts->misc_items=misc_info_unpack(in+sizeof(Text_stat),ts->no_of_misc);
*size=sizeof(Text_stat)+misc_info_size(ts->misc_items,ts->no_of_misc);
sfree(in);
return ts;
}
static void text_free(Text_stat *ts)
static void text_stat_free(Text_stat *ts)
{
misc_info_free(ts->misc_items,ts->no_of_misc);
sfree(ts);
free_text_stat(ts);
}
static Text_stat *text_create(unsigned long *size)
static Text_stat *text_stat_create(unsigned long *size)
{
size=0;
return NULL;
*size=sizeof(Text_stat);
return alloc_text_stat();
}
/** conferance status database; datatype: Conferance* **/
......@@ -523,15 +562,13 @@ static void *conf_unpack(unsigned char *in,unsigned long *size)
static void conf_free(Conference *object)
{
if (object->texts.texts) sfree(object->texts.texts);
if (object->members.members) sfree(object->members.members);
sfree(object);
free_conference(object);
}
static Conference *conf_create(unsigned long *size)
{
size=0;
return NULL;
*size=sizeof(Conference);
return alloc_conference();
}
/** person status database; datatype: Person* **/
......@@ -585,16 +622,13 @@ static Person *pers_unpack(unsigned char *in,unsigned long *size)
static void pers_free(Person *p)
{
sfree(p->marks.marks);
sfree(p->created_texts.texts);
membership_list_free(p->conferences.confs,p->conferences.no_of_confs);
sfree(p);
free_person(p);
}
static Person *pers_create(unsigned long *size)
{
size=0;
return NULL;
*size=sizeof(Person);
return alloc_person();
}
/******** internal cache master routines *********************************/
......@@ -685,22 +719,22 @@ Success init_cache(void)
/* initiate cache (called at initiation/startup of server) */
{
log("cache: Initiating cache system...\n");
textc=initiate_cache(TEXTC_FILE,TEXTC_INDEX,
text_statc=initiate_cache(TEXTC_FILE,TEXTC_INDEX,
TEXTC_MEM,TEXTC_ADD,TEXTC_SIZE,TRUE,
text_pack,text_unpack,text_free,text_create);
text_stat_pack,text_stat_unpack,text_stat_free,text_stat_create);
textsc=initiate_cache(TEXTSC_FILE,TEXTSC_INDEX,
TEXTSC_MEM,TEXTC_ADD,TEXTSC_SIZE,TRUE,
texts_pack,texts_unpack,texts_free,texts_create);
confc=initiate_cache(CONFC_FILE,CONFC_INDEX,
CONFC_MEM,CONFC_ADD,CONFC_SIZE,TRUE,
conf_pack,conf_unpack,conf_free,texts_create);
conf_pack,conf_unpack,conf_free,conf_create);
persc=initiate_cache(PERSC_FILE,PERSC_INDEX,
PERSC_MEM,PERSC_ADD,PERSC_SIZE,TRUE,
pers_pack,pers_unpack,pers_free,pers_create);
if (!(textc&&textsc&&confc&&persc))
if (!(text_statc&&textsc&&confc&&persc))
{
log("cache: Initiation of cache system failed.\n");
if (textc) shutdown_cache(textc);
if (text_statc) shutdown_cache(text_statc);
if (textsc) shutdown_cache(textsc);
if (confc) shutdown_cache(confc);
if (persc) shutdown_cache(persc);
......@@ -714,7 +748,7 @@ void free_all_cache(void)
/* flush, shutdown cache and free all cache memory (called at shutdown) */
{
cache_sync_all();
shutdown_cache(textc);
shutdown_cache(text_statc);
shutdown_cache(textsc);
shutdown_cache(confc);
shutdown_cache(persc);
......@@ -731,7 +765,7 @@ void cache_limit_size(void);
void cache_sync(void)
/* flush all, dont wait for disk */
{
sync_cache(textc);
sync_cache(text_statc);
sync_cache(textsc);
sync_cache(confc);
sync_cache(persc);
......@@ -740,43 +774,80 @@ void cache_sync(void)
Bool sync_part(void)
/* sync timout routine, TRUE=>long timeout before next */
{
cache_write(textc); /* write data to be written */
cache_write(textsc);
cache_write(confc);
cache_write(persc);
cache_clean(textc); /* clean overflow data */
cache_clean(textsc);
cache_clean(confc);
cache_clean(persc);
int k=0;
k+=cache_write(text_statc); /* write data to be written */
k+=limit_cache(text_statc); /* clean overflow data */
k+=cache_write(textsc); /* write data to be written */
k+=limit_cache(textsc); /* clean overflow data */
k+=cache_write(confc); /* write data to be written */
k+=limit_cache(confc); /* clean overflow data */
k+=cache_write(persc); /* write data to be written */
k+=limit_cache(persc); /* clean overflow data */
return k>0 ? FALSE : TRUE;
}
void cache_sync_all(void)
/* flush all & wait until disk is synced */
{
cache_sync();
if (fsync(fileno(text_statc->cb->fp)) != 0)
restart_kom("cache_sync_all(): failed to fsync text_stat: %d", errno);
if (fsync(fileno(text_statc->cb->ifp)) != 0)
restart_kom("cache_sync_all(): failed to fsync text_stat index: %d",
errno);
if (fsync(fileno(textsc->cb->fp)) != 0)
restart_kom("cache_sync_all(): failed to fsync text: %d", errno);
if (fsync(fileno(textsc->cb->ifp)) != 0)
restart_kom("cache_sync_all(): failed to fsync text index: %d",
errno);
if (fsync(fileno(confc->cb->fp)) != 0)
restart_kom("cache_sync_all(): failed to fsync conference: %d", errno);
if (fsync(fileno(confc->cb->ifp)) != 0)
restart_kom("cache_sync_all(): failed to fsync conference index: %d",
errno);
if (fsync(fileno(persc->cb->fp)) != 0)
restart_kom("cache_sync_all(): failed to fsync person: %d", errno);
if (fsync(fileno(persc->cb->ifp)) != 0)
restart_kom("cache_sync_all(): failed to fsync person index: %d",
errno);
}
void tell_cache_garb_text(int running);
/* tell cache that garb_text is in progress, ie never flush cache */
void tell_cache_garb_text(int running)
{
/* We currently ignore this hint. */
}
static _dump_cache_stats(FILE *stat_file,struct cache *c)
{
fprintf(stat_file," Reads: %lu (%lub) - %lu (%lub), %lu%% (%lu%%) from cache; %lu (%lub), %lu%% (%lu%%) from disk\n",
fprintf(stat_file," Reads: %lu (%lub) - %lu (%lub), %lu%% (%lu%%) "
"from cache; %lu (%lub), %lu%% (%lu%%) from disk\n",
c->reads,c->readbytes,
c->hits,c->readbytes-c->readbytesdisk,(100*c->hits)/(c->reads?c->reads:1),
c->hits,c->readbytes-c->readbytesdisk,
(100*c->hits)/(c->reads?c->reads:1),
(100*(c->readbytes-c->readbytesdisk))/(c->readbytes?c->readbytes:1),
c->reads-c->hits,c->readbytesdisk,
(100*(c->reads-c->hits))/(c->reads?c->reads:1),
(100*c->readbytesdisk)/(c->readbytes?c->readbytes:1));
fprintf(stat_file," Writes: %lu (%lub) - %lu (%lub), %lu%% (%lu%%) in cache; %lu (%lub), %lu%% (%lu%%) to disk\n",
fprintf(stat_file," Writes: %lu (%lub) - %lu (%lub), %lu%% (%lu%%) "
"in cache; %lu (%lub), %lu%% (%lu%%) to disk\n",
c->writes,c->writebytes,
c->writehits,c->writebytes-c->writebytesdisk,
(100*c->writehits)/(c->writes?c->writes:1),
(100*(c->writebytes-c->writebytesdisk))/(c->writebytes?c->writebytes:1),
((100*(c->writebytes-c->writebytesdisk))/
(c->writebytes?c->writebytes:1)),
c->writes-c->writehits,c->writebytesdisk,
(100*(c->writes-c->writehits))/(c->writes?c->writebytes:1),
(100*c->writebytesdisk)/(c->writebytes?c->writebytes:1));
fprintf(stat_file," Records: %lu, %lu (%lu%%) in cache using %lub out of %lub (%lu%%)\n",
fprintf(stat_file," Records: %lu, %lu (%lu%%) in cache using %lub "
"out of %lub (%lu%%)\n",
c->cb->active_records,c->nodes,
(100*c->nodes)/(c->cb->active_records?c->cb->active_records:1),
c->cachesize,c->cachemaxsize,(100*c->cachesize)/
......@@ -788,7 +859,7 @@ void dump_cache_stats(FILE *stat_file)
{
fprintf(stat_file,"Cache statistics:\n=================\n\n");
fprintf(stat_file,"Text status database/cache:\n");
_dump_cache_stats(stat_file,textc);
_dump_cache_stats(stat_file,text_statc);
fprintf(stat_file,"\nText database/cache:\n");
_dump_cache_stats(stat_file,textsc);
fprintf(stat_file,"\nConference status database/cache:\n");
......@@ -803,20 +874,24 @@ void dump_cache_mem_usage(FILE *stat_file)
{
unsigned long other,total,cache;
other=(sizeof(struct cache)+sizeof(struct cachebase))*4+
sizeof(struct cachenode)*textc->nodes+
sizeof(struct cachenode)*text_statc->nodes+
sizeof(struct cachenode)*textsc->nodes+
sizeof(struct cachenode)*confc->nodes+
sizeof(struct cachenode)*persc->nodes;
cache=textc->cachesize+
cache=text_statc->cachesize+
textsc->cachesize+
confc->cachesize+
persc->cachesize;
total=cache+other;
fprintf(stat_file,"Cache memory usage: %lub (cache data:%lub (%lu%%), other:%lub (%lu%%))\n",total,cache,(100*cache)/total,other,(100*other)/total);
fprintf(stat_file,"Cache memory usage: %lub (cache data:%lub (%lu%%), "
"other:%lub (%lu%%))\n",
total,cache,(100*cache)/total,other,(100*other)/total);
}
/******** object manipulation routines ***********************************/
/* mark as changed (object is to be re-written to disk) */
void mark_person_as_changed(Pers_no pers)
{
cache_rewrite(persc,pers);
......@@ -824,7 +899,7 @@ void mark_person_as_changed(Pers_no pers)
void mark_text_as_changed(Text_no text)
{
cache_rewrite(textc,text);
cache_rewrite(text_statc,text);
}
void mark_conference_as_changed(Conf_no conf)
......@@ -832,7 +907,8 @@ void mark_conference_as_changed(Conf_no conf)
cache_rewrite(confc,conf);
}
/* mark as changed (object is to be re-written to disk) */
/* lock (do never remove object from memory) & unlock */
void cached_lock_conf(Conf_no conf)
{
......@@ -854,13 +930,40 @@ void cached_unlock_person(Pers_no pers)
cache_unlock(persc,pers);
}
/* lock (do never remove object from memory) & unlock */
Success cached_create_person(Pers_no pers);
Conf_no cached_create_conf(String name);
Text_no cached_create_text(const String message);
/* create object (returns FALSE if person existed) */
Success cached_create_person(Pers_no pers)
{
if ( person < 1 || person >= cb_nextnumber(confc->cb) )
{
restart_kom("cached_create_person(%d): nextnumber == %d.\n",
person, next_free_num);
}
if ( cb_recordpos(persc->cb, pers) != 0 )
{
restart_kom("cached_create_person(%d): Person existed.\n",
person);
}
if (cache_create_at_id(persc, pers) == NULL)
return FAILURE;
return OK;
}
Conf_no cached_create_conf(String name)
{
unsigned long ul;
cache_create(confc, &ul);
return (Conf_no)ul;
}
/* FIXME - resten av filen ej fixad av ceder. */
Text_no cached_create_text(const String message);
Person *cached_get_person_stat(Pers_no person)
{
return cache_read(persc,person);
......@@ -873,14 +976,14 @@ Conference *cached_get_conf_stat(Conf_no conf)
Text_stat *cached_get_text_stat(Text_no text)
{
return cache_read(textc,text);
return cache_read(text_statc,text);
}
/* get object from database */
String cached_get_text(Text_no text)
{
return *((String *)cache_read(textc,text));
return *((String *)cache_read(textsc,text));
}
/* return text. String is to be freed by caller */
......@@ -924,6 +1027,12 @@ Local_text_no cached_get_highes_local_no(Conf_no conf);
Success cached_lookup_name(const String name,Conf_list_old *result);
/* unknown use */
extern Conf_no
cached_no_of_existing_conferences(void)
{
return confc->cb->active_records;
}
/******** miscellanous weird routines ************************************/
Success build_matching_info(void);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment