Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
memcache.c File Reference
#include <assert.h>
#include "ldap-int.h"

Go to the source code of this file.

Classes

struct  HashTableNode_struct
struct  HashTable_struct
struct  ldapmemcacheReqId_struct
struct  ldapmemcacheld_struct
struct  ldapmemcacheRes_struct
struct  ldapmemcacheStats_struct
struct  ldapmemcache

Defines

#define EXTRA_SIZE   1024
#define MEMCACHE_ACCESS_ADD   0
#define MEMCACHE_ACCESS_APPEND   1
#define MEMCACHE_ACCESS_APPEND_LAST   2
#define MEMCACHE_ACCESS_FIND   3
#define MEMCACHE_ACCESS_DELETE   4
#define MEMCACHE_ACCESS_DELETE_ALL   5
#define MEMCACHE_ACCESS_UPDATE   6
#define MEMCACHE_ACCESS_FLUSH   7
#define MEMCACHE_ACCESS_FLUSH_ALL   8
#define MEMCACHE_ACCESS_FLUSH_LRU   9
#define MEMCACHE_SIZE_DEDUCT   0
#define MEMCACHE_SIZE_ADD   1
#define MEMCACHE_SIZE_ENTRIES   1
#define MEMCACHE_SIZE_NON_ENTRIES   2
#define MEMCACHE_DEF_SIZE   131072 /* 128K bytes */
#define LIST_TTL   0
#define LIST_LRU   1
#define LIST_TMP   2
#define LIST_TOTAL   3
#define NSLDAPI_VALID_MEMCACHE_POINTER(cp)   ( (cp) != NULL )
#define NSLDAPI_STR_NONNULL(s)   ( (s) ? (s) : "" )
#define NSLDAPI_SAFE_STRLEN(s)   ( (s) ? strlen((s)) + 1 : 1 )
#define LDAP_MEMCACHE_MUTEX_LOCK(c)
#define LDAP_MEMCACHE_MUTEX_UNLOCK(c)
#define LDAP_MEMCACHE_MUTEX_ALLOC(c)
#define LDAP_MEMCACHE_MUTEX_FREE(c)
#define NSLDAPI_IS_SPACE(c)   (((c) == ' ') || ((c) == '\t') || ((c) == '\n'))
#define NSLDAPI_IS_SEPARATER(c)   ((c) == ',')
#define NSLDAPI_CRC32_POLY   0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */

Typedefs

typedef int(* HashFuncPtr )(int table_size, void *key)
typedef int(* PutDataPtr )(void **ppTableData, void *key, void *pData)
typedef int(* GetDataPtr )(void *pTableData, void *key, void **ppData)
typedef int(* RemoveDataPtr )(void **ppTableData, void *key, void **ppData)
typedef int(* MiscFuncPtr )(void **ppTableData, void *key, void *pData)
typedef void(* ClrTableNodePtr )(void **ppTableData, void *pData)
typedef struct HashTableNode_struct HashTableNode
typedef struct HashTable_struct HashTable
typedef struct
ldapmemcacheReqId_struct 
ldapmemcacheReqId
typedef struct
ldapmemcacheld_struct 
ldapmemcacheld
typedef struct
ldapmemcacheRes_struct 
ldapmemcacheRes
typedef struct
ldapmemcacheStats_struct 
ldapmemcacheStats

Functions

static int memcache_exist (LDAP *ld)
static int memcache_add_to_ld (LDAP *ld, int msgid, LDAPMessage *pMsg)
static int memcache_compare_dn (const char *main_dn, const char *dn, int scope)
static int memcache_dup_message (LDAPMessage *res, int msgid, int fromcache, LDAPMessage **ppResCopy, unsigned long *pSize)
static BerElement * memcache_ber_dup (BerElement *pBer, unsigned long *pSize)
static void memcache_trim_basedn_spaces (char *basedn)
static int memcache_validate_basedn (LDAPMemCache *cache, const char *basedn)
static int memcache_get_ctrls_len (LDAPControl **ctrls)
static void memcache_append_ctrls (char *buf, LDAPControl **serverCtrls, LDAPControl **clientCtrls)
static int memcache_adj_size (LDAPMemCache *cache, unsigned long size, int usageFlags, int bAdd)
static int memcache_free_entry (LDAPMemCache *cache, ldapmemcacheRes *pRes)
static int memcache_expired (LDAPMemCache *cache, ldapmemcacheRes *pRes, unsigned long curTime)
static int memcache_add_to_list (LDAPMemCache *cache, ldapmemcacheRes *pRes, int index)
static int memcache_add_res_to_list (ldapmemcacheRes *pRes, LDAPMessage *pMsg, unsigned long size)
static int memcache_free_from_list (LDAPMemCache *cache, ldapmemcacheRes *pRes, int index)
static int memcache_search (LDAP *ld, unsigned long key, LDAPMessage **ppRes)
static int memcache_add (LDAP *ld, unsigned long key, int msgid, const char *basedn)
static int memcache_append (LDAP *ld, int msgid, LDAPMessage *pRes)
static int memcache_append_last (LDAP *ld, int msgid, LDAPMessage *pRes)
static int memcache_remove (LDAP *ld, int msgid)
static int memcache_access (LDAPMemCache *cache, int mode, void *pData1, void *pData2, void *pData3)
static int htable_calculate_size (int sizelimit)
static int htable_sizeinbytes (HashTable *pTable)
static int htable_put (HashTable *pTable, void *key, void *pData)
static int htable_get (HashTable *pTable, void *key, void **ppData)
static int htable_misc (HashTable *pTable, void *key, void *pData)
static int htable_remove (HashTable *pTable, void *key, void **ppData)
static int htable_removeall (HashTable *pTable, void *pData)
static int htable_create (int size_limit, HashFuncPtr hashf, PutDataPtr putDataf, GetDataPtr getDataf, RemoveDataPtr removeDataf, ClrTableNodePtr clrNodef, MiscFuncPtr miscOpf, HashTable **ppTable)
static int htable_free (HashTable *pTable)
static int msgid_hashf (int table_size, void *key)
static int msgid_putdata (void **ppTableData, void *key, void *pData)
static int msgid_getdata (void *pTableData, void *key, void **ppData)
static int msgid_removedata (void **ppTableData, void *key, void **ppData)
static int msgid_clear_ld_items (void **ppTableData, void *key, void *pData)
static void msgid_clearnode (void **ppTableData, void *pData)
static int attrkey_hashf (int table_size, void *key)
static int attrkey_putdata (void **ppTableData, void *key, void *pData)
static int attrkey_getdata (void *pTableData, void *key, void **ppData)
static int attrkey_removedata (void **ppTableData, void *key, void **ppData)
static void attrkey_clearnode (void **ppTableData, void *pData)
static unsigned long crc32_convert (char *buf, int len)
int LDAP_CALL ldap_memcache_init (unsigned long ttl, unsigned long size, char **baseDNs, struct ldap_thread_fns *thread_fns, LDAPMemCache **cachep)
int LDAP_CALL ldap_memcache_set (LDAP *ld, LDAPMemCache *cache)
int LDAP_CALL ldap_memcache_get (LDAP *ld, LDAPMemCache **cachep)
void LDAP_CALL ldap_memcache_update (LDAPMemCache *cache)
void LDAP_CALL ldap_memcache_flush (LDAPMemCache *cache, char *dn, int scope)
void LDAP_CALL ldap_memcache_destroy (LDAPMemCache *cache)
int ldap_memcache_createkey (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, unsigned long *keyp)
int ldap_memcache_result (LDAP *ld, int msgid, unsigned long key)
int ldap_memcache_new (LDAP *ld, int msgid, unsigned long key, const char *basedn)
int ldap_memcache_append (LDAP *ld, int msgid, int bLast, LDAPMessage *result)
int ldap_memcache_abandon (LDAP *ld, int msgid)

Variables

static unsigned long crc32_table [256]

Class Documentation

struct HashTableNode_struct

Definition at line 123 of file memcache.c.

Class Members
void * pData
struct HashTable_struct

Definition at line 128 of file memcache.c.

Collaboration diagram for HashTable_struct:
Class Members
ClrTableNodePtr clrtablenode
GetDataPtr getdata
HashFuncPtr hashfunc
MiscFuncPtr miscfunc
PutDataPtr putdata
RemoveDataPtr removedata
int size
HashTableNode * table
struct ldapmemcacheReqId_struct

Definition at line 140 of file memcache.c.

Collaboration diagram for ldapmemcacheReqId_struct:
Class Members
LDAP * ldmemcrid_ld
int ldmemcrid_msgid
struct ldapmemcacheld_struct

Definition at line 146 of file memcache.c.

Collaboration diagram for ldapmemcacheld_struct:
Class Members
LDAP * ldmemcl_ld
struct ldapmemcacheld_struct * ldmemcl_next
struct ldapmemcacheRes_struct

Definition at line 152 of file memcache.c.

Collaboration diagram for ldapmemcacheRes_struct:
Class Members
char * ldmemcr_basedn
unsigned long ldmemcr_crc_key
struct ldapmemcacheRes_struct * ldmemcr_htable_next
struct ldapmemcacheRes_struct * ldmemcr_next
struct ldapmemcacheRes_struct * ldmemcr_prev
ldapmemcacheReqId ldmemcr_req_id
LDAPMessage * ldmemcr_resHead
unsigned long ldmemcr_resSize
LDAPMessage * ldmemcr_resTail
unsigned long ldmemcr_timestamp
struct ldapmemcacheStats_struct

Definition at line 166 of file memcache.c.

Class Members
unsigned long ldmemcstat_hits
unsigned long ldmemcstat_tries
struct ldapmemcache

