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:
parent
a88ae60fc3
commit
1dafef8887
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user