head	1.19;
access;
symbols;
locks; strict;
comment	@# @;


1.19
date	2001.08.11.09.08.09;	author dlr;	state Exp;
branches;
next	1.18;

1.18
date	2001.06.14.21.15.22;	author leonardr;	state Exp;
branches;
next	1.17;

1.17
date	2001.06.08.21.52.09;	author leonardr;	state Exp;
branches;
next	1.16;

1.16
date	2001.06.08.20.44.45;	author leonardr;	state Exp;
branches;
next	1.15;

1.15
date	2001.06.07.01.58.20;	author leonardr;	state Exp;
branches;
next	1.14;

1.14
date	2001.05.30.20.15.25;	author leonardr;	state Exp;
branches;
next	1.13;

1.13
date	2001.05.25.01.45.29;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.05.23.00.35.00;	author leonardr;	state Exp;
branches;
next	1.11;

1.11
date	2001.05.22.00.14.19;	author leonardr;	state Exp;
branches;
next	1.10;

1.10
date	2001.05.21.21.06.01;	author leonardr;	state Exp;
branches;
next	1.9;

1.9
date	2001.05.11.19.38.56;	author leonardr;	state Exp;
branches;
next	1.8;

1.8
date	2001.04.20.15.30.21;	author dlr;	state Exp;
branches;
next	1.7;

1.7
date	2001.04.12.18.49.01;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2001.04.12.05.17.47;	author dlr;	state Exp;
branches;
next	1.5;

1.5
date	2001.04.12.04.41.06;	author leonardr;	state Exp;
branches;
next	1.4;

1.4
date	2001.04.12.02.08.56;	author dlr;	state Exp;
branches;
next	1.3;

1.3
date	2001.04.12.01.34.42;	author dlr;	state Exp;
branches;
next	1.2;

1.2
date	2001.04.07.06.59.09;	author dlr;	state Exp;
branches;
next	1.1;

1.1
date	2001.04.07.06.47.54;	author dlr;	state Exp;
branches;
next	;


desc
@@


1.19
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@/* ================================================================
 * Copyright (c) 2001 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.collab.net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */

package org.tigris.helm.tool.cache;

import java.util.Iterator;
import java.util.Map;
import java.rmi.RemoteException;

import org.apache.turbine.util.Log;
import org.apache.commons.util.BufferCache;

import org.tigris.helm.tool.cluster.*;
import org.tigris.helm.om.*;

/**
 * A {@@link org.tigris.helm.tool.RegisterableCache} with support for a
 * single cache interested in saves to specified database tables.
 *
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@version $Id: SimpleRegisterableCache.java,v 1.18 2001/06/14 21:15:22 leonardr Exp $ 
 */
public class SimpleRegisterableCache extends RegisterableCache
{
    /**
     * Flag indicating whether in debug mode.
     */
    private static final boolean DEBUG = false;

    /**
     * The encapsulated object cache.
     */
    private Map cache;

    /**
     * Registers with this JVM's {@@link
     * org.tigris.helm.tool.cache.CacheRegistry} as being interested
     * in the specified class. The cache created will be a BufferCache
     * of the specified size.
     */
    public SimpleRegisterableCache
        (String name, Class interestingDescriptor, int bufferCacheSize)
    {
        super(name, interestingDescriptor);
        this.cache = new BufferCache(bufferCacheSize);
    }

    /**
     * Registers with this JVM's {@@link
     * org.tigris.helm.tool.cache.CacheRegistry} as being interested
     * in the specified table. The cache is the one provided.
     */
    public SimpleRegisterableCache
        (String name, Class interestingDescriptor, Map cache)
    {
        super(name, interestingDescriptor);
        this.cache = cache;
    }

    /**
     * Registers with this JVM's {@@link
     * org.tigris.helm.tool.cache.CacheRegistry} as being interested
     * in the specified tables. The cache is the one provided.
     */
    public SimpleRegisterableCache
        (String name, Class[] interestingDescriptors, Map cache)
    {
        super(name, interestingDescriptors);
        this.cache = cache;
    }

    /**
     * Returns the encapsulated object cache.
     */
    public Map getCache()
    {
        return cache;
    }

    /**
     * Describes the keys currently cached.
     */
    public String describeContents()
    {
        StringBuffer buf = new StringBuffer("\n Currently cached entries:\n");
        Object[] keys = cache.keySet().toArray();
        for (int i = 0; i < keys.length; i++)
        {        
            Object key = keys[i];
            buf.append("  ").append(key.toString()).append('\n');
        }
        return buf.toString();
    }

    /**
     * Invalidates some portion of the cache.
     *
     * @@param invalidationDescriptor Description of the invalidation that 
     *                               should occur, or <code>null</code> for
     *                               complete invalidation.
     */
    public void invalidate()
        throws Exception
    {
        super.invalidate();
        if (DEBUG)
        {
            synchronized (cache)
            {
                StringBuffer buf = new StringBuffer
                    ("Invalidating the following cache: \n")
                    .append(describe());
                Log.debug(buf.toString());
            }
        }
        else
        {
            cache.clear();
            if (cache instanceof TableTrackingBufferCache)
            {
                ((TableTrackingBufferCache)cache).resize();
            }
        }
    }
}
@