Definition at line 172 of file memcache.c.

Collaboration diagram for ldapmemcache:
Class Members
char ** ldmemc_basedns
ldapmemcacheld * ldmemc_lds
void * ldmemc_lock
ldapmemcacheRes * ldmemc_resHead
HashTable * ldmemc_resLookup
ldapmemcacheRes * ldmemc_resTail
HashTable * ldmemc_resTmp
unsigned long ldmemc_size
unsigned long ldmemc_size_entries
unsigned long ldmemc_size_used
ldapmemcacheStats ldmemc_stats
unsigned long ldmemc_ttl

Define Documentation

#define EXTRA_SIZE   1024

Definition at line 52 of file memcache.c.

Value:
((c) && ((c)->ldmemc_lock_fns).ltf_mutex_alloc ? \
           ((c)->ldmemc_lock_fns).ltf_mutex_alloc() : NULL)

Definition at line 98 of file memcache.c.

Value:
if ( (c) && ((c)->ldmemc_lock_fns).ltf_mutex_free ) { \
           ((c)->ldmemc_lock_fns).ltf_mutex_free( (c)->ldmemc_lock ); \
       }

Definition at line 102 of file memcache.c.

Value:
if ( (c) && ((c)->ldmemc_lock_fns).ltf_mutex_lock ) { \
           ((c)->ldmemc_lock_fns).ltf_mutex_lock( (c)->ldmemc_lock ); \
       }

Definition at line 88 of file memcache.c.

Value:
if ( (c) && ((c)->ldmemc_lock_fns).ltf_mutex_unlock ) { \
           ((c)->ldmemc_lock_fns).ltf_mutex_unlock( (c)->ldmemc_lock ); \
       }

Definition at line 93 of file memcache.c.

#define LIST_LRU   1

Definition at line 78 of file memcache.c.

#define LIST_TMP   2

Definition at line 79 of file memcache.c.

#define LIST_TOTAL   3

Definition at line 80 of file memcache.c.

#define LIST_TTL   0

Definition at line 77 of file memcache.c.

Definition at line 55 of file memcache.c.

Definition at line 56 of file memcache.c.

Definition at line 57 of file memcache.c.

Definition at line 59 of file memcache.c.

Definition at line 60 of file memcache.c.

Definition at line 58 of file memcache.c.

Definition at line 62 of file memcache.c.

Definition at line 63 of file memcache.c.

Definition at line 64 of file memcache.c.

Definition at line 61 of file memcache.c.

#define MEMCACHE_DEF_SIZE   131072 /* 128K bytes */

Definition at line 74 of file memcache.c.

Definition at line 68 of file memcache.c.

Definition at line 67 of file memcache.c.

Definition at line 70 of file memcache.c.

Definition at line 71 of file memcache.c.

#define NSLDAPI_CRC32_POLY   0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */

Definition at line 2137 of file memcache.c.

#define NSLDAPI_IS_SEPARATER (   c)    ((c) == ',')

Definition at line 111 of file memcache.c.

#define NSLDAPI_IS_SPACE (   c)    (((c) == ' ') || ((c) == '\t') || ((c) == '\n'))

Definition at line 108 of file memcache.c.

#define NSLDAPI_SAFE_STRLEN (   s)    ( (s) ? strlen((s)) + 1 : 1 )

Definition at line 85 of file memcache.c.

#define NSLDAPI_STR_NONNULL (   s)    ( (s) ? (s) : "" )

Definition at line 84 of file memcache.c.

Definition at line 83 of file memcache.c.


Typedef Documentation

typedef void(* ClrTableNodePtr)(void **ppTableData, void *pData)

Definition at line 120 of file memcache.c.

typedef int(* GetDataPtr)(void *pTableData, void *key, void **ppData)

Definition at line 117 of file memcache.c.

typedef int(* HashFuncPtr)(int table_size, void *key)

Definition at line 115 of file memcache.c.

typedef struct HashTable_struct HashTable
typedef int(* MiscFuncPtr)(void **ppTableData, void *key, void *pData)

Definition at line 119 of file memcache.c.

typedef int(* PutDataPtr)(void **ppTableData, void *key, void *pData)

Definition at line 116 of file memcache.c.

typedef int(* RemoveDataPtr)(void **ppTableData, void *key, void **ppData)

Definition at line 118 of file memcache.c.


Function Documentation

static void attrkey_clearnode ( void **  ppTableData,
void pData 
) [static]

Definition at line 2117 of file memcache.c.

{
    ldapmemcacheRes **ppHead = (ldapmemcacheRes**)ppTableData;
    ldapmemcacheRes *pRes = *ppHead;

    (void)pData;

    for (; *ppHead; pRes = *ppHead) {
       ppHead = &((*ppHead)->ldmemcr_htable_next);
       pRes->ldmemcr_htable_next = NULL;
    }
}

Here is the caller graph for this function:

static int attrkey_getdata ( void pTableData,
void key,
void **  ppData 
) [static]

Definition at line 2069 of file memcache.c.

{
    unsigned long attrkey = *((unsigned long*)key);
    ldapmemcacheRes *pRes = (ldapmemcacheRes*)pTableData;
    
    for (; pRes; pRes = pRes->ldmemcr_htable_next) {
       if (pRes->ldmemcr_crc_key == attrkey) {
           *ppData = (void*)pRes;
           return( LDAP_SUCCESS );
       }
    }

    *ppData = NULL;

    return( LDAP_NO_SUCH_OBJECT );
}

Here is the caller graph for this function:

static int attrkey_hashf ( int  table_size,
void key 
) [static]

Definition at line 2042 of file memcache.c.

{
    return ((*((unsigned long*)key)) % table_size);
}

Here is the caller graph for this function:

static int attrkey_putdata ( void **  ppTableData,
void key,
void pData 
) [static]

Definition at line 2049 of file memcache.c.

