1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-27 03:21:53 +03:00

Made changes to the dir cache functions:

- 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 commit is contained in:
Christopher R. Hertel 0001-01-01 00:00:00 +00:00
parent a88ae60fc3
commit 1dafef8887

View File

@ -628,97 +628,135 @@ int TellDir(void *p)
} }
static int dir_cache_size = 0; /* -------------------------------------------------------------------------- **
static struct dir_cache { * This section manages a global directory cache.
struct dir_cache *next; * (It should probably be split into a separate module. crh)
struct dir_cache *prev; * -------------------------------------------------------------------------- **
*/
#include "ubi_dLinkList.h"
typedef struct
{
ubi_dlNode node;
char *path; char *path;
char *name; char *name;
char *dname; char *dname;
int snum; int snum;
} *dir_cache = NULL; } dir_cache_entry;
static ubi_dlList dir_cache[1] = { { NULL, NULL, 0 } };
/*******************************************************************
add an entry to the directory cache
********************************************************************/
void DirCacheAdd( char *path, char *name, char *dname, int snum ) 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 count; int pathlen;
struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry)); int namelen;
if (!entry) return; dir_cache_entry *entry;
entry->path = strdup(path);
entry->name = strdup(name); /* Allocate the structure & string space in one go so that it can be freed
entry->dname = strdup(dname); * 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; 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;
/* 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 ) ); DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
if (dir_cache_size == DIRCACHESIZE) { /* Free excess cache entries. */
for (entry=dir_cache, count=1; while( DIRCACHESIZE < dir_cache->count )
entry->next && count < dir_cache_size + 1; free( ubi_dlRemTail( dir_cache ) );
entry=entry->next, count++) ;
if (entry->next || count != dir_cache_size + 1) { } /* DirCacheAdd */
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++;
}
}
/*******************************************************************
check for an entry in the directory cache
********************************************************************/
char *DirCacheCheck( char *path, char *name, int snum ) 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.
*
* ------------------------------------------------------------------------ **
*/
{ {
struct dir_cache *entry; dir_cache_entry *entry;
for (entry=dir_cache; entry; entry=entry->next) { for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
if (entry->snum == snum && NULL != entry;
strcmp(path,entry->path) == 0 && entry = (dir_cache_entry *)ubi_dlNext( entry ) )
strcmp(name,entry->name) == 0) { {
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)); DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
return( entry->dname ); return( entry->dname );
} }
} }
return(NULL); return(NULL);
} } /* DirCacheCheck */
/*******************************************************************
flush entries in the dir_cache
********************************************************************/
void DirCacheFlush( int snum ) void DirCacheFlush( int snum )
/* ------------------------------------------------------------------------ **
* Remove all cache entries which have an snum that matches the input.
*
* Input: snum -
*
* Output: None.
*
* ------------------------------------------------------------------------ **
*/
{ {
struct dir_cache *entry,*next; dir_cache_entry *entry;
ubi_dlNodePtr next;
for (entry=dir_cache; entry; entry=next) { for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); NULL != entry; )
if (entry->snum == snum) { {
free(entry->path); next = ubi_dlNext( entry );
free(entry->dname); if( entry->snum == snum )
free(entry->name); free( ubi_dlRemThis( dir_cache, entry ) );
next = entry->next; entry = (dir_cache_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;
}
}
} }
} /* DirCacheFlush */
/* -------------------------------------------------------------------------- **
* End of the section that manages the global directory cache.
* -------------------------------------------------------------------------- **
*/
#ifdef REPLACE_GETWD #ifdef REPLACE_GETWD