1.18
log
@Put TableTrackingBufferCache into practice; hopefully I can soon replace it with something smarter.
@
text
@d54 1
a54 1
import org.apache.turbine.util.BufferCache;
d65 1
a65 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.17 2001/06/08 21:52:09 leonardr Exp $ 
@


1.17
log
@Added ability for caches to keep track of number of invalidations.
@
text
@d54 1
d65 1
a65 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.16 2001/06/08 20:44:45 leonardr Exp $ 
d80 4
a83 4
     * Registers with this JVM's {@@link org.tigris.helm.tool.CacheRegistry},
     * using the provided {@@link java.lang.Class} instance's name as the key.
     *
     * The cache will be a BufferCache
d85 2
a86 2
    public SimpleRegisterableCache(String name, Class key, String table, 
                                   double proportionalSize)
d88 2
a89 2
        super(name, key);
        this.cache = cache;
d93 3
a95 2
     * Registers with this JVM's {@@link org.tigris.helm.tool.CacheRegistry},
     * using the provided {@@link java.lang.Class} instance's name as the key.
d97 2
a98 1
    public SimpleRegisterableCache(String name, Class key, Map cache)
d100 1
a100 1
        super(name, key);
d105 3
a107 2
     * Registers with this JVM's 
     * {@@link org.tigris.helm.tool.cache.CacheRegistry}.
d109 2
a110 2
    public SimpleRegisterableCache(String name, 
                                   Class[] interestingDescriptors, Map cache)
a134 1
            cache.remove(key);
@


1.16
log
@Bugfixes and debugging cleanup.
@
text
@d64 1
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.15 2001/06/07 01:58:20 leonardr Exp $ 
d146 1
@


1.15
log
@Added placeholder HelmService interface.
@
text
@d64 1
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.14 2001/05/30 20:15:25 leonardr Exp $ 
d144 1
d159 4
@


1.14
log
@Big cleanup of cache self-descriptions. Also added an admin tool to do manual selective cache invalidation.
@
text
@d64 1
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.13 2001/05/25 01:45:29 leonardr Exp $ 
d77 13
@


1.13
log
@Finally got rid of REQUESTABLE and DENOTES_OWNER fields in HELM_ROLE.
@
text
@d64 1
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.12 2001/05/23 00:35:00 leonardr Exp $ 
d112 1
a112 1
        StringBuffer buf = new StringBuffer("Currently cached entries: ");
d117 1
a117 2
            if (i > 0) buf.append(", ");
            buf.append(key.toString());
@


1.12
log
@Cleanup of caching and cache invalidation.
@
text
@d64 1
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.11 2001/05/22 00:14:19 leonardr Exp $ 
d112 1
a112 1
        StringBuffer buf = new StringBuffer();
@


1.11
log
@Bug fixes for clustering.
@
text
@d32 1
a32 1
 * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
d59 2
a60 1
 * A {@@link org.tigris.helm.tool.RegisterableCache} with support for one cache.
d63 2
a64 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.10 2001/05/21 21:06:01 leonardr Exp $
d82 1
a82 2
    public SimpleRegisterableCache(Class key, Map cache)
        throws RemoteException
d84 1
a84 1
        super(key);
d92 2
a93 1
    public SimpleRegisterableCache(String[] interestingDescriptors, Map cache)
d95 1
a95 1
        super(interestingDescriptors);
d108 17
d137 3
a139 10
                StringBuffer buf =
                    new StringBuffer("invalidating cache: ");
                Object[] userKeys = cache.keySet().toArray();
                for (int i = 0; i < userKeys.length; i++)
                {
                    Object key = userKeys[i];
                    if (i > 0) buf.append(", ");
                    buf.append(key.toString());
                    cache.remove(key);
                }
@


1.10
log
@Moved clustering features out of RMI and into the database.
@
text
@d62 1
a62 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.9 2001/05/11 19:38:56 leonardr Exp $
d84 10
@


1.9
log
@A Heartbreaking Patch of Staggering Genius: adds capacity (but no interface) for deeply nested projects, categories, and project groups. As a side effect, gets rid of the hacky special 'all public projects in domain' group. There are probably bugs in this, and some of those bugs are probably security holes, so watch out.
@
text
@d62 1
a62 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.8 2001/04/20 15:30:21 dlr Exp $
a76 10
     * Registers with this JVM's {@@link org.tigris.helm.tool.CacheRegistry}.
     */
    public SimpleRegisterableCache(Object key, Map cache)
        throws RemoteException
    {
        super(key);
        this.cache = cache;
    }

    /**
d83 2
a84 1
        this(key.getName(), cache);
a95 42
     * Returns true if the invalidation descriptor means that this
     * cache must be invalidated.
     */
    protected boolean affectedByInvalidation(Object invalidationDescriptor)
    {
        boolean affects = false;
        if (invalidationDescriptor == null)
        {
            if (DEBUG) 
            {
                Log.debug("invalidationDescriptor is null, so " 
                          + "SimpleRegisterableCache with key " + key
                          + " is affected.");
            }
            affects = true;
        }
        else if (invalidationDescriptor instanceof String)
        {
            String objectClassName = (String)invalidationDescriptor;
            String peerClassName = objectClassName + "Peer";
            if (peerClassName.equals(key))
            {
                if (DEBUG) 
                {
                    Log.debug("SimpleRegisterableCache with key " + key
                              + " is affected.");
                }
                affects = true;
            }
            else
            {
                if (DEBUG)
                {
                    Log.debug("SimpleRegisterableCache with key " + key
                              + " is not affected.");
                }
            }                      
        }
        return affects;
    }

    /**
d102 1
a102 1
    public void invalidate(Object invalidationDescriptor)
d104 1
a104 1
        if (affectedByInvalidation(invalidationDescriptor))
d106 1
a106 1
            if (DEBUG)
d108 4
a111 1
                synchronized (cache)
d113 4
a116 11
                    StringBuffer buf =
                        new StringBuffer(key + " invalidating cache: ");
                    Object[] userKeys = cache.keySet().toArray();
                    for (int i = 0; i < userKeys.length; i++)
                    {
                        Object key = userKeys[i];
                        if (i > 0) buf.append(", ");
                        buf.append(key.toString());
                        cache.remove(key);
                    }
                    Log.debug(buf.toString());
d118 1
d120 4
a123 4
            else
            {
                cache.clear();
            }
@


1.8
log
@Added semi-selective cache invalidation which invalidates particular caches on a write instead of all the caches.
@
text
@d55 2
a56 1
import org.tigris.helm.tool.cluster.ClusterObject;
d62 1
a62 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.7 2001/04/12 18:49:01 leonardr Exp $
@


1.7
log
@Caching fixes and additions.
@
text
@d61 1
a61 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.6 2001/04/12 05:17:47 dlr Exp $
d68 1
a68 1
    private static final boolean DEBUG = true;
d104 42
d154 1
a154 1
        if (invalidationDescriptor == null)
a176 6
        }
        else
        {
            throw new UnsupportedOperationException
                ("SimpleRegisterableCache.invalidate() does not currently " + 
                 "support a descriptor");
@


1.6
log
@Refactored invalidate(Object descriptor) to be more like UserPeer's
implementation of RegisterableCache.
@
text
@d61 1
a61 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.5 2001/04/12 04:41:06 leonardr Exp $
d123 1
a123 1
                        String key = (String) userKeys[i];
d125 1
a125 1
                        buf.append(key);
@


1.5
log
@Added debugging code and moved RARPeer and ProjectPeer to the new caching system.
@
text
@d61 1
a61 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.4 2001/04/12 02:08:56 dlr Exp $
d65 8
d114 1
a114 1
            synchronized(cache)
d116 1
a116 1
                for (Iterator keys = cache.keySet().iterator(); keys.hasNext(); )
d118 11
a128 3
                    Object key = keys.next();
                    Log.debug("SimpleRegisterableCache removing " + key.toString());
                    cache.remove(key);
d130 4
@


1.4
log
@* Added addition ctor which extracts the specified Class's name to use
as the cache key.

* Added cache accessor method.
@
text
@d53 2
d61 1
a61 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.3 2001/04/12 01:34:42 dlr Exp $
d106 1
a106 1
            for (Iterator keys = cache.keySet().iterator(); keys.hasNext(); )
d108 6
a113 1
                cache.remove(keys.next());
@


1.3
log
@Use a key other than Class.
@
text
@d59 1
a59 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.2 2001/04/07 06:59:09 dlr Exp $
d73 18
@


1.2
log
@Moved if/else test outside of for loop in invalidate() impl, and
removed unnecessary local variable.
@
text
@d59 1
a59 1
 * @@version $Id: SimpleRegisterableCache.java,v 1.1 2001/04/07 06:47:54 dlr Exp $
d68 1
a68 1
    public SimpleRegisterableCache(Class key, Map cache)
@


1.1
log
@A RegisterableCache with support for a single cache.
@
text
@d59 1
a59 1
 * @@version $Id: $
d84 1
a84 1
        for (Iterator iter = cache.keySet().iterator(); iter.hasNext(); )
d86 1
a86 2
            Object key = iter.next();
            if (invalidationDescriptor == null)
d88 1
a88 7
                cache.remove(key);
            }
            else
            {
                throw new UnsupportedOperationException
                    ("SimpleRegisterableCache.invalidate() does not " + 
                     "currently support a descriptor");
d90 6
@

