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; * -------------------------------------------------------------------------- **
char *path; */
char *name;
char *dname;
int snum;
} *dir_cache = NULL;
/******************************************************************* #include "ubi_dLinkList.h"
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; typedef struct
entry->prev = NULL; {
if (entry->next) entry->next->prev = entry; ubi_dlNode node;
dir_cache = entry; char *path;
char *name;
char *dname;
int snum;
} dir_cache_entry;
DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname)); static ubi_dlList dir_cache[1] = { { NULL, NULL, 0 } };
if (dir_cache_size == DIRCACHESIZE) { void DirCacheAdd( char *path, char *name, char *dname, int snum )
for (entry=dir_cache, count=1; /* ------------------------------------------------------------------------ **
entry->next && count < dir_cache_size + 1; * Add an entry to the directory cache.
entry=entry->next, count++) ; *
if (entry->next || count != dir_cache_size + 1) { * Input: path -
DEBUG(0,("DirCache bug - please report %d %d\n",dir_cache_size,count)); * 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;
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 );
}
} }
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)
{
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);
}
}
return(NULL); return(NULL);
} } /* DirCacheCheck */
/******************************************************************* void DirCacheFlush( int snum )
flush entries in the dir_cache /* ------------------------------------------------------------------------ **
********************************************************************/ * Remove all cache entries which have an snum that matches the input.
void DirCacheFlush(int snum) *
{ * Input: snum -
struct dir_cache *entry,*next; *
* Output: None.
*
* ------------------------------------------------------------------------ **
*/
{
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