1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r2112: Simplify the mangle hash code to use an in-memory tdb.

Should be ready for the new directory code now...
Jeremy.
This commit is contained in:
Jeremy Allison 2004-08-30 20:19:40 +00:00 committed by Gerald (Jerry) Carter
parent 3f0707132a
commit c2eff8ef1b
4 changed files with 59 additions and 167 deletions

View File

@ -397,7 +397,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(LIBMSRPC_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
$(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
printing/print_cups.o printing/print_generic.o \

View File

@ -132,7 +132,7 @@ END {
gotstart = 1;
}
if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP/ ) {
if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP|^u32/ ) {
gotstart = 1;
}

View File

@ -85,23 +85,6 @@
* if that character is in the illegal characters set.
* This is faster than using strchr_m().
*
* mangled_cache - Cache header used for storing mangled -> original
* reverse maps.
*
* mc_initialized - False until the mangled_cache structure has been
* initialized via a call to reset_mangled_cache().
*
* MANGLED_CACHE_MAX_ENTRIES - Default maximum number of entries for the
* cache. A value of 0 indicates "infinite".
*
* MANGLED_CACHE_MAX_MEMORY - Default maximum amount of memory for the
* cache. When the cache was kept as an array of 256
* byte strings, the default cache size was 50 entries.
* This required a fixed 12.5Kbytes of memory. The
* mangled stack parameter is no longer used (though
* this might change). We're now using a fixed 16Kbyte
* maximum cache size. This will probably be much more
* than 50 entries.
*/
char magic_char = '~';
@ -118,10 +101,7 @@ static BOOL ct_initialized = False;
#define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
static BOOL mc_initialized = False;
#define MANGLED_CACHE_MAX_ENTRIES 1024
#define MANGLED_CACHE_MAX_MEMORY 0
static TDB_CONTEXT *tdb_mangled_cache;
/* -------------------------------------------------------------------- */
@ -400,157 +380,69 @@ static BOOL is_mangled(const char *s)
return( False );
}
/* ************************************************************************** **
* Compare two cache keys and return a value indicating their ordinal
* relationship.
*
* Input: ItemPtr - Pointer to a comparison key. In this case, this will
* be a mangled name string.
* NodePtr - Pointer to a node in the cache. The node structure
* will be followed in memory by a mangled name string.
*
* Output: A signed integer, as follows:
* (x < 0) <==> Key1 less than Key2
* (x == 0) <==> Key1 equals Key2
* (x > 0) <==> Key1 greater than Key2
*
* Notes: This is a ubiqx-style comparison routine. See ubi_BinTree for
* more info.
*
* ************************************************************************** **
*/
static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
{
char *Key1 = (char *)ItemPtr;
char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1);
return( StrCaseCmp( Key1, Key2 ) );
}
/* ************************************************************************** **
* Free a cache entry.
*
* Input: WarrenZevon - Pointer to the entry that is to be returned to
* Nirvana.
* Output: none.
*
* Notes: This function gets around the possibility that the standard
* free() function may be implemented as a macro, or other evil
* subversions (oh, so much fun).
*
* ************************************************************************** **
*/
static void cache_free_entry( ubi_trNodePtr WarrenZevon )
{
ZERO_STRUCTP(WarrenZevon);
SAFE_FREE( WarrenZevon );
}
/* ************************************************************************** **
* Initializes or clears the mangled cache.
*
* Input: none.
* Output: none.
*
* Notes: There is a section below that is commented out. It shows how
* one might use lp_ calls to set the maximum memory and entry size
* of the cache. You might also want to remove the constants used
* in ubi_cacheInit() and replace them with lp_ calls. If so, then
* the calls to ubi_cacheSetMax*() would be moved into the else
* clause. Another option would be to pass in the max_entries and
* max_memory values as parameters. crh 09-Apr-1998.
*
* ************************************************************************** **
*/
/***************************************************************************
Initializes or clears the mangled cache.
***************************************************************************/
static void mangle_reset( void )
{
if( !mc_initialized ) {
(void)ubi_cacheInit( mangled_cache,
cache_compare,
cache_free_entry,
MANGLED_CACHE_MAX_ENTRIES,
MANGLED_CACHE_MAX_MEMORY );
mc_initialized = True;
} else {
(void)ubi_cacheClear( mangled_cache );
}
/*
(void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
(void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
*/
/* We could close and re-open the tdb here... should we ? The old code did
the equivalent... JRA. */
}
/* ************************************************************************** **
* Add a mangled name into the cache.
*
* Notes: If the mangled cache has not been initialized, then the
* function will simply fail. It could initialize the cache,
* but that's not the way it was done before I changed the
* cache mechanism, so I'm sticking with the old method.
*
* If the extension of the raw name maps directly to the
* extension of the mangled name, then we'll store both names
* *without* extensions. That way, we can provide consistent
* reverse mangling for all names that match. The test here is
* a bit more careful than the one done in earlier versions of
* mangle.c:
*
* - the extension must exist on the raw name,
* - it must be all lower case
* - it must match the mangled extension (to prove that no
* mangling occurred).
*
* crh 07-Apr-1998
*
* ************************************************************************** **
*/
static void cache_mangled_name( char *mangled_name, char *raw_name )
/***************************************************************************
Add a mangled name into the cache.
If the extension of the raw name maps directly to the
extension of the mangled name, then we'll store both names
*without* extensions. That way, we can provide consistent
reverse mangling for all names that match. The test here is
a bit more careful than the one done in earlier versions of
mangle.c:
- the extension must exist on the raw name,
- it must be all lower case
- it must match the mangled extension (to prove that no
mangling occurred).
crh 07-Apr-1998
**************************************************************************/
static void cache_mangled_name( const char mangled_name[13], char *raw_name )
{
ubi_cacheEntryPtr new_entry;
char *s1;
char *s2;
size_t mangled_len;
size_t raw_len;
size_t i;
TDB_DATA data_val;
char mangled_name_key[13];
char *s1;
char *s2;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
if( !tdb_mangled_cache )
return;
/* Init the string lengths. */
mangled_len = strlen( mangled_name );
raw_len = strlen( raw_name );
safe_strcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key)-1);
/* See if the extensions are unmangled. If so, store the entry
* without the extension, thus creating a "group" reverse map.
*/
s1 = strrchr( mangled_name, '.' );
s1 = strrchr( mangled_name_key, '.' );
if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
i = 1;
size_t i = 1;
while( s1[i] && (tolower( s1[i] ) == s2[i]) )
i++;
if( !s1[i] && !s2[i] ) {
mangled_len -= i;
raw_len -= i;
/* Truncate at the '.' */
*s1 = '\0';
*s2 = '\0';
}
}
/* Allocate a new cache entry. If the allocation fails, just return. */
i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
new_entry = malloc( i );
if( !new_entry )
return;
/* Fill the new cache entry, and add it to the cache. */
s1 = (char *)(new_entry + 1);
s2 = (char *)&(s1[mangled_len + 1]);
memcpy( s1, mangled_name, mangled_len );
s1[mangled_len] = '\0';
memcpy( s2, raw_name, raw_len );
s2[raw_len] = '\0';
ubi_cachePut( mangled_cache, i, new_entry, s1 );
data_val.dptr = raw_name;
data_val.dsize = strlen(raw_name)+1;
if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) {
DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name));
} else {
DEBUG(5,("cache_mangled_name: Stored entry %s -> %s\n", mangled_name_key, raw_name));
}
}
/* ************************************************************************** **
@ -570,26 +462,25 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
static BOOL check_cache( char *s, size_t maxlen )
{
ubi_cacheEntryPtr FoundPtr;
char *ext_start = NULL;
char *found_name;
char *saved_ext = NULL;
TDB_DATA data_val;
char *ext_start = NULL;
char *saved_ext = NULL;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
if( !tdb_mangled_cache )
return( False );
FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
/* If we didn't find the name *with* the extension, try without. */
if( !FoundPtr ) {
if(data_val.dptr == NULL || data_val.dsize == 0) {
ext_start = strrchr( s, '.' );
if( ext_start ) {
if((saved_ext = strdup(ext_start)) == NULL)
return False;
*ext_start = '\0';
FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
/*
* At this point s is the name without the
* extension. We re-add the extension if saved_ext
@ -599,7 +490,7 @@ static BOOL check_cache( char *s, size_t maxlen )
}
/* Okay, if we haven't found it we're done. */
if( !FoundPtr ) {
if(data_val.dptr == NULL || data_val.dsize == 0) {
if(saved_ext) {
/* Replace the saved_ext as it was truncated. */
(void)safe_strcat( s, saved_ext, maxlen );
@ -609,16 +500,13 @@ static BOOL check_cache( char *s, size_t maxlen )
}
/* If we *did* find it, we need to copy it into the string buffer. */
found_name = (char *)(FoundPtr + 1);
found_name += (strlen( found_name ) + 1);
(void)safe_strcpy( s, found_name, maxlen );
(void)safe_strcpy( s, data_val.dptr, maxlen );
if( saved_ext ) {
/* Replace the saved_ext as it was truncated. */
(void)safe_strcat( s, saved_ext, maxlen );
SAFE_FREE(saved_ext);
}
SAFE_FREE(data_val.dptr);
return( True );
}
@ -767,5 +655,9 @@ struct mangle_fns *mangle_hash_init(void)
{
mangle_reset();
/* Create the in-memory tdb using our custom hash function. */
tdb_mangled_cache = tdb_open_ex("mangled_cache", 1031, TDB_INTERNAL,
(O_RDWR|O_CREAT), 0644, NULL, fast_string_hash);
return &mangle_fns;
}

View File

@ -286,7 +286,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
JRA. Use a djb-algorithm hash for speed.
***************************************************************/
static u32 string_hash(TDB_DATA *key)
u32 fast_string_hash(TDB_DATA *key)
{
u32 n = 0;
const char *p;
@ -311,7 +311,7 @@ BOOL reset_stat_cache( void )
/* Create the in-memory tdb using our custom hash function. */
tdb_stat_cache = tdb_open_ex("statcache", 0, TDB_INTERNAL,
(O_RDWR|O_CREAT), 0644, NULL, string_hash);
(O_RDWR|O_CREAT), 0644, NULL, fast_string_hash);
if (!tdb_stat_cache)
return False;