]> andersk Git - moira.git/blobdiff - server/cache.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / server / cache.qc
index 3ad5e8bd87ed3eb26a05d4061c9e8f157e6cd15c..2c5635ce96df5f8f0347176377a909c6a5145c40 100644 (file)
@@ -15,16 +15,16 @@ static char *rcsid_qsupport_qc = "$Header$";
 
 #include <mit-copyright.h>
 #include "query.h"
-#include "sms_server.h"
+#include "mr_server.h"
 
 
 extern char *whoami, *strsave();
-extern int ingres_errno, sms_errcode;
+extern int ingres_errno, mr_errcode;
 
 
 /*** NOTE **************************************************************
  *
- *     This code depends each type starting with a unique letter.  If
+ *    This code depends on each type starting with a unique letter.  If
  *    any new types are added to the system that begin with the same
  *    letter as one of the existing types:
  *             User
@@ -46,22 +46,18 @@ extern int ingres_errno, sms_errcode;
 struct item {
     char name[NAMESZ];
     char type[9];
+    int nhash;
     int id;
-    int use;
+    struct item *next;
+    struct item *prev;
 };
 
-static struct item  cache[CACHESIZE];
-static struct item *ncache[CACHESIZE];
-static struct item *icache[CACHESIZE];
+static struct item cachehead;
+static int cachesize;
 
-/* use counter for implementing LRU */
-static int use = 1;
 /* statistics counters */
 int cachehits = 0, cachemisses = 0;
 
-/* ID hash function */
-#define hashid(id, type) (((id) + *(type)) % CACHESIZE)
-
 
 /* Name hash function. */
 
@@ -73,7 +69,7 @@ char *type;
 
     while (*name)
       val = val<<5 - val + *name++ - '`';
-    return(val % CACHESIZE);
+    return(val);
 }
 
 