{
    unsigned long attrkey = *((unsigned long*)key);
    ldapmemcacheRes **ppHead = (ldapmemcacheRes**)ppTableData;
    ldapmemcacheRes *pRes = *ppHead;

    for (; pRes; pRes = pRes->ldmemcr_htable_next) {
       if (pRes->ldmemcr_crc_key == attrkey)
           return( LDAP_ALREADY_EXISTS );
    }

    pRes = (ldapmemcacheRes*)pData;
    pRes->ldmemcr_htable_next = *ppHead;
    *ppHead = pRes;

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int attrkey_removedata ( void **  ppTableData,
void key,
void **  ppData 
) [static]

Definition at line 2088 of file memcache.c.

{
    unsigned long attrkey = *((unsigned long*)key);
    ldapmemcacheRes **ppHead = (ldapmemcacheRes**)ppTableData;
    ldapmemcacheRes *pRes = *ppHead;
    ldapmemcacheRes *pPrev = NULL;
    
    for (; pRes; pRes = pRes->ldmemcr_htable_next) {
       if (pRes->ldmemcr_crc_key == attrkey) {
           if (ppData)
              *ppData = (void*)pRes;
           if (pPrev)
              pPrev->ldmemcr_htable_next = pRes->ldmemcr_htable_next;
           else
              *ppHead = pRes->ldmemcr_htable_next;
           pRes->ldmemcr_htable_next = NULL;
           return( LDAP_SUCCESS );
       }
       pPrev = pRes;
    }

    if (ppData)
       *ppData = NULL;

    return( LDAP_NO_SUCH_OBJECT );
}

Here is the caller graph for this function:

static unsigned long crc32_convert ( char *  buf,
int  len 
) [static]

Definition at line 2189 of file memcache.c.

{
    char *p;
#ifdef OSF1V4D
    unsigned int crc;
#else
    unsigned long crc;          /* FIXME: this is not 32-bits on all platforms! */
#endif /* OSF1V4D */

    crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
    for (p = buf; len > 0; ++p, --len)
       crc = ((crc << 8) ^ crc32_table[(crc >> 24) ^ *p]) & 0xffffffff;

    return (unsigned long) ~crc;    /* transmit complement, per CRC-32 spec */
}

Here is the caller graph for this function:

static int htable_calculate_size ( int  sizelimit) [static]

Definition at line 1707 of file memcache.c.

{
    int i, j;
    int size = (int)(((double)sizelimit / 
                       (double)(sizeof(BerElement) + EXTRA_SIZE)) / 1.5);

    /* Get a prime # */
    size = (size & 0x1 ? size : size + 1);
    for (i = 3, j = size / 2; i < j; i++) {
       if ((size % i) == 0) {
           size += 2;
           i = 3;
           j = size / 2;
       }
    }

    return size;
}

Here is the caller graph for this function:

static int htable_create ( int  size_limit,
HashFuncPtr  hashf,
PutDataPtr  putDataf,
GetDataPtr  getDataf,
RemoveDataPtr  removeDataf,
ClrTableNodePtr  clrNodef,
MiscFuncPtr  miscOpf,
HashTable **  ppTable 
) [static]

Definition at line 1804 of file memcache.c.

{
    size_limit = htable_calculate_size(size_limit);

    if ((*ppTable = (HashTable*)NSLDAPI_CALLOC(1, sizeof(HashTable))) == NULL)
       return( LDAP_NO_MEMORY );

    (*ppTable)->table = (HashTableNode*)NSLDAPI_CALLOC(size_limit, 
                                              sizeof(HashTableNode));
    if ((*ppTable)->table == NULL) {
       NSLDAPI_FREE(*ppTable);
       *ppTable = NULL;
       return( LDAP_NO_MEMORY );
    }

    (*ppTable)->size = size_limit;
    (*ppTable)->hashfunc = hashf;
    (*ppTable)->putdata = putDataf;
    (*ppTable)->getdata = getDataf;
    (*ppTable)->miscfunc = miscOpf;
    (*ppTable)->removedata = removeDataf;
    (*ppTable)->clrtablenode = clrNodef;

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int htable_free ( HashTable pTable) [static]

Definition at line 1835 of file memcache.c.

{
    NSLDAPI_FREE(pTable->table);
    NSLDAPI_FREE(pTable);
    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int htable_get ( HashTable pTable,
void key,
void **  ppData 
) [static]

Definition at line 1750 of file memcache.c.

{
    int index = pTable->hashfunc(pTable->size, key);

    *ppData = NULL;

    if (index >= 0 && index < pTable->size)
       return pTable->getdata(pTable->table[index].pData, key, ppData);

    return( LDAP_OPERATIONS_ERROR );
}

Here is the caller graph for this function:

static int htable_misc ( HashTable pTable,
void key,
void pData 
) [static]

Definition at line 1764 of file memcache.c.

{
    if (pTable->miscfunc) {
       int index = pTable->hashfunc(pTable->size, key);
       if (index >= 0 && index < pTable->size)
           return pTable->miscfunc(&(pTable->table[index].pData), key, pData);
    }

    return( LDAP_OPERATIONS_ERROR );
}

Here is the caller graph for this function:

static int htable_put ( HashTable pTable,
void key,
void pData 
) [static]

Definition at line 1738 of file memcache.c.

{
    int index = pTable->hashfunc(pTable->size, key);

    if (index >= 0 && index < pTable->size)
       return pTable->putdata(&(pTable->table[index].pData), key, pData);

    return( LDAP_OPERATIONS_ERROR );
}

Here is the caller graph for this function:

static int htable_remove ( HashTable pTable,
void key,
void **  ppData 
) [static]

Definition at line 1777 of file memcache.c.

{
    int index = pTable->hashfunc(pTable->size, key);

    if (ppData)
       *ppData = NULL;

    if (index >= 0 && index < pTable->size)
       return pTable->removedata(&(pTable->table[index].pData), key, ppData);

    return( LDAP_OPERATIONS_ERROR );
}

Here is the caller graph for this function:

static int htable_removeall ( HashTable pTable,
void pData 
) [static]

Definition at line 1792 of file memcache.c.

{
    int i;

    for (i = 0; i < pTable->size; i++)
       pTable->clrtablenode(&(pTable->table[i].pData), pData);

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int htable_sizeinbytes ( HashTable pTable) [static]

Definition at line 1728 of file memcache.c.

{
    if (!pTable)
       return 0;

    return (pTable->size * sizeof(HashTableNode));
}

Here is the caller graph for this function:

int ldap_memcache_abandon ( LDAP *  ld,
int  msgid 
)

Definition at line 802 of file memcache.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_memcache_append ( LDAP *  ld,
int  msgid,
int  bLast,
LDAPMessage *  result 
)

Definition at line 763 of file memcache.c.

{
    int nRes = LDAP_SUCCESS;

    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_append( ld: 0x%x, ", ld, 0, 0 );
    LDAPDebug( LDAP_DEBUG_TRACE, "msgid %d, bLast: %d, result: 0x%x)\n",
           msgid, bLast, result );

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || !result ) {
       return( LDAP_PARAM_ERROR );
    }

    LDAP_MUTEX_LOCK( ld, LDAP_MEMCACHE_LOCK );

    if (!memcache_exist(ld)) {
        LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );
       return( LDAP_LOCAL_ERROR );
    }

    LDAP_MEMCACHE_MUTEX_LOCK( ld->ld_memcache );

    if (!bLast)
       nRes = memcache_append(ld, msgid, result);
    else
       nRes = memcache_append_last(ld, msgid, result);

    LDAPDebug( LDAP_DEBUG_TRACE,
           "ldap_memcache_append: %s result for msgid %d\n",
           ( nRes == LDAP_SUCCESS ) ? "added" : "failed to add", msgid , 0 );

    LDAP_MEMCACHE_MUTEX_UNLOCK( ld->ld_memcache );
    LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_memcache_createkey ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
unsigned long keyp 
)

Definition at line 586 of file memcache.c.

{
    int nRes, i, j, i_smallest;
    int len;
    int defport;
    char buf[50];
    char *tmp, *defhost, *binddn, *keystr, *tmpbase;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || (keyp == NULL) )
       return( LDAP_PARAM_ERROR );

    *keyp = 0;

    if (!memcache_exist(ld))
       return( LDAP_LOCAL_ERROR );

    LDAP_MUTEX_LOCK( ld, LDAP_MEMCACHE_LOCK );
    LDAP_MEMCACHE_MUTEX_LOCK( ld->ld_memcache );
    nRes = memcache_validate_basedn(ld->ld_memcache, base);
    LDAP_MEMCACHE_MUTEX_UNLOCK( ld->ld_memcache );
    LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );

    if (nRes != LDAP_SUCCESS)
       return nRes;

    defhost = NSLDAPI_STR_NONNULL(ld->ld_defhost);
    defport = ld->ld_defport;
    tmpbase = nsldapi_strdup(NSLDAPI_STR_NONNULL(base));
    memcache_trim_basedn_spaces(tmpbase);

    if ((binddn = nsldapi_get_binddn(ld)) == NULL)
       binddn = "";

    sprintf(buf, "%i\n%i\n%i\n", defport, scope, (attrsonly ? 1 : 0));
    len = NSLDAPI_SAFE_STRLEN(buf) + NSLDAPI_SAFE_STRLEN(tmpbase) +
         NSLDAPI_SAFE_STRLEN(filter) + NSLDAPI_SAFE_STRLEN(defhost) +
         NSLDAPI_SAFE_STRLEN(binddn);

    if (attrs) {
       for (i = 0; attrs[i]; i++) {

           for (i_smallest = j = i; attrs[j]; j++) {
              if (strcasecmp(attrs[i_smallest], attrs[j]) > 0)
                  i_smallest = j;
           }

           if (i != i_smallest) {
              tmp = attrs[i];
              attrs[i] = attrs[i_smallest];
              attrs[i_smallest] = tmp;
           }

           len += NSLDAPI_SAFE_STRLEN(attrs[i]);
       }
    } else {
       len += 1;
    }

    len += memcache_get_ctrls_len(serverctrls) + 
          memcache_get_ctrls_len(clientctrls) + 1;

    if ((keystr = (char*)NSLDAPI_CALLOC(len, sizeof(char))) == NULL) {
       NSLDAPI_FREE(defhost);
       return( LDAP_NO_MEMORY );
    }

    sprintf(keystr, "%s\n%s\n%s\n%s\n%s\n", binddn, tmpbase,
           NSLDAPI_STR_NONNULL(defhost), NSLDAPI_STR_NONNULL(filter), 
           NSLDAPI_STR_NONNULL(buf));

    if (attrs) {
       for (i = 0; attrs[i]; i++) {
           strcat(keystr, NSLDAPI_STR_NONNULL(attrs[i]));
           strcat(keystr, "\n");
       }
    } else {
       strcat(keystr, "\n");
    }

    for (tmp = keystr; *tmp; 
         *tmp += (*tmp >= 'a' && *tmp <= 'z' ? 'A'-'a' : 0), tmp++) {
              ;
       }

    memcache_append_ctrls(keystr, serverctrls, clientctrls);

    /* CRC algorithm */
    *keyp = crc32_convert(keystr, len);

    NSLDAPI_FREE(keystr);
    NSLDAPI_FREE(tmpbase);

    return LDAP_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void LDAP_CALL ldap_memcache_destroy ( LDAPMemCache *  cache)

Definition at line 517 of file memcache.c.

{
    int i = 0;
    unsigned long size = sizeof(LDAPMemCache);
    ldapmemcacheld *pNode = NULL, *pNextNode = NULL;

    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_destroy( 0x%x )\n",
           cache, 0, 0 );

    if ( !NSLDAPI_VALID_MEMCACHE_POINTER( cache )) {
       return;
    }

    /* Dissociate all ldap handes from this cache. */
    LDAP_MEMCACHE_MUTEX_LOCK( cache );

    for (pNode = cache->ldmemc_lds; pNode; pNode = pNextNode, i++) {
        LDAP_MUTEX_LOCK( pNode->ldmemcl_ld, LDAP_MEMCACHE_LOCK );
       cache->ldmemc_lds = pNode->ldmemcl_next;
       pNode->ldmemcl_ld->ld_memcache = NULL;
        LDAP_MUTEX_UNLOCK( pNode->ldmemcl_ld, LDAP_MEMCACHE_LOCK );
       pNextNode = pNode->ldmemcl_next;
       NSLDAPI_FREE(pNode);
    }

    size += i * sizeof(ldapmemcacheld);

    LDAP_MEMCACHE_MUTEX_UNLOCK( cache );

    /* Free array of basedns */
    if (cache->ldmemc_basedns) {
       for (i = 0; cache->ldmemc_basedns[i]; i++) {
           size += strlen(cache->ldmemc_basedns[i]) + 1;
           NSLDAPI_FREE(cache->ldmemc_basedns[i]);
       }
       size += (i + 1) * sizeof(char*);
       NSLDAPI_FREE(cache->ldmemc_basedns);
    }

    /* Free hash table used for temporary cache */
    if (cache->ldmemc_resTmp) {
       size += htable_sizeinbytes(cache->ldmemc_resTmp);
       memcache_access(cache, MEMCACHE_ACCESS_DELETE_ALL, NULL, NULL, NULL);
       htable_free(cache->ldmemc_resTmp);
    }

    /* Free hash table used for primary cache */
    if (cache->ldmemc_resLookup) {
       size += htable_sizeinbytes(cache->ldmemc_resLookup);
       memcache_access(cache, MEMCACHE_ACCESS_FLUSH_ALL, NULL, NULL, NULL);
       htable_free(cache->ldmemc_resLookup);
    }

    memcache_adj_size(cache, size, MEMCACHE_SIZE_NON_ENTRIES, 
                     MEMCACHE_SIZE_DEDUCT);

    LDAP_MEMCACHE_MUTEX_FREE( cache );

    NSLDAPI_FREE(cache);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void LDAP_CALL ldap_memcache_flush ( LDAPMemCache *  cache,
char *  dn,
int  scope 
)

Definition at line 492 of file memcache.c.

{
    LDAPDebug( LDAP_DEBUG_TRACE,
           "ldap_memcache_flush( cache: 0x%x, dn: %s, scope: %d)\n",
           cache, ( dn == NULL ) ? "(null)" : dn, scope );

    if ( !NSLDAPI_VALID_MEMCACHE_POINTER( cache )) {
       return;
    }

    LDAP_MEMCACHE_MUTEX_LOCK( cache );

    if (!dn) {
       memcache_access(cache, MEMCACHE_ACCESS_FLUSH_ALL, NULL, NULL, NULL);
    } else {
       memcache_access(cache, MEMCACHE_ACCESS_FLUSH, 
                       (void*)dn, (void*)scope, NULL);
    }

    LDAP_MEMCACHE_MUTEX_UNLOCK( cache );
}

Here is the call graph for this function:

int LDAP_CALL ldap_memcache_get ( LDAP *  ld,
LDAPMemCache **  cachep 
)

Definition at line 453 of file memcache.c.

{
    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_get ld: 0x%x\n", ld, 0, 0 );

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || cachep == NULL ) { 
       return( LDAP_PARAM_ERROR );
    }

    LDAP_MUTEX_LOCK( ld, LDAP_MEMCACHE_LOCK );
    *cachep = ld->ld_memcache;
    LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );

    return( LDAP_SUCCESS );
}
int LDAP_CALL ldap_memcache_init ( unsigned long  ttl,
unsigned long  size,
char **  baseDNs,
struct ldap_thread_fns thread_fns,
LDAPMemCache **  cachep 
)

