blob: 9e1e948ffef807db6169c4be0fed76bc029ab5a5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.server.core.api.subtree;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.subtree.Subentry;
/**
* A cache for subtree specifications. It associates a Subentry with a Dn,
* representing its position in the DIT.<br>
* This cache has a size limit set to 1000 at the moment. We should add a configuration
* parameter to manage its size.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class SubentryCache implements Iterable<Dn>
{
/** The default cache size limit */
private static final int DEFAULT_CACHE_MAX_SIZE = 1000;
/** The cache size limit */
private int cacheMaxSize = DEFAULT_CACHE_MAX_SIZE;
/** The current cache size */
private AtomicInteger cacheSize;
/** The Subentry cache */
private final Map<Dn, Subentry> cache;
/**
* Creates a new instance of SubentryCache with a default maximum size.
*/
public SubentryCache()
{
cache = new ConcurrentHashMap<Dn, Subentry>();
cacheSize = new AtomicInteger( 0 );
}
/**
* Creates a new instance of SubentryCache with a specific maximum size.
*/
public SubentryCache( int maxSize )
{
cache = new ConcurrentHashMap<Dn, Subentry>();
cacheSize = new AtomicInteger( 0 );
cacheMaxSize = maxSize;
}
/**
* Retrieve a Subentry given a Dn. If there is none, null will be returned.
*
* @param dn The Dn we want to get the Subentry for
* @return The found Subentry, or null
*/
public final Subentry getSubentry( Dn dn )
{
return cache.get( dn );
}
/**
* Remove a Subentry for a given Dn
*
* @param dn The Dn for which we want to remove the
* associated Subentry
* @return The removed Subentry, if any
*/
public final Subentry removeSubentry( Dn dn )
{
Subentry oldSubentry = cache.remove( dn );
if ( oldSubentry != null )
{
cacheSize.decrementAndGet();
}
return oldSubentry;
}
/**
* Stores a new Subentry into the cache, associated with a Dn
*
* @param dn The Subentry Dn
* @param ss The SubtreeSpecification
* @param adminRoles The administrative roles for this Subentry
* @return The old Subentry, if any
*/
public Subentry addSubentry( Dn dn, Subentry subentry )
{
if ( cacheSize.get() > cacheMaxSize )
{
// TODO : Throw an exception here
}
Subentry oldSubentry = cache.put( dn, subentry );
if ( oldSubentry == null )
{
cacheSize.getAndIncrement();
}
return oldSubentry;
}
/**
* Tells if there is a Subentry associated with a Dn
* @param dn The Dn
* @return True if a Subentry is found
*/
public boolean hasSubentry( Dn dn )
{
return cache.containsKey( dn );
}
/**
* @return An Iterator over the Subentry's DNs
*/
public Iterator<Dn> iterator()
{
return cache.keySet().iterator();
}
/**
* @return The number of elements in the cache
*/
public int getCacheSize()
{
return cacheSize.get();
}
}