/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
package netscape.ldap;
import java.util.*;
import java.io.*;
import netscape.ldap.*;
import netscape.ldap.client.*;
import netscape.ldap.util.*;
import java.util.zip.CRC32;
/**
* LDAPCache is the class that represents an
* in-memory cache that you can use to reduce the number of
* search requests sent to the LDAP server.
*
* * Each item in the cache represents a search request and * its results. Each item is uniquely identified by the * search criteria, which includes: *
* *
* * After a search request is cached, the results of any * subsequent search requests using the same criteria are 8 * read from the cache. Note that if any part of the * criteria differs (for example, if a different DN is used * when binding to the server or if a different set of * attributes to be returned is specified), the search * request is sent to the server. *
* * When you create the cache, you specify the maximum amount * of time that an item can be kept in the cache. When an * item's age exceeds that time limit, the item is removed * from the cache. *
* * The cache also has a maximum size that you specify when * creating the cache. If adding a new item exceeds the * maximum size of the cache, the first entries in the cache * are removed to make enough space for the new item. *
*
* Finally, when creating the cache, you can specify a list
* of the base DNs in search requests that you want to cache.
* For example, if you specify o=Airius.com as
* a base DN to cache, your client caches search requests
* where the base DN is o=Airius.com.
*
*
* To specify that you want to use a cache for a particular
* LDAP session, call the setCache method of
* the LDAPConnection object that you are
* working with.
*
*
* All clones of an LDAPConnection object share
* the same LDAPCache object.
*
*
* The LDAPCache class includes methods for
* getting statistics (such as hit rates) from the cache and
* for flushing entries from the cache.
*
*
* @see netscape.ldap.LDAPConnection#setCache(netscape.ldap.LDAPCache)
* @see netscape.ldap.LDAPConnection#getCache
*/
public class LDAPCache implements TimerEventListener {
private Hashtable m_cache;
private long m_timeToLive;
private long m_maxSize;
private String[] m_dns;
private Vector m_orderedStruct;
private long m_remainingSize = 0;
/**
* Delimiter used internally when creating keys
* for the cache.
*/
public static final String DELIM = "#";
private Timer m_timer = null;
private static long TIMEOUT = 60000;
private long m_totalOpers = 0;
private static final boolean m_debug = false;
private long m_hits = 0;
private long m_flushes = 0;
/**
* Constructs a new LDAPCache object, using the
* specified maximum size of the cache (in bytes) and the maximum
* age of cached items (in seconds). When items in the cache
* exceed this age, they are removed from the cache.
*
*
* @param ttl The maximum amount of time that an item can be cached
* (in seconds)
* @param size The maximum size of the cache (in bytes)
*/
public LDAPCache(long ttl, long size)
{
init(ttl, size);
}
/**
* Constructs a new LDAPCache object, using the
* specified maximum size of the cache (in bytes), and the maximum
* age of cached items (in seconds), and an array of the base DNs
* of searches that you want to cache. (For example,
* if the array of base DNs includes o=Airius.com,
* the cache stores search results if the base DN in the search
* request is o=Airius.com.)
*
*
* @param ttl The maximum amount of time that an item can be cached
* (in seconds)
* @param size The maximum size of the cache (in bytes)
* @param dns The list of base DNs of searches that you want to cache.
*/
public LDAPCache(long ttl, long size, String[] dns)
{
init(ttl, size);
m_dns = new String[dns.length];
if ((dns != null) && (dns.length > 0))
for (int i=0; i
*
* @return The maximum age of items in the cache (in
* seconds).
*/
public long getTimeToLive()
{
return m_timeToLive/1000;
}
/**
* Gets the array of base DNs of searches to be cached.
* (Search requests with these base DNs are cached.)
*
*
* @return The array of base DNs.
*/
public String[] getBaseDNs()
{
return m_dns;
}
/**
* Flush the entries identified by DN and scope from the cache.
*
*
* @param dn The distinguished name (or base DN) of the entries
* to be removed from the cache. Use this parameter in conjunction
* with
* @return
*
* @return The available space (in bytes) in the cache.
*/
public long getAvailableSize() {
return m_remainingSize;
}
/**
* Gets the total number of requests for retrieving items from
* the cache. This includes both items successfully found in
* the cache and items not found in the cache.
*
*
* @return The total number of requests for retrieving items from
* the cache.
*/
public long getTotalOperations() {
return m_totalOpers;
}
/**
* Gets the total number of requests which failed to find and
* retrieve an item from the cache.
*
*
* @return The number of requests that did not find and retrieve
* an item in the cache.
*/
public long getNumMisses() {
return (m_totalOpers - m_hits);
}
/**
* Gets the total number of requests which successfully found and
* retrieved an item from the cache.
* @return The number of requests that successfully found and
* retrieved an item from the cache.
*/
public long getNumHits() {
return m_hits;
}
/**
* Gets the total number of entries that are flushed when timer expires
* and
*
* @return The total number of entries that are flushed when timer
* expires.
*/
public long getNumFlushes() {
return m_flushes;
}
/**
* Create a key for a cache entry by concatenating all input parameters
* @return The key for a cache entry
* @exception LDAPException Thrown when failed to create key.
*/
Long createKey(String host, int port, String baseDN, String filter,
int scope, String[] attrs, String bindDN, LDAPSearchConstraints cons)
throws LDAPException {
DN dn = new DN(baseDN);
baseDN = dn.toString();
if (m_dns != null) {
int i=0;
for (; iscope to identify the entries that you want
* removed from the cache. If this parameter is null,
* the entire cache is flushed.
* @param scope The scope identifying the entries that you want
* removed from the cache. The value of this parameter can be
* one of the following:
*
*
* LDAPv2.SCOPE_BASE (to remove the entry identified
* by dn)
* LDAPv2.SCOPE_ONE (to remove the entries that
* have dn as their parent entry)
* LDAPv2.SCOPE_SUB (to remove the entries in the
* subtree under dn in the directory)
* true if the entry is removed from the cache,
* or false if the entry is not removed.
*/
public synchronized boolean flushEntries(String dn, int scope) {
if (m_debug)
System.out.println("DEBUG: User request for flushing entry: dn "+
dn+" and scope "+scope);
// if the dn is null, invalidate the whole cache
if (dn == null)
{
// reclaim all the cache spaces
m_remainingSize = m_maxSize;
m_cache.clear();
m_orderedStruct.removeAllElements();
return true;
}
DN dn2 = new DN(dn);
Enumeration e = m_cache.keys();
while(e.hasMoreElements()) {
Long key = (Long)e.nextElement();
Vector val = (Vector)m_cache.get(key);
int j=1;
int size2=val.size();
for (; jflushEntries is called.
*