Definition at line 259 of file memcache.c.

{
    unsigned long total_size = 0;

    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_init\n", 0, 0, 0 );

    if ( cachep == NULL ) {
       return( LDAP_PARAM_ERROR );
    }

    if ((*cachep = (LDAPMemCache*)NSLDAPI_CALLOC(1,
           sizeof(LDAPMemCache))) == NULL) {
       return ( LDAP_NO_MEMORY );
    }

    total_size += sizeof(LDAPMemCache);

    (*cachep)->ldmemc_ttl = ttl;
    (*cachep)->ldmemc_size = size;
    (*cachep)->ldmemc_lds = NULL;

    /* Non-zero default size needed for calculating size of hash tables */
    size = (size ? size : MEMCACHE_DEF_SIZE);

    if (thread_fns) {
       memcpy(&((*cachep)->ldmemc_lock_fns), thread_fns, 
           sizeof(struct ldap_thread_fns));
    } else {
       memset(&((*cachep)->ldmemc_lock_fns), 0, 
          sizeof(struct ldap_thread_fns));
    }

    (*cachep)->ldmemc_lock = LDAP_MEMCACHE_MUTEX_ALLOC( *cachep );

    /* Cache basedns */
    if (baseDNs != NULL) {

       int i;

       for (i = 0; baseDNs[i]; i++) {
              ;
       }

       (*cachep)->ldmemc_basedns = (char**)NSLDAPI_CALLOC(i + 1,
              sizeof(char*));

       if ((*cachep)->ldmemc_basedns == NULL) {
           ldap_memcache_destroy(*cachep);
           *cachep = NULL;
           return ( LDAP_NO_MEMORY );
       }

       total_size += (i + 1) * sizeof(char*);

       for (i = 0; baseDNs[i]; i++) {
           (*cachep)->ldmemc_basedns[i] = nsldapi_strdup(baseDNs[i]);
           total_size += strlen(baseDNs[i]) + 1;
       }

       (*cachep)->ldmemc_basedns[i] = NULL;
    }

    /* Create hash table for temporary cache */
    if (htable_create(size, msgid_hashf, msgid_putdata, msgid_getdata,
                      msgid_removedata, msgid_clearnode, msgid_clear_ld_items,
                    &((*cachep)->ldmemc_resTmp)) != LDAP_SUCCESS) {
       ldap_memcache_destroy(*cachep);
       *cachep = NULL;
       return( LDAP_NO_MEMORY );
    }

    total_size += htable_sizeinbytes((*cachep)->ldmemc_resTmp);

    /* Create hash table for primary cache */
    if (htable_create(size, attrkey_hashf, attrkey_putdata, 
                     attrkey_getdata, attrkey_removedata, attrkey_clearnode,
                    NULL, &((*cachep)->ldmemc_resLookup)) != LDAP_SUCCESS) {
       ldap_memcache_destroy(*cachep);
       *cachep = NULL;
       return( LDAP_NO_MEMORY );
    }

    total_size += htable_sizeinbytes((*cachep)->ldmemc_resLookup);
    
    /* See if there is enough room so far */
    if (memcache_adj_size(*cachep, total_size, MEMCACHE_SIZE_NON_ENTRIES,
                         MEMCACHE_SIZE_ADD) != LDAP_SUCCESS) {
       ldap_memcache_destroy(*cachep);
       *cachep = NULL;
       return( LDAP_SIZELIMIT_EXCEEDED );
    }

    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_init new cache 0x%x\n",
           *cachep, 0, 0 );

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_memcache_new ( LDAP *  ld,
int  msgid,
unsigned long  key,
const char *  basedn 
)

Definition at line 736 of file memcache.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_memcache_result ( LDAP *  ld,
int  msgid,
unsigned long  key 
)

Definition at line 688 of file memcache.c.

{
    int nRes;
    LDAPMessage *pMsg = NULL;

    LDAPDebug( LDAP_DEBUG_TRACE,
           "ldap_memcache_result( ld: 0x%x, msgid: %d, key: 0x%8.8lx)\n",
           ld, msgid, key );

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || (msgid < 0) ) {
       return( LDAP_PARAM_ERROR );
    }

    if (!memcache_exist(ld)) {
       return( LDAP_LOCAL_ERROR );
    }

    LDAP_MUTEX_LOCK( ld, LDAP_MEMCACHE_LOCK );
    LDAP_MEMCACHE_MUTEX_LOCK( ld->ld_memcache );

    /* Search the cache and append the results to ld if found */
    ++ld->ld_memcache->ldmemc_stats.ldmemcstat_tries;
    if ((nRes = memcache_search(ld, key, &pMsg)) == LDAP_SUCCESS) {
       nRes = memcache_add_to_ld(ld, msgid, pMsg);
       ++ld->ld_memcache->ldmemc_stats.ldmemcstat_hits;
       LDAPDebug( LDAP_DEBUG_TRACE,
              "ldap_memcache_result: key 0x%8.8lx found in cache\n",
              key, 0, 0 );
    } else {
       LDAPDebug( LDAP_DEBUG_TRACE,
              "ldap_memcache_result: key 0x%8.8lx not found in cache\n",
              key, 0, 0 );
    }

#ifdef LDAP_DEBUG
    memcache_print_list( ld->ld_memcache, LIST_LRU );
    memcache_report_statistics( ld->ld_memcache );
#endif /* LDAP_DEBUG */

    LDAP_MEMCACHE_MUTEX_UNLOCK( ld->ld_memcache );
    LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int LDAP_CALL ldap_memcache_set ( LDAP *  ld,
LDAPMemCache *  cache 
)

Definition at line 362 of file memcache.c.

{
    int nRes = LDAP_SUCCESS;

    LDAPDebug( LDAP_DEBUG_TRACE, "ldap_memcache_set\n", 0, 0, 0 );

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) )
       return( LDAP_PARAM_ERROR );

    LDAP_MUTEX_LOCK( ld, LDAP_MEMCACHE_LOCK );

    if (ld->ld_memcache != cache) {

        LDAPMemCache *c = ld->ld_memcache;
       ldapmemcacheld *pCur = NULL;
       ldapmemcacheld *pPrev = NULL;

       /* First dissociate handle from old cache */

       LDAP_MEMCACHE_MUTEX_LOCK( c );

       pCur = (c ? c->ldmemc_lds : NULL);
       for (; pCur; pCur = pCur->ldmemcl_next) {
           if (pCur->ldmemcl_ld == ld)
              break;
           pPrev = pCur;
       }

       if (pCur) {

           ldapmemcacheReqId reqid;

           reqid.ldmemcrid_ld = ld;
           reqid.ldmemcrid_msgid = -1;
           htable_misc(c->ldmemc_resTmp, (void*)&reqid, (void*)c);

           if (pPrev)
              pPrev->ldmemcl_next = pCur->ldmemcl_next;
           else
              c->ldmemc_lds = pCur->ldmemcl_next;
           NSLDAPI_FREE(pCur);
           pCur = NULL;

           memcache_adj_size(c, sizeof(ldapmemcacheld),
                       MEMCACHE_SIZE_NON_ENTRIES, MEMCACHE_SIZE_DEDUCT);
       }

       LDAP_MEMCACHE_MUTEX_UNLOCK( c );

       ld->ld_memcache = NULL;

       /* Exit if no new cache is specified */
       if (cache == NULL) {
           LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );
           return( LDAP_SUCCESS );
       }

       /* Then associate handle with new cache */

        LDAP_MEMCACHE_MUTEX_LOCK( cache );

       if ((nRes = memcache_adj_size(cache, sizeof(ldapmemcacheld),
              MEMCACHE_SIZE_NON_ENTRIES, MEMCACHE_SIZE_ADD)) != LDAP_SUCCESS) {
           LDAP_MEMCACHE_MUTEX_UNLOCK( cache );
           LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );
           return nRes;
       }

       pCur = (ldapmemcacheld*)NSLDAPI_CALLOC(1, sizeof(ldapmemcacheld));
       if (pCur == NULL) {
           memcache_adj_size(cache, sizeof(ldapmemcacheld), 
                            MEMCACHE_SIZE_NON_ENTRIES, MEMCACHE_SIZE_DEDUCT);
           nRes = LDAP_NO_MEMORY;
       } else {
           pCur->ldmemcl_ld = ld;
           pCur->ldmemcl_next = cache->ldmemc_lds;
           cache->ldmemc_lds = pCur;
           ld->ld_memcache = cache;
       }

       LDAP_MEMCACHE_MUTEX_UNLOCK( cache );
    }

    LDAP_MUTEX_UNLOCK( ld, LDAP_MEMCACHE_LOCK );

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void LDAP_CALL ldap_memcache_update ( LDAPMemCache *  cache)

