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 used to be commit c2eff8ef1b
)
This commit is contained in:
parent
58a1460330
commit
f1688d61df
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user