@@ -83,18 +79,22 @@ char *type;
 
 flush_cache()
 {
-    int i;
+    register struct item *i;
 
     if (cachehits + cachemisses != 0)
       com_err(whoami, 0, "Flushing cache; %d hits, %d misses, %d%% hit rate",
              cachehits, cachemisses,
              (100 * cachehits) / (cachehits + cachemisses));
-    cachehits = cachemisses = 0;
-    for (i = 0; i < CACHESIZE; i++) {
-       cache[i].use = 0;
-       ncache[i] = NULL;
-       icache[i] = NULL;
+    else
+      cachehead.next = cachehead.prev = &cachehead;
+    cachehits = cachemisses = cachesize = 0;
+    for (i = cachehead.next; i != &cachehead; i = i->next) {
+       if (i->prev != &cachehead)
+         free(i->prev);
     }
+    if (cachehead.prev != &cachehead)
+      free(cachehead.prev);
+    cachehead.next = cachehead.prev = &cachehead;
 }
 
 
@@ -107,17 +107,26 @@ char *name;
 char *type;
 int *id;
 ##{
-    struct item *i, *mini;
+    register struct item *i;
 ##  char *iname;
 ##  int j, rowcount;
-    int ctr, minv;
-
-    i = ncache[hashname(name, type)];
-    if (i && !strcmp(name, i->name) && !strcasecmp(type, i->type)) {
+    int h, ctr;
+
+    h = hashname(name, type);
+    for (i = cachehead.next; i != &cachehead; i = i->next) {
+       if (i->nhash != h ||
+           strcmp(name, i->name) ||
+           strcasecmp(type, i->type))
+         continue;
        *id = i->id;
-       i->use = use++;
        cachehits++;
-       return(SMS_SUCCESS);
+       i->next->prev = i->prev;
+       i->prev->next = i->next;
+       i->next = cachehead.next;
+       i->prev = &cachehead;
+       cachehead.next->prev = i;
+       cachehead.next = i;
+       return(MR_SUCCESS);
     }
 
     cachemisses++;
@@ -149,32 +158,34 @@ int *id;
 ##     repeat retrieve (j = strings.string_id) where strings.#string=@iname
        break;
     default:
-       return(SMS_INTERNAL);
+       return(MR_INTERNAL);
     }
 ##  inquire_equel(rowcount = "rowcount")
-    if (ingres_errno) return(sms_errcode);
+    if (ingres_errno) return(mr_errcode);
     if (rowcount == 0)
-      return(SMS_NO_MATCH);
+      return(MR_NO_MATCH);
     if (rowcount > 1)
-      return(SMS_NOT_UNIQUE);
+      return(MR_NOT_UNIQUE);
     *id = j;
     if (name[0] == '#' && !strcasecmp(type, "USER"))
-      return(SMS_SUCCESS);
-    minv = use;
-    for (i = &cache[0]; i < &cache[CACHESIZE]; i++) {
-       if (i->use < minv) {
-           minv = i->use;
-           mini = i;
-           if (minv == 0)
-             break;
-       }
+      return(MR_SUCCESS);
+    if (cachesize < CACHESIZE) {
+       i = (struct item *) malloc(sizeof(struct item));
+       cachesize++;
+    } else {
+       i = cachehead.prev;
+       cachehead.prev = i->prev;
+       i->prev->next = &cachehead;
     }
-    mini->id = j;
-    mini->use = use++;
-    strcpy(mini->name, name);
-    strcpy(mini->type, type);
-    ncache[hashname(name, type)] = icache[hashid(j, type)] = mini;
-    return(SMS_SUCCESS);
+    strcpy(i->name, name);
+    strcpy(i->type, type);
+    i->nhash = h;
+    i->id = j;
+    i->next = cachehead.next;
+    i->prev = &cachehead;
+    cachehead.next->prev = i;
+    cachehead.next = i;
+    return(MR_SUCCESS);
 ##}
 
 
@@ -188,18 +199,23 @@ int id;
 char *type;
 char **name;
 ##{
-    struct item *i, *mini;
+    register struct item *i;
 ##  char iname[NAMESZ];
 ##  int j, rowcount;
-    int ctr, minv;
+    int ctr;
 
-    i = icache[hashid(id, type)];
-    if (i && id == i->id && !strcasecmp(type, i->type)) {
+    for (i = cachehead.next; i != &cachehead; i = i->next) {
+       if (i->id != id || strcasecmp(type, i->type)) continue;
        free(*name);
        *name = strsave(i->name);
-       i->use = use++;
        cachehits++;
-       return(SMS_SUCCESS);
+       i->next->prev = i->prev;
+       i->prev->next = i->next;
+       i->next = cachehead.next;
+       i->prev = &cachehead;
+       cachehead.next->prev = i;
+       cachehead.next = i;
+       return(MR_SUCCESS);
     }
 
     cachemisses++;
@@ -231,37 +247,39 @@ char **name;
 ##     repeat retrieve (iname = strings.string) where strings.string_id=@j
        break;
     default:
-       return(SMS_INTERNAL);
+       return(MR_INTERNAL);
     }
 ##  inquire_equel(rowcount = "rowcount")
-    if (ingres_errno) return(sms_errcode);
+    if (ingres_errno) return(mr_errcode);
     if (rowcount == 0) {
        free(*name);
        sprintf(iname, "#%d", j);
        *name = strsave(iname);
-       return(SMS_NO_MATCH);
+       return(MR_NO_MATCH);
     }
     if (rowcount != 1)
-      return(SMS_INTERNAL);
+      return(MR_INTERNAL);
     free(*name);
     *name = strsave(strtrim(iname));
     if (**name == '#' && !strcasecmp(type, "USER"))
-      return(SMS_SUCCESS);
-    minv = use;
-    for (i = &cache[0]; i < &cache[CACHESIZE]; i++) {
-       if (i->use < minv) {
-           minv = i->use;
-           mini = i;
-           if (minv == 0)
-             break;
-       }
+      return(MR_SUCCESS);
+    if (cachesize < CACHESIZE) {
+       i = (struct item *) malloc(sizeof(struct item));
+       cachesize++;
+    } else {
+       i = cachehead.prev;
+       cachehead.prev = i->prev;
+       i->prev->next = &cachehead;
     }
-    mini->id = id;
-    mini->use = use++;
-    strcpy(mini->name, *name);
-    strcpy(mini->type, type);
-    ncache[hashname(name, type)] = icache[hashid(id, type)] = mini;
-    return(SMS_SUCCESS);
+    strcpy(i->name, *name);
+    strcpy(i->type, type);
+    i->nhash = hashname(*name, type);
+    i->id = id;
+    i->next = cachehead.next;
+    i->prev = &cachehead;
+    cachehead.next->prev = i;
+    cachehead.next = i;
+    return(MR_SUCCESS);
 ##}
 
 
@@ -274,31 +292,28 @@ char *name;
 char *type;
 int id;
 {
-    int minv;
-    struct item *i, *mini;
-
-    i = icache[hashid(id, type)];
-    if (i->id == id &&
-       !strcasecmp(i->type, type) &&
-       !strcmp(i->name, name))
-      return(SMS_SUCCESS);
-    minv = use;
-    if (i)
-      mini = i;
-    else
-      for (i = &cache[0]; i < &cache[CACHESIZE]; i++) {
-         if (i->use < minv) {
-             minv = i->use;
-             mini = i;
-             if (minv == 0)
-               break;
-         }
-      }
-    mini->id = id;
-    mini->use = use++;
-    strcpy(mini->name, name);
-    strcpy(mini->type, type);
-    ncache[hashname(name, type)] = icache[hashid(id, type)] = mini;
+    register struct item *i;
+
+    for (i = cachehead.next; i != &cachehead; i = i->next)
+      if (i->id == id && !strcmp(i->type, type))
+       return(MR_SUCCESS);
+    if (cachesize < CACHESIZE) {
+       i = (struct item *) malloc(sizeof(struct item));
+       cachesize++;
+    } else {
+       i = cachehead.prev;
+       cachehead.prev = i->prev;
+       i->prev->next = &cachehead;
+    }
+    strcpy(i->name, name);
+    strcpy(i->type, type);
+    i->nhash = hashname(name, type);
+    i->id = id;
+    i->next = cachehead.next;
+    i->prev = &cachehead;
+    cachehead.next->prev = i;
+    cachehead.next = i;
+    return(MR_SUCCESS);
 }
 
 
@@ -308,13 +323,18 @@ flush_name(name, type)
 char *name;
 char *type;
 {
-    struct item *i;
-
-    i = ncache[hashname(name, type)];
-    if (i && !strcmp(name, i->name) && !strcasecmp(type, i->type)) {
-       ncache[hashname(name, type)] = NULL;
-       icache[hashid(i->id, type)] = NULL;
-       i->use = 0;
-       return(SMS_SUCCESS);
+    int h;
+    register struct item *i;
+
+    h = hashname(name, type);
+
+    for (i = cachehead.next; i != &cachehead; i = i->next) {
+       if (!strcmp(name, i->name) && !strcasecmp(type, i->type)) {
+           cachesize--;
+           i->next->prev = i->prev;
+           i->prev->next = i->next;
+           free(i);
+           return(MR_SUCCESS);
+       }
     }
 }
This page took 0.047606 seconds and 4 git commands to generate.