Definition at line 475 of file memcache.c.

Here is the call graph for this function:

static int memcache_access ( LDAPMemCache *  cache,
int  mode,
void pData1,
void pData2,
void pData3 
) [static]

Definition at line 1419 of file memcache.c.

{
    int nRes = LDAP_SUCCESS;
    unsigned long size = 0;

    /* Add a new cache header to the cache. */
    if (mode == MEMCACHE_ACCESS_ADD) {
       unsigned long key = *((unsigned long*)pData1);
       char *basedn = (char*)pData3;
       ldapmemcacheRes *pRes = NULL;

       nRes = htable_get(cache->ldmemc_resTmp, pData2, (void**)&pRes);
       if (nRes == LDAP_SUCCESS)
           return( LDAP_ALREADY_EXISTS );

       pRes = (ldapmemcacheRes*)NSLDAPI_CALLOC(1, sizeof(ldapmemcacheRes));
       if (pRes == NULL)
           return( LDAP_NO_MEMORY );

       pRes->ldmemcr_crc_key = key;
       pRes->ldmemcr_req_id = *((ldapmemcacheReqId*)pData2);
       pRes->ldmemcr_basedn = (basedn ? nsldapi_strdup(basedn) : NULL);

       size += sizeof(ldapmemcacheRes) + strlen(basedn) + 1;
       nRes = memcache_adj_size(cache, size, MEMCACHE_SIZE_ENTRIES,
                                MEMCACHE_SIZE_ADD);
       if (nRes == LDAP_SUCCESS)
           nRes = htable_put(cache->ldmemc_resTmp, pData2, (void*)pRes);
       if (nRes == LDAP_SUCCESS)
           memcache_add_to_list(cache, pRes, LIST_TMP);
       else
           memcache_free_entry(cache, pRes);
    }
    /* Append entries to an existing cache header. */
    else if ((mode == MEMCACHE_ACCESS_APPEND) ||
            (mode == MEMCACHE_ACCESS_APPEND_LAST)) {

       LDAPMessage *pMsg = (LDAPMessage*)pData2;
       LDAPMessage *pCopy = NULL;
       ldapmemcacheRes *pRes = NULL;

       nRes = htable_get(cache->ldmemc_resTmp, pData1, (void**)&pRes);
       if (nRes != LDAP_SUCCESS)
           return nRes;

       nRes = memcache_dup_message(pMsg, pMsg->lm_msgid, 0, &pCopy, &size);
       if (nRes != LDAP_SUCCESS) {
           nRes = htable_remove(cache->ldmemc_resTmp, pData1, NULL);
           assert(nRes == LDAP_SUCCESS);
           memcache_free_from_list(cache, pRes, LIST_TMP);
           memcache_free_entry(cache, pRes);
           return nRes;
       }

       nRes = memcache_adj_size(cache, size, MEMCACHE_SIZE_ENTRIES,
                                MEMCACHE_SIZE_ADD);
       if (nRes != LDAP_SUCCESS) {
           ldap_msgfree(pCopy);
           nRes = htable_remove(cache->ldmemc_resTmp, pData1, NULL);
           assert(nRes == LDAP_SUCCESS);
           memcache_free_from_list(cache, pRes, LIST_TMP);
           memcache_free_entry(cache, pRes);
           return nRes;
       }

       memcache_add_res_to_list(pRes, pCopy, size);

       if (mode == MEMCACHE_ACCESS_APPEND)
           return( LDAP_SUCCESS );

       nRes = htable_remove(cache->ldmemc_resTmp, pData1, NULL);
       assert(nRes == LDAP_SUCCESS);
       memcache_free_from_list(cache, pRes, LIST_TMP);
       (pRes->ldmemcr_req_id).ldmemcrid_ld = NULL;
       (pRes->ldmemcr_req_id).ldmemcrid_msgid = -1;
       pRes->ldmemcr_timestamp = (unsigned long)time(NULL);

       if ((nRes = htable_put(cache->ldmemc_resLookup, 
                              (void*)&(pRes->ldmemcr_crc_key),
                               (void*)pRes)) == LDAP_SUCCESS) {
           memcache_add_to_list(cache, pRes, LIST_TTL);
           memcache_add_to_list(cache, pRes, LIST_LRU);
       } else {
           memcache_free_entry(cache, pRes);
       }
    }
    /* Search for cached entries for a particular search. */
    else if (mode == MEMCACHE_ACCESS_FIND) {

       ldapmemcacheRes **ppRes = (ldapmemcacheRes**)pData2;

       nRes = htable_get(cache->ldmemc_resLookup, pData1, (void**)ppRes);
       if (nRes != LDAP_SUCCESS)
           return nRes;

       if (!memcache_expired(cache, *ppRes, (unsigned long)time(0))) {
           memcache_free_from_list(cache, *ppRes, LIST_LRU);
           memcache_add_to_list(cache, *ppRes, LIST_LRU);
           return( LDAP_SUCCESS );
       }

       nRes = htable_remove(cache->ldmemc_resLookup, pData1, NULL);
       assert(nRes == LDAP_SUCCESS);
       memcache_free_from_list(cache, *ppRes, LIST_TTL);
       memcache_free_from_list(cache, *ppRes, LIST_LRU);
       memcache_free_entry(cache, *ppRes);
       nRes = LDAP_NO_SUCH_OBJECT;
       *ppRes = NULL;
    }
    /* Remove cached entries in the temporary cache. */
    else if (mode == MEMCACHE_ACCESS_DELETE) {

       ldapmemcacheRes *pCurRes = NULL;

       if ((nRes = htable_remove(cache->ldmemc_resTmp, pData1,
                                 (void**)&pCurRes)) == LDAP_SUCCESS) {
           memcache_free_from_list(cache, pCurRes, LIST_TMP);
           memcache_free_entry(cache, pCurRes);
       }
    }
    /* Wipe out the temporary cache. */
    else if (mode == MEMCACHE_ACCESS_DELETE_ALL) {

       nRes = htable_removeall(cache->ldmemc_resTmp, (void*)cache);
    }
    /* Remove expired entries from primary cache. */
    else if (mode == MEMCACHE_ACCESS_UPDATE) {

       ldapmemcacheRes *pCurRes = cache->ldmemc_resTail[LIST_TTL];
       unsigned long curTime = (unsigned long)time(NULL);

       for (; pCurRes; pCurRes = cache->ldmemc_resTail[LIST_TTL]) {

           if (!memcache_expired(cache, pCurRes, curTime))
              break;

           nRes = htable_remove(cache->ldmemc_resLookup, 
                        (void*)&(pCurRes->ldmemcr_crc_key), NULL);
           assert(nRes == LDAP_SUCCESS);
           memcache_free_from_list(cache, pCurRes, LIST_TTL);
           memcache_free_from_list(cache, pCurRes, LIST_LRU);
           memcache_free_entry(cache, pCurRes);
       }
    }
    /* Wipe out the primary cache. */
    else if (mode == MEMCACHE_ACCESS_FLUSH_ALL) {

       ldapmemcacheRes *pCurRes = cache->ldmemc_resHead[LIST_TTL];

       nRes = htable_removeall(cache->ldmemc_resLookup, (void*)cache);

       for (; pCurRes; pCurRes = cache->ldmemc_resHead[LIST_TTL]) {
           memcache_free_from_list(cache, pCurRes, LIST_LRU);
           cache->ldmemc_resHead[LIST_TTL] = 
                    cache->ldmemc_resHead[LIST_TTL]->ldmemcr_next[LIST_TTL];
           memcache_free_entry(cache, pCurRes);
       }
       cache->ldmemc_resTail[LIST_TTL] = NULL;
    }
    /* Remove cached entries in both primary and temporary cache. */
    else if (mode == MEMCACHE_ACCESS_FLUSH) {

       int i, list_id, bDone;
       int scope = (int)pData2;
       char *dn = (char*)pData1;
       char *dnTmp;
       BerElement ber;
       LDAPMessage *pMsg;
       ldapmemcacheRes *pRes;

       if (cache->ldmemc_basedns) {
           for (i = 0; cache->ldmemc_basedns[i]; i++) {
              if ((memcache_compare_dn(cache->ldmemc_basedns[i], dn, 
                         LDAP_SCOPE_SUBTREE) == LDAP_COMPARE_TRUE) ||
                  (memcache_compare_dn(dn, cache->ldmemc_basedns[i], 
                         LDAP_SCOPE_SUBTREE) == LDAP_COMPARE_TRUE))
                  break;
           }
           if (cache->ldmemc_basedns[i] == NULL)
              return( LDAP_SUCCESS );
       }

       for (i = 0; i < 2; i++) {

           list_id = (i == 0 ? LIST_TTL : LIST_TMP);

           for (pRes = cache->ldmemc_resHead[list_id]; pRes != NULL; 
               pRes = pRes->ldmemcr_next[list_id]) {

              if ((memcache_compare_dn(pRes->ldmemcr_basedn, dn, 
                             LDAP_SCOPE_SUBTREE) != LDAP_COMPARE_TRUE) &&
                  (memcache_compare_dn(dn, pRes->ldmemcr_basedn, 
                             LDAP_SCOPE_SUBTREE) != LDAP_COMPARE_TRUE))
                  continue;

              for (pMsg = pRes->ldmemcr_resHead, bDone = 0; 
                   !bDone && pMsg; pMsg = pMsg->lm_chain) {

                  if (!NSLDAPI_IS_SEARCH_ENTRY( pMsg->lm_msgtype ))
                     continue;

                  ber = *(pMsg->lm_ber);
                  if (ber_scanf(&ber, "{a", &dnTmp) != LBER_ERROR) {
                     bDone = (memcache_compare_dn(dnTmp, dn, scope) == 
                                                     LDAP_COMPARE_TRUE);
                     ldap_memfree(dnTmp);
                  }
              }

              if (!bDone)
                  continue;

              if (list_id == LIST_TTL) {
                  nRes = htable_remove(cache->ldmemc_resLookup, 
                             (void*)&(pRes->ldmemcr_crc_key), NULL);
                  assert(nRes == LDAP_SUCCESS);
                  memcache_free_from_list(cache, pRes, LIST_TTL);
                  memcache_free_from_list(cache, pRes, LIST_LRU);
              } else {
                  nRes = htable_remove(cache->ldmemc_resTmp, 
                              (void*)&(pRes->ldmemcr_req_id), NULL);
                  assert(nRes == LDAP_SUCCESS);
                  memcache_free_from_list(cache, pRes, LIST_TMP);
              }
              memcache_free_entry(cache, pRes);
           }
       }
    }
    /* Flush least recently used entries from cache */
    else if (mode == MEMCACHE_ACCESS_FLUSH_LRU) {

       ldapmemcacheRes *pRes = cache->ldmemc_resTail[LIST_LRU];

       if (pRes == NULL)
           return LDAP_NO_SUCH_OBJECT;

       LDAPDebug( LDAP_DEBUG_TRACE,
              "memcache_access FLUSH_LRU: removing key 0x%8.8lx\n",
              pRes->ldmemcr_crc_key, 0, 0 );
       nRes = htable_remove(cache->ldmemc_resLookup,
                     (void*)&(pRes->ldmemcr_crc_key), NULL);
       assert(nRes == LDAP_SUCCESS);
       memcache_free_from_list(cache, pRes, LIST_TTL);
       memcache_free_from_list(cache, pRes, LIST_LRU);
       memcache_free_entry(cache, pRes);
    }
    /* Unknown command */
    else {
       nRes = LDAP_PARAM_ERROR;
    }

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_add ( LDAP *  ld,
unsigned long  key,
int  msgid,
const char *  basedn 
) [static]

Definition at line 1021 of file memcache.c.

{
    ldapmemcacheReqId reqid;

    if (!memcache_exist(ld))
        return LDAP_LOCAL_ERROR;

    reqid.ldmemcrid_msgid = msgid;
    reqid.ldmemcrid_ld = ld;

    return memcache_access(ld->ld_memcache, MEMCACHE_ACCESS_ADD,
                          (void*)&key, (void*)&reqid, (void*)basedn);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_add_res_to_list ( ldapmemcacheRes pRes,
LDAPMessage *  pMsg,
unsigned long  size 
) [static]

Definition at line 1344 of file memcache.c.

{
    if (pRes->ldmemcr_resTail)
       pRes->ldmemcr_resTail->lm_chain = pMsg;
    else
       pRes->ldmemcr_resHead = pMsg;

    for (pRes->ldmemcr_resTail = pMsg;
         pRes->ldmemcr_resTail->lm_chain;
         pRes->ldmemcr_resTail = pRes->ldmemcr_resTail->lm_chain) {
              ;
       }

    pRes->ldmemcr_resSize += size;

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int memcache_add_to_ld ( LDAP *  ld,
int  msgid,
LDAPMessage *  pMsg 
) [static]

Definition at line 1109 of file memcache.c.

{
    int nRes = LDAP_SUCCESS;
    LDAPMessage **r;
    LDAPMessage *pCopy;

    nRes = memcache_dup_message(pMsg, msgid, 1, &pCopy, NULL);
    if (nRes != LDAP_SUCCESS)
       return nRes;

    for (r = &(ld->ld_responses); *r; r = &((*r)->lm_next))
       if ((*r)->lm_msgid == msgid)
           break;

    if (*r)
       for (r = &((*r)->lm_chain); *r; r = &((*r)->lm_chain)) {
              ;
       }

    *r = pCopy;
    
    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_add_to_list ( LDAPMemCache *  cache,
ldapmemcacheRes pRes,
int  index 
) [static]

Definition at line 1328 of file memcache.c.

{
    if (cache->ldmemc_resHead[index])
       cache->ldmemc_resHead[index]->ldmemcr_prev[index] = pRes;
    else
       cache->ldmemc_resTail[index] = pRes;

    pRes->ldmemcr_prev[index] = NULL;
    pRes->ldmemcr_next[index] = cache->ldmemc_resHead[index];
    cache->ldmemc_resHead[index] = pRes;

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int memcache_adj_size ( LDAPMemCache *  cache,
unsigned long  size,
int  usageFlags,
int  bAdd 
) [static]

Definition at line 936 of file memcache.c.

{
    LDAPDebug( LDAP_DEBUG_TRACE,
           "memcache_adj_size: attempting to %s %ld %s bytes...\n",
           bAdd ? "add" : "remove", size,
           ( usageFlags & MEMCACHE_SIZE_ENTRIES ) ? "entry" : "non-entry" );

    if (bAdd) {
       cache->ldmemc_size_used += size;
       if ((cache->ldmemc_size > 0) &&
           (cache->ldmemc_size_used > cache->ldmemc_size)) {

           if (size > cache->ldmemc_size_entries) {
               cache->ldmemc_size_used -= size;
              LDAPDebug( LDAP_DEBUG_TRACE,
                     "memcache_adj_size: failed (size > size_entries %ld).\n",
                     cache->ldmemc_size_entries, 0, 0 );
              return( LDAP_SIZELIMIT_EXCEEDED );
           }

           while (cache->ldmemc_size_used > cache->ldmemc_size) {
              if (memcache_access(cache, MEMCACHE_ACCESS_FLUSH_LRU,
                                  NULL, NULL, NULL) != LDAP_SUCCESS) {
                   cache->ldmemc_size_used -= size;
                  LDAPDebug( LDAP_DEBUG_TRACE,
                         "memcache_adj_size: failed (LRU flush failed).\n",
                         0, 0, 0 );
                  return( LDAP_SIZELIMIT_EXCEEDED );
               }
           }
       }
       if (usageFlags & MEMCACHE_SIZE_ENTRIES)
           cache->ldmemc_size_entries += size;
    } else {
       cache->ldmemc_size_used -= size;
       assert(cache->ldmemc_size_used >= 0);
       if (usageFlags & MEMCACHE_SIZE_ENTRIES)
           cache->ldmemc_size_entries -= size;
    }

#ifdef LDAP_DEBUG
    if ( cache->ldmemc_size == 0 ) {      /* no size limit */
       LDAPDebug( LDAP_DEBUG_TRACE,
              "memcache_adj_size: succeeded (new size: %ld bytes).\n",
              cache->ldmemc_size_used, 0, 0 );
    } else {
       LDAPDebug( LDAP_DEBUG_TRACE,
              "memcache_adj_size: succeeded (new size: %ld bytes, "
              "free space: %ld bytes).\n", cache->ldmemc_size_used,
              cache->ldmemc_size - cache->ldmemc_size_used, 0 );
    }
#endif /* LDAP_DEBUG */

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_append ( LDAP *  ld,
int  msgid,
LDAPMessage *  pRes 
) [static]

Definition at line 1038 of file memcache.c.

{
    ldapmemcacheReqId reqid;

    if (!memcache_exist(ld))
        return LDAP_LOCAL_ERROR;

    reqid.ldmemcrid_msgid = msgid;
    reqid.ldmemcrid_ld = ld;

    return memcache_access(ld->ld_memcache, MEMCACHE_ACCESS_APPEND,
                          (void*)&reqid, (void*)pRes, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void memcache_append_ctrls ( char *  buf,
LDAPControl **  serverCtrls,
LDAPControl **  clientCtrls 
) [static]

Definition at line 907 of file memcache.c.

{
    int i, j;
    char *pCh = buf + strlen(buf);
    LDAPControl **ctrls;

    for (j = 0; j < 2; j++) {

       if ((ctrls = (j ? clientCtrls : serverCtrls)) == NULL)
           continue;

       for (i = 0; ctrls[i]; i++) {
           sprintf(pCh, "%s\n", NSLDAPI_STR_NONNULL(ctrls[i]->ldctl_oid));
           pCh += strlen(NSLDAPI_STR_NONNULL(ctrls[i]->ldctl_oid)) + 1;
           if ((ctrls[i]->ldctl_value).bv_len > 0) {
              memcpy(pCh, (ctrls[i]->ldctl_value).bv_val, 
                     (ctrls[i]->ldctl_value).bv_len);
              pCh += (ctrls[i]->ldctl_value).bv_len;
           }
           sprintf(pCh, "\n%i\n", (ctrls[i]->ldctl_iscritical ? 1 : 0));
           pCh += 3;
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_append_last ( LDAP *  ld,
int  msgid,
LDAPMessage *  pRes 
) [static]

Definition at line 1057 of file memcache.c.

{
    ldapmemcacheReqId reqid;

    if (!memcache_exist(ld))
        return LDAP_LOCAL_ERROR;

    reqid.ldmemcrid_msgid = msgid;
    reqid.ldmemcrid_ld = ld;

    return memcache_access(ld->ld_memcache, MEMCACHE_ACCESS_APPEND_LAST,
                          (void*)&reqid, (void*)pRes, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static BerElement * memcache_ber_dup ( BerElement *  pBer,
unsigned long pSize 
) [static]

Definition at line 1195 of file memcache.c.

{
    BerElement *p = ber_dup(pBer);

    *pSize = 0;

    if (p) {

       *pSize += sizeof(BerElement) + EXTRA_SIZE;

       if (p->ber_len <= EXTRA_SIZE) {
           p->ber_flags |= LBER_FLAG_NO_FREE_BUFFER;
           p->ber_buf = (char*)p + sizeof(BerElement);
       } else {
           p->ber_flags &= ~LBER_FLAG_NO_FREE_BUFFER;
           p->ber_buf = (char*)NSLDAPI_CALLOC(1, p->ber_len);
           *pSize += (p->ber_buf ? p->ber_len : 0);
       }

       if (p->ber_buf) {
           p->ber_ptr = p->ber_buf + (pBer->ber_ptr - pBer->ber_buf);
           p->ber_end = p->ber_buf + p->ber_len;
           memcpy(p->ber_buf, pBer->ber_buf, p->ber_len);
       } else {
           ber_free(p, 0);
           p = NULL;
           *pSize = 0;
       }
    }

    return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_compare_dn ( const char *  main_dn,
const char *  dn,
int  scope 
) [static]

Definition at line 1135 of file memcache.c.

{
    int nRes;
    char **components = NULL;
    char **main_components = NULL;

    components = ldap_explode_dn(dn, 0);
    main_components = ldap_explode_dn(main_dn, 0);

    if (!components || !main_components) {
       nRes = LDAP_COMPARE_TRUE;
    }
    else {

       int i, main_i;

       main_i = ldap_count_values(main_components) - 1;
       i = ldap_count_values(components) - 1;

       for (; i >= 0 && main_i >= 0; i--, main_i--) {
           if (strcasecmp(main_components[main_i], components[i]))
              break;
       }

       if (i >= 0 && main_i >= 0) {
           nRes = LDAP_COMPARE_FALSE;
       }
       else if (i < 0 && main_i < 0) {
           if (scope != LDAP_SCOPE_ONELEVEL)
              nRes = LDAP_COMPARE_TRUE;
           else
              nRes = LDAP_COMPARE_FALSE;
       }
       else if (main_i < 0) {
           nRes = LDAP_COMPARE_FALSE;
       }
       else {
           if (scope == LDAP_SCOPE_BASE) 
              nRes = LDAP_COMPARE_FALSE;
           else if (scope == LDAP_SCOPE_SUBTREE)
              nRes = LDAP_COMPARE_TRUE;
           else if (main_i == 0)
              nRes = LDAP_COMPARE_TRUE;
           else
              nRes = LDAP_COMPARE_FALSE;
       }
    }

    if (components)
       ldap_value_free(components);

    if (main_components)
       ldap_value_free(main_components);

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_dup_message ( LDAPMessage *  res,
int  msgid,
int  fromcache,
LDAPMessage **  ppResCopy,
unsigned long pSize 
) [static]

Definition at line 1230 of file memcache.c.

{
    int nRes = LDAP_SUCCESS;
    unsigned long ber_size;
    LDAPMessage *pCur;
    LDAPMessage **ppCurNew;

    *ppResCopy = NULL;

    if (pSize)
       *pSize = 0;

    /* Make a copy of res */
    for (pCur = res, ppCurNew = ppResCopy; pCur; 
         pCur = pCur->lm_chain, ppCurNew = &((*ppCurNew)->lm_chain)) {

       if ((*ppCurNew = (LDAPMessage*)NSLDAPI_CALLOC(1, 
                                            sizeof(LDAPMessage))) == NULL) {
           nRes = LDAP_NO_MEMORY;
           break;
       }

       memcpy(*ppCurNew, pCur, sizeof(LDAPMessage));
       (*ppCurNew)->lm_next = NULL;
       (*ppCurNew)->lm_ber = memcache_ber_dup(pCur->lm_ber, &ber_size);
       (*ppCurNew)->lm_msgid = msgid;
       (*ppCurNew)->lm_fromcache = (fromcache != 0);

       if (pSize)
           *pSize += sizeof(LDAPMessage) + ber_size;
    }

    if ((nRes != LDAP_SUCCESS) && (*ppResCopy != NULL)) {
       ldap_msgfree(*ppResCopy);
       *ppResCopy = NULL;
       if (pSize)
           *pSize = 0;
    }

    return nRes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_exist ( LDAP *  ld) [static]

Definition at line 1102 of file memcache.c.

{
    return (ld->ld_memcache != NULL);
}

Here is the caller graph for this function:

static int memcache_expired ( LDAPMemCache *  cache,
ldapmemcacheRes pRes,
unsigned long  curTime 
) [static]

Definition at line 1405 of file memcache.c.

{
    if (!cache->ldmemc_ttl)
       return 0;

    return ((unsigned long)difftime(
                            (time_t)curTime, 
                          (time_t)(pRes->ldmemcr_timestamp)) >=
                                               cache->ldmemc_ttl);
}

Here is the caller graph for this function:

static int memcache_free_entry ( LDAPMemCache *  cache,
ldapmemcacheRes pRes 
) [static]

Definition at line 1277 of file memcache.c.

{
    if (pRes) {

       unsigned long size = sizeof(ldapmemcacheRes); 

       if (pRes->ldmemcr_basedn) {
           size += strlen(pRes->ldmemcr_basedn) + 1;
           NSLDAPI_FREE(pRes->ldmemcr_basedn);
       }

       if (pRes->ldmemcr_resHead) {
           size += pRes->ldmemcr_resSize;
           ldap_msgfree(pRes->ldmemcr_resHead);
       }

       NSLDAPI_FREE(pRes);

       memcache_adj_size(cache, size, MEMCACHE_SIZE_ENTRIES,
                         MEMCACHE_SIZE_DEDUCT);
    }

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_free_from_list ( LDAPMemCache *  cache,
ldapmemcacheRes pRes,
int  index 
) [static]

Definition at line 1304 of file memcache.c.

{
    if (pRes->ldmemcr_prev[index])
       pRes->ldmemcr_prev[index]->ldmemcr_next[index] = 
                                            pRes->ldmemcr_next[index];

    if (pRes->ldmemcr_next[index])
       pRes->ldmemcr_next[index]->ldmemcr_prev[index] = 
                                            pRes->ldmemcr_prev[index];

    if (cache->ldmemc_resHead[index] == pRes)
       cache->ldmemc_resHead[index] = pRes->ldmemcr_next[index];

    if (cache->ldmemc_resTail[index] == pRes)
       cache->ldmemc_resTail[index] = pRes->ldmemcr_prev[index];

    pRes->ldmemcr_prev[index] = NULL;
    pRes->ldmemcr_next[index] = NULL;

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int memcache_get_ctrls_len ( LDAPControl **  ctrls) [static]

Definition at line 891 of file memcache.c.

{
    int len = 0, i;

    if (ctrls) {
       for (i = 0; ctrls[i]; i++) {
           len += strlen(NSLDAPI_STR_NONNULL(ctrls[i]->ldctl_oid)) +
                  (ctrls[i]->ldctl_value).bv_len + 4;
       }
    }

    return len;
}

Here is the caller graph for this function:

static int memcache_remove ( LDAP *  ld,
int  msgid 
) [static]

Definition at line 1073 of file memcache.c.

{
    ldapmemcacheReqId reqid;

    if (!memcache_exist(ld))
        return LDAP_LOCAL_ERROR;

    reqid.ldmemcrid_msgid = msgid;
    reqid.ldmemcrid_ld = ld;

    return memcache_access(ld->ld_memcache, MEMCACHE_ACCESS_DELETE,
                          (void*)&reqid, NULL, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memcache_search ( LDAP *  ld,
unsigned long  key,
LDAPMessage **  ppRes 
) [static]

Definition at line 996 of file memcache.c.

{
    int nRes;
    ldapmemcacheRes *pRes;

    *ppRes = NULL;

    if (!memcache_exist(ld))
        return LDAP_LOCAL_ERROR;

    nRes = memcache_access(ld->ld_memcache, MEMCACHE_ACCESS_FIND,
                          (void*)&key, (void*)(&pRes), NULL);

    if (nRes != LDAP_SUCCESS)
       return nRes;

    *ppRes = pRes->ldmemcr_resHead;
    assert((pRes->ldmemcr_req_id).ldmemcrid_msgid == -1);

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void memcache_trim_basedn_spaces ( char *  basedn) [static]

Definition at line 835 of file memcache.c.

{
    char *pRead, *pWrite;

    if (!basedn) 
       return;

    for (pWrite = pRead = basedn; *pRead; ) {
       for (; *pRead && NSLDAPI_IS_SPACE(*pRead); pRead++) {
              ;
       }
       for (; *pRead && !NSLDAPI_IS_SEPARATER(*pRead);
           *(pWrite++) = *(pRead++)) {
           ;
       }
       *(pWrite++) = (*pRead ? *(pRead++) : *pRead);
    }
}

Here is the caller graph for this function:

static int memcache_validate_basedn ( LDAPMemCache *  cache,
const char *  basedn 
) [static]

Definition at line 858 of file memcache.c.

{
    int i;

    if ( cache->ldmemc_basedns == NULL ) {
       return( LDAP_SUCCESS );
    }

#if 1
    if (basedn == NULL) {
       basedn = "";
    }
#else
    /* XXXmcs: I do not understand this code... */
    if (basedn == NULL)
       return (cache->ldmemc_basedns && cache->ldmemc_basedns[0] ?
                                    LDAP_OPERATIONS_ERROR : LDAP_SUCCESS);
    }
#endif

    for (i = 0; cache->ldmemc_basedns[i]; i++) {
       if (memcache_compare_dn(basedn, cache->ldmemc_basedns[i], 
                               LDAP_SCOPE_SUBTREE) == LDAP_COMPARE_TRUE) {
           return( LDAP_SUCCESS );
       }
    }

    return( LDAP_OPERATIONS_ERROR );
}

Here is the caller graph for this function:

static int msgid_clear_ld_items ( void **  ppTableData,
void key,
void pData 
) [static]

Definition at line 1988 of file memcache.c.

{
    LDAPMemCache *cache = (LDAPMemCache*)pData;
    ldapmemcacheRes *pHead = *((ldapmemcacheRes**)ppTableData);
    ldapmemcacheRes *pPrev = NULL;
    ldapmemcacheRes *pCurRes = NULL;
    ldapmemcacheReqId *pReqId = (ldapmemcacheReqId*)key;
    
    for (; pHead; pHead = pHead->ldmemcr_htable_next) {
       if ((pHead->ldmemcr_req_id).ldmemcrid_ld == pReqId->ldmemcrid_ld)
           break;
       pPrev = pHead;
    }

    if (!pHead)
       return( LDAP_NO_SUCH_OBJECT );

    if (pPrev)
       pPrev->ldmemcr_htable_next = pHead->ldmemcr_htable_next;
    else
       *((ldapmemcacheRes**)ppTableData) = pHead->ldmemcr_htable_next;

    for (pCurRes = pHead; pHead; pCurRes = pHead) {
       pHead = pHead->ldmemcr_next[LIST_TTL];
       memcache_free_from_list(cache, pCurRes, LIST_TMP);
       memcache_free_entry(cache, pCurRes);
    }

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void msgid_clearnode ( void **  ppTableData,
void pData 
) [static]

Definition at line 2021 of file memcache.c.

{
    LDAPMemCache *cache = (LDAPMemCache*)pData;
    ldapmemcacheRes **ppHead = (ldapmemcacheRes**)ppTableData;
    ldapmemcacheRes *pSubHead = *ppHead;
    ldapmemcacheRes *pCurRes = NULL;

    for (; *ppHead; pSubHead = *ppHead) {
       ppHead = &((*ppHead)->ldmemcr_htable_next);
       for (pCurRes = pSubHead; pSubHead; pCurRes = pSubHead) {
           pSubHead = pSubHead->ldmemcr_next[LIST_TTL];
           memcache_free_from_list(cache, pCurRes, LIST_TMP);
           memcache_free_entry(cache, pCurRes);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int msgid_getdata ( void pTableData,
void key,
void **  ppData 
) [static]

Definition at line 1891 of file memcache.c.

{
    ldapmemcacheReqId *pReqId = (ldapmemcacheReqId*)key;
    ldapmemcacheRes *pCurRes = (ldapmemcacheRes*)pTableData;

    *ppData = NULL;
    
    for (; pCurRes; pCurRes = pCurRes->ldmemcr_htable_next) {
       if ((pCurRes->ldmemcr_req_id).ldmemcrid_ld == pReqId->ldmemcrid_ld)
           break;
    }

    if (!pCurRes)
       return( LDAP_NO_SUCH_OBJECT );

    for (; pCurRes; pCurRes = pCurRes->ldmemcr_next[LIST_TTL]) { 
       if ((pCurRes->ldmemcr_req_id).ldmemcrid_msgid == 
                                         pReqId->ldmemcrid_msgid) {
           *ppData = (void*)pCurRes;
           return( LDAP_SUCCESS );
       }
    }

    return( LDAP_NO_SUCH_OBJECT );
}

Here is the caller graph for this function:

static int msgid_hashf ( int  table_size,
void key 
) [static]

Definition at line 1846 of file memcache.c.

{
    unsigned code = (unsigned)((ldapmemcacheReqId*)key)->ldmemcrid_ld;
    return (((code << 20) + (code >> 12)) % table_size);
}

Here is the caller graph for this function:

static int msgid_putdata ( void **  ppTableData,
void key,
void pData 
) [static]

Definition at line 1854 of file memcache.c.

{
    ldapmemcacheReqId *pReqId = (ldapmemcacheReqId*)key;
    ldapmemcacheRes *pRes = (ldapmemcacheRes*)pData;
    ldapmemcacheRes **ppHead = (ldapmemcacheRes**)ppTableData;
    ldapmemcacheRes *pCurRes = *ppHead;
    ldapmemcacheRes *pPrev = NULL;

    for (; pCurRes; pCurRes = pCurRes->ldmemcr_htable_next) {
       if ((pCurRes->ldmemcr_req_id).ldmemcrid_ld == pReqId->ldmemcrid_ld)
           break;
       pPrev = pCurRes;
    }

    if (pCurRes) {
       for (; pCurRes; pCurRes = pCurRes->ldmemcr_next[LIST_TTL]) { 
           if ((pCurRes->ldmemcr_req_id).ldmemcrid_msgid == 
                                             pReqId->ldmemcrid_msgid)
              return( LDAP_ALREADY_EXISTS );
           pPrev = pCurRes;
       }
       pPrev->ldmemcr_next[LIST_TTL] = pRes;
       pRes->ldmemcr_prev[LIST_TTL] = pPrev;
       pRes->ldmemcr_next[LIST_TTL] = NULL;
    } else {
       if (pPrev)
           pPrev->ldmemcr_htable_next = pRes;
       else
           *ppHead = pRes;
       pRes->ldmemcr_htable_next = NULL;
    }

    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:

static int msgid_removedata ( void **  ppTableData,
void key,
void **  ppData 
) [static]

Definition at line 1919 of file memcache.c.

{
    ldapmemcacheRes *pHead = *((ldapmemcacheRes**)ppTableData);
    ldapmemcacheRes *pCurRes = NULL;
    ldapmemcacheRes *pPrev = NULL;
    ldapmemcacheReqId *pReqId = (ldapmemcacheReqId*)key;

    if (ppData)
       *ppData = NULL;

    for (; pHead; pHead = pHead->ldmemcr_htable_next) {
       if ((pHead->ldmemcr_req_id).ldmemcrid_ld == pReqId->ldmemcrid_ld)
           break;
       pPrev = pHead;
    }

    if (!pHead)
       return( LDAP_NO_SUCH_OBJECT );

    for (pCurRes = pHead; pCurRes; pCurRes = pCurRes->ldmemcr_next[LIST_TTL]) { 
       if ((pCurRes->ldmemcr_req_id).ldmemcrid_msgid == 
                                               pReqId->ldmemcrid_msgid)
           break;
    }

    if (!pCurRes)
       return( LDAP_NO_SUCH_OBJECT );

    if (ppData) {
       pCurRes->ldmemcr_next[LIST_TTL] = NULL;
       pCurRes->ldmemcr_prev[LIST_TTL] = NULL;
       pCurRes->ldmemcr_htable_next = NULL;
       *ppData = (void*)pCurRes;
    }

    if (pCurRes != pHead) {
       if (pCurRes->ldmemcr_prev[LIST_TTL])
           pCurRes->ldmemcr_prev[LIST_TTL]->ldmemcr_next[LIST_TTL] = 
                                            pCurRes->ldmemcr_next[LIST_TTL];
       if (pCurRes->ldmemcr_next[LIST_TTL])
           pCurRes->ldmemcr_next[LIST_TTL]->ldmemcr_prev[LIST_TTL] = 
                                            pCurRes->ldmemcr_prev[LIST_TTL];
       return( LDAP_SUCCESS );
    }

    if (pPrev) {
       if (pHead->ldmemcr_next[LIST_TTL]) {
           pPrev->ldmemcr_htable_next = pHead->ldmemcr_next[LIST_TTL];
           pHead->ldmemcr_next[LIST_TTL]->ldmemcr_htable_next = 
                                        pHead->ldmemcr_htable_next;
       } else {
           pPrev->ldmemcr_htable_next = pHead->ldmemcr_htable_next;
       }
    } else {
       if (pHead->ldmemcr_next[LIST_TTL]) {
           *((ldapmemcacheRes**)ppTableData) = pHead->ldmemcr_next[LIST_TTL];
           pHead->ldmemcr_next[LIST_TTL]->ldmemcr_htable_next = 
                                        pHead->ldmemcr_htable_next;
       } else {
           *((ldapmemcacheRes**)ppTableData) = pHead->ldmemcr_htable_next;
       }
    }
    
    return( LDAP_SUCCESS );
}

Here is the caller graph for this function:


Variable Documentation

unsigned long crc32_table[256] [static]

Definition at line 2139 of file memcache.c.