Made changes to the dir cache functions:
authorChristopher R. Hertel <crh@samba.org>
Thu, 16 Oct 1997 01:03:18 +0000 (01:03 +0000)
committerChristopher R. Hertel <crh@samba.org>
Thu, 16 Oct 1997 01:03:18 +0000 (01:03 +0000)
- They now use the ubi_dLinkList linked list code.
  This is not a big gain, I suppose.  It would be significant if there
  were lots of doubly-linked lists in the code and I replaced them all.
  The only other advantage is that the code is more modular, which
  appeals to my own sense of order, if no one elses.  :-}
- I allocate space for the entry structure and the strings in one go,
  instead of using malloc() and separate strdup() calls.  This should
  be more efficient, and allows for a single call to free() to free the
  whole thing.
These are very minor changes, but they do serve to make me more familiar
with the code overall.
(This used to be commit 1dafef88871338f06dbcbbb67ce3bbbb460d7bb6)

source3/smbd/dir.c

index 316b58818fd942adb76c96e2e22c9c9b15245783..d69ccfe1c190e5de88dc767674abe5c49dc4bfcb 100644 (file)
@@ -628,97 +628,135 @@ int TellDir(void *p)
 }
 
 
-static int dir_cache_size = 0;
-static struct dir_cache {
-  struct dir_cache *next;
-  struct dir_cache *prev;
-  char *path;
-  char *name;
-  char *dname;
-  int snum;
-} *dir_cache = NULL;
+/* -------------------------------------------------------------------------- **
+ * This section manages a global directory cache.
+ * (It should probably be split into a separate module.  crh)
+ * -------------------------------------------------------------------------- **
+ */
 
-/*******************************************************************
-add an entry to the directory cache
-********************************************************************/
-void DirCacheAdd(char *path,char *name,char *dname,int snum)
-{
-  int count;
-  struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry));
-  if (!entry) return;
-  entry->path = strdup(path);
-  entry->name = strdup(name);
-  entry->dname = strdup(dname);
-  entry->snum = snum;
-  if (!entry->path || !entry->name || !entry->dname) return;
-
-  entry->next = dir_cache;
-  entry->prev = NULL;
-  if (entry->next) entry->next->prev = entry;
-  dir_cache = entry;
-
-  DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname));
-  
-  if (dir_cache_size == DIRCACHESIZE) {
-    for (entry=dir_cache, count=1; 
-        entry->next && count < dir_cache_size + 1; 
-        entry=entry->next, count++) ;
-    if (entry->next || count != dir_cache_size + 1) {
-      DEBUG(0,("DirCache bug - please report %d %d\n",dir_cache_size,count));
-    }
-    free(entry->path);
-    free(entry->name);
-    free(entry->dname);
-    if (entry->prev) entry->prev->next = entry->next;
-    free(entry);
-  } else {
-    dir_cache_size++;
-  }
-}
+#include "ubi_dLinkList.h"
 
+typedef struct
+  {
+  ubi_dlNode  node;
+  char       *path;
+  char       *name;
+  char       *dname;
+  int         snum;
+  } dir_cache_entry;
+
+static ubi_dlList dir_cache[1] = { { NULL, NULL, 0 } };
+
+void DirCacheAdd( char *path, char *name, char *dname, int snum )
+  /* ------------------------------------------------------------------------ **
+   * Add an entry to the directory cache.
+   *
+   *  Input:  path  -
+   *          name  -
+   *          dname -
+   *          snum  -
+   *
+   *  Output: None.
+   *
+   * ------------------------------------------------------------------------ **
+   */
+  {
+  int               pathlen;
+  int               namelen;
+  dir_cache_entry  *entry;
+
+  /* Allocate the structure & string space in one go so that it can be freed
+   * in one call to free().
+   */
+  pathlen = strlen( path ) +1;  /* Bytes required to store path (with nul). */
+  namelen = strlen( name ) +1;  /* Bytes required to store name (with nul). */
+  entry = (dir_cache_entry *)malloc( sizeof( dir_cache_entry )
+                                   + pathlen
+                                   + namelen
+                                   + strlen( dname ) +1 );
+  if( NULL == entry )   /* Not adding to the cache is not fatal,  */
+    return;             /* so just return as if nothing happened. */
+
+  /* Set pointers correctly and load values. */
+  entry->path  = strcpy( (char *)&entry[1],       path);
+  entry->name  = strcpy( &(entry->path[pathlen]), name);
+  entry->dname = strcpy( &(entry->name[namelen]), dname);
+  entry->snum  = snum;
+
+  /* Add the new entry to the linked list. */
+  (void)ubi_dlAddHead( dir_cache, entry );
+  DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
+
+  /* Free excess cache entries. */
+  while( DIRCACHESIZE < dir_cache->count )
+    free( ubi_dlRemTail( dir_cache ) );
+
+  } /* DirCacheAdd */
+
+
+char *DirCacheCheck( char *path, char *name, int snum )
+  /* ------------------------------------------------------------------------ **
+   * Search for an entry to the directory cache.
+   *
+   *  Input:  path  -
+   *          name  -
+   *          snum  -
+   *
+   *  Output: The dname string of the located entry, or NULL if the entry was
+   *          not found.
+   *
+   *  Notes:  This uses a linear search, which is is okay because of
+   *          the small size of the cache.  Use a splay tree or hash
+   *          for large caches.
+   *
+   * ------------------------------------------------------------------------ **
+   */
+  {
+  dir_cache_entry *entry;
 
-/*******************************************************************
-check for an entry in the directory cache
-********************************************************************/
-char *DirCacheCheck(char *path,char *name,int snum)
-{
-  struct dir_cache *entry;
-
-  for (entry=dir_cache; entry; entry=entry->next) {
-    if (entry->snum == snum &&
-       strcmp(path,entry->path) == 0 &&
-       strcmp(name,entry->name) == 0) {
-      DEBUG(4,("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
-      return(entry->dname);
+  for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
+       NULL != entry;
+       entry = (dir_cache_entry *)ubi_dlNext( entry ) )
+    {
+    if( entry->snum == snum
+        && 0 == strcmp( name, entry->name )
+        && 0 == strcmp( path, entry->path ) )
+      {
+      DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
+      return( entry->dname );
+      }
     }
-  }
 
   return(NULL);
-}
+  } /* DirCacheCheck */
+
+void DirCacheFlush( int snum )
+  /* ------------------------------------------------------------------------ **
+   * Remove all cache entries which have an snum that matches the input.
+   *
+   *  Input:  snum  -
+   *
+   *  Output: None.
+   *
+   * ------------------------------------------------------------------------ **
+   */
+  {
+  dir_cache_entry *entry;
+  ubi_dlNodePtr    next;
 
-/*******************************************************************
-flush entries in the dir_cache
-********************************************************************/
-void DirCacheFlush(int snum)
-{
-  struct dir_cache *entry,*next;
-
-  for (entry=dir_cache; entry; entry=next) {
-    if (entry->snum == snum) {
-      free(entry->path);
-      free(entry->dname);
-      free(entry->name);
-      next = entry->next;
-      if (entry->prev) entry->prev->next = entry->next;
-      if (entry->next) entry->next->prev = entry->prev;
-      if (dir_cache == entry) dir_cache = entry->next; 
-      free(entry);
-      dir_cache_size--;
-    } else {
-      next = entry->next;
+  for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); NULL != entry; )
+    {
+    next = ubi_dlNext( entry );
+    if( entry->snum == snum )
+      free( ubi_dlRemThis( dir_cache, entry ) );
+    entry = (dir_cache_entry *)next;
     }
-  }
-}
+  } /* DirCacheFlush */
+
+/* -------------------------------------------------------------------------- **
+ * End of the section that manages the global directory cache.
+ * -------------------------------------------------------------------------- **
+ */
 
 
 #ifdef REPLACE_GETWD