cziegeler    2003/08/25 02:50:57

  Modified:    store/src/java/org/apache/excalibur/store/impl
                        AbstractFilesystemStore.java
                        AbstractJispFilesystemStore.java
  Added:       store/src/java/org/apache/excalibur/store/impl
                        AbstractReadWriteStore.java
  Log:
  Better synchronization of the File Store
  
  Revision  Changes    Path
  1.11      +179 -103  
avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/AbstractFilesystemStore.java
  
  Index: AbstractFilesystemStore.java
  ===================================================================
  RCS file: 
/home/cvs/avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/AbstractFilesystemStore.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- AbstractFilesystemStore.java      29 Jul 2003 03:58:33 -0000      1.10
  +++ AbstractFilesystemStore.java      25 Aug 2003 09:50:56 -0000      1.11
  @@ -49,23 +49,12 @@
   */
   package org.apache.excalibur.store.impl;
   
  -import java.io.BufferedInputStream;
  -import java.io.BufferedOutputStream;
  -import java.io.ByteArrayOutputStream;
  -import java.io.File;
  -import java.io.FileInputStream;
  -import java.io.FileOutputStream;
  -import java.io.FileReader;
  -import java.io.FileWriter;
  -import java.io.IOException;
  -import java.io.ObjectInputStream;
  -import java.io.ObjectOutputStream;
  -import java.io.OutputStreamWriter;
  -import java.io.Writer;
  +import java.io.*;
   import java.util.BitSet;
   import java.util.Enumeration;
   
  -import org.apache.avalon.framework.logger.AbstractLogEnabled;
  +import EDU.oswego.cs.dl.util.concurrent.Sync;
  +
   import org.apache.avalon.framework.thread.ThreadSafe;
   import org.apache.excalibur.store.Store;
   
  @@ -76,10 +65,11 @@
    *
    * @author ?
    * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
   public abstract class AbstractFilesystemStore
  -extends AbstractLogEnabled
  +extends AbstractReadWriteStore
   implements Store, ThreadSafe {
   
       /** The directory repository */
  @@ -90,7 +80,8 @@
        * Sets the repository's location
        */
       public void setDirectory(final String directory)
  -    throws IOException {
  +    throws IOException 
  +    {
           this.setDirectory(new File(directory));
       }
   
  @@ -98,7 +89,8 @@
        * Sets the repository's location
        */
       public void setDirectory(final File directory)
  -    throws IOException {
  +    throws IOException 
  +    {
           this.m_directoryFile = directory;
   
           /* Save directory path prefix */
  @@ -106,21 +98,25 @@
           this.m_directoryPath += File.separator;
   
           /* Does directory exist? */
  -        if (!this.m_directoryFile.exists()) {
  +        if (!this.m_directoryFile.exists()) 
  +        {
               /* Create it anew */
  -            if (!this.m_directoryFile.mkdir()) {
  +            if (!this.m_directoryFile.mkdir()) 
  +            {
                   throw new IOException(
                   "Error creating store directory '" + this.m_directoryPath + "': ");
               }
           }
   
           /* Is given file actually a directory? */
  -        if (!this.m_directoryFile.isDirectory()) {
  +        if (!this.m_directoryFile.isDirectory()) 
  +        {
               throw new IOException("'" + this.m_directoryPath + "' is not a 
directory");
           }
   
           /* Is directory readable and writable? */
  -        if (!(this.m_directoryFile.canRead() && this.m_directoryFile.canWrite())) {
  +        if (!(this.m_directoryFile.canRead() && this.m_directoryFile.canWrite())) 
  +        {
               throw new IOException(
                   "Directory '" + this.m_directoryPath + "' is not readable/writable"
               );
  @@ -130,27 +126,36 @@
       /**
        * Returns the repository's full pathname
        */
  -    public String getDirectoryPath() {
  +    public String getDirectoryPath() 
  +    {
           return this.m_directoryPath;
       }
   
       /**
        * Get the File object associated with the given unique key name.
        */
  -    public synchronized Object get(final Object key) {
  +    protected Object doGet(final Object key) 
  +    {
           final File file = fileFromKey(key);
   
  -        if (file != null && file.exists()) {
  -            if (getLogger().isDebugEnabled()) {
  +        if (file != null && file.exists()) 
  +        {
  +            if (getLogger().isDebugEnabled()) 
  +            {
                   getLogger().debug("Found file: " + key);
               }
  -            try {
  +            try 
  +            {
                   return this.deserializeObject(file);
  -            } catch (Exception any) {
  +            } 
  +            catch (Exception any) {
                   getLogger().error("Error during deseralization.", any);
               }
  -        } else {
  -            if (getLogger().isDebugEnabled()) {
  +        } 
  +        else 
  +        {
  +            if (getLogger().isDebugEnabled()) 
  +            {
                   getLogger().debug("NOT Found file: " + key);
               }
           }
  @@ -164,53 +169,52 @@
        * 2) String values are dumped to text files
        * 3) Object values are serialized
        */
  -    public synchronized void store(final Object key, final Object value)
  -    throws IOException {
  +    protected void doStore(final Object key, final Object value)
  +    throws IOException
  +     {
           final File file = fileFromKey(key);
   
           /* Create subdirectories as needed */
           final File parent = file.getParentFile();
  -        if (parent != null) {
  +        if (parent != null) 
  +        {
               parent.mkdirs();
           }
   
           /* Store object as file */
  -        if (value == null) { /* Directory */
  -            if (file.exists()) {
  -                if (!file.delete()) { /* FAILURE */
  +        if (value == null) 
  +        { /* Directory */
  +            if (file.exists()) 
  +            {
  +                if (!file.delete()) 
  +                { /* FAILURE */
                       getLogger().error("File cannot be deleted: " + file.toString());
                       return;
                   }
               }
   
               file.mkdir();
  -        } else if (value instanceof String) {
  +        } 
  +        else if (value instanceof String) 
  +        {
               /* Text file */
               this.serializeString(file, (String) value);
  -        } else {
  +        } 
  +        else 
  +        {
               /* Serialized Object */
               this.serializeObject(file, value);
           }
       }
   
       /**
  -     * Holds the given object in a volatile state.
  -     */
  -    public synchronized void hold(final Object key, final Object value)
  -    throws IOException {
  -        this.store(key, value);
  -        final File file = (File) this.fileFromKey(key);
  -        if (file != null) {
  -          file.deleteOnExit();
  -        }
  -    }
  -
  -    /**
        * Remove the object associated to the given key.
        */
  -    public synchronized void remove(final Object key) {
  +    protected void doRemove(final Object key) 
  +    {
           final File file = fileFromKey(key);
  -        if (file != null) {
  +        if (file != null) 
  +        {
               file.delete();
           }
       }
  @@ -218,23 +222,28 @@
       /**
        * Clear the Store of all elements 
        */
  -    public synchronized void clear() {
  -                Enumeration enum = this.keys();
  -                while (enum.hasMoreElements()) {
  -                    Object key = enum.nextElement();
  -                    if (key == null) {
  -                        continue;
  -                    }
  -                        this.remove(key);
  -                 }
  +    protected void doClear() 
  +    {
  +        Enumeration enum = this.keys();
  +        while (enum.hasMoreElements()) 
  +        {
  +            Object key = enum.nextElement();
  +            if (key == null) 
  +            {
  +                continue;
  +            }
  +            this.remove(key);
  +        }
       }
   
       /**
        * Indicates if the given key is associated to a contained object.
        */
  -    public synchronized boolean containsKey(final Object key) {
  +    protected boolean doContainsKey(final Object key) 
  +    {
           final File file = fileFromKey(key);
  -        if (file == null) {
  +        if (file == null) 
  +        {
               return false;
           }
           return file.exists();
  @@ -243,7 +252,8 @@
       /**
        * Returns the list of stored files as an Enumeration of Files
        */
  -    public synchronized Enumeration keys() {
  +    protected Enumeration doGetKeys() 
  +    {
           final FSEnumeration enum = new FSEnumeration();
           this.addKeys(enum, this.m_directoryFile);
           return enum;
  @@ -253,48 +263,63 @@
        * Returns count of the objects in the store, or -1 if could not be
        * obtained.
        */
  -    public synchronized int size() {
  +    protected int doGetSize() 
  +    {
           return countKeys(this.m_directoryFile);
       }
   
  -    protected void addKeys(FSEnumeration enum, File directory) {
  +    protected void addKeys(FSEnumeration enum, File directory) 
  +    {
           final int subStringBegin = this.m_directoryFile.getAbsolutePath().length() 
+ 1;
           final File[] files = directory.listFiles();
  -        for (int i=0; i<files.length; i++) {
  -            if (files[i].isDirectory()) {
  +        for (int i=0; i<files.length; i++)
  +         {
  +            if (files[i].isDirectory()) 
  +            {
                   this.addKeys(enum, files[i]);
  -            } else {
  +            } 
  +            else 
  +            {
                   
enum.add(this.decode(files[i].getAbsolutePath().substring(subStringBegin)));
               }
           }
       }
   
  -    protected int countKeys(File directory) {
  +    protected int countKeys(File directory) 
  +    {
           int count = 0;
           final File[] files = directory.listFiles();
  -        for (int i=0; i<files.length; i++) {
  -            if (files[i].isDirectory()) {
  +        for (int i=0; i<files.length; i++) 
  +        {
  +            if (files[i].isDirectory()) 
  +            {
                   count += this.countKeys(files[i]);
  -            } else {
  +            } 
  +            else 
  +            {
                   count ++;
               }
           }
           return count;
       }
   
  -    final class FSEnumeration implements Enumeration {
  +    final class FSEnumeration implements Enumeration 
  +    {
           private String[] array;
           private int      index;
           private int      length;
   
  -        FSEnumeration() {
  +        FSEnumeration() 
  +        {
               this.array = new String[16];
               this.length = 0;
               this.index = 0;
           }
   
  -        public void add(String key) {
  -            if (this.length == array.length) {
  +        public void add(String key) 
  +        {
  +            if (this.length == array.length) 
  +            {
                   String[] newarray = new String[this.length + 16];
                   System.arraycopy(this.array, 0, newarray, 0, this.array.length);
                   this.array = newarray;
  @@ -303,12 +328,15 @@
               this.length++;
           }
   
  -        public boolean hasMoreElements() {
  +        public boolean hasMoreElements() 
  +        {
               return (this.index < this.length);
           }
   
  -        public Object nextElement() {
  -            if (this.hasMoreElements()) {
  +        public Object nextElement() 
  +        {
  +            if (this.hasMoreElements()) 
  +            {
                   this.index++;
                   return this.array[index-1];
               }
  @@ -317,7 +345,8 @@
       }
   
       /* Utility Methods*/
  -    protected File fileFromKey(final Object key) {
  +    protected File fileFromKey(final Object key) 
  +    {
           File file = new File(this.m_directoryFile, this.encode(key.toString()));
           File parent = file.getParentFile();
           if (parent != null) parent.mkdirs();
  @@ -325,25 +354,53 @@
       }
   
       public String getString(final Object key)
  -    throws IOException {
  +    throws IOException 
  +    {
           final File file = (File) this.fileFromKey(key);
  -        if (file != null) {
  +        if (file != null) 
  +        {
               return this.deserializeString(file);
           }
   
           return null;
       }
   
  -    public synchronized void free() {}
  +    public void free() 
  +    {
  +        // if we ever implement this, we should implement doFree()
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.excalibur.store.impl.AbstractReadWriteStore#doFree()
  +     */
  +    protected void doFree() 
  +    {
  +    }
   
       public synchronized Object getObject(final Object key)
       throws IOException, ClassNotFoundException
       {
  -        final File file = (File) this.fileFromKey(key);
  -        if (file != null) {
  -            return this.deserializeObject(file);
  +        Object value = null;
  +        Sync sync = this.lock.writeLock();
  +        try
  +        {
  +            sync.acquire();
  +            try 
  +            {
  +                final File file = (File) this.fileFromKey(key);
  +                if (file != null) {
  +                    return this.deserializeObject(file);
  +                }
  +            }
  +            finally 
  +            {
  +                sync.release();
  +            }
           }
  -
  +        catch (InterruptedException ignore)
  +        {
  +        } 
  +        
           return null;
       }
   
  @@ -357,7 +414,8 @@
       {
           // if the key is longer than 127 bytes a File.separator
           // is added each 127 bytes
  -        if (filename.length() > 127) {
  +        if (filename.length() > 127) 
  +        {
               int c = filename.length() / 127;
               int pos = c * 127;
               StringBuffer out = new StringBuffer(filename);
  @@ -407,7 +465,8 @@
        * it may normally happen). For this reason, it's highly recommended
        * (even if not mandated) that Strings be used as keys.
        */
  -    protected String encode(String s) {
  +    protected String encode(String s) 
  +    {
           final StringBuffer out = new StringBuffer( s.length() );
           final ByteArrayOutputStream buf = new ByteArrayOutputStream( 32 );
           final OutputStreamWriter writer = new OutputStreamWriter( buf );
  @@ -471,12 +530,16 @@
        * @exception IOException IO Error
        */
       public void serializeString(File file, String string)
  -    throws IOException {
  +    throws IOException 
  +    {
           final Writer fw = new FileWriter(file);
  -        try {
  +        try 
  +        {
               fw.write(string);
               fw.flush();
  -        } finally {
  +        } 
  +        finally 
  +        {
               if (fw != null) fw.close();
           }
       }
  @@ -490,16 +553,21 @@
        * @exception IOException IO Error
        */
       public String deserializeString(File file)
  -    throws IOException {
  +    throws IOException 
  +    {
           int len;
           char[] chr = new char[4096];
           final StringBuffer buffer = new StringBuffer();
           final FileReader reader = new FileReader(file);
  -        try {
  -            while ((len = reader.read(chr)) > 0) {
  +        try 
  +        {
  +            while ((len = reader.read(chr)) > 0) 
  +            {
                   buffer.append(chr, 0, len);
               }
  -        } finally {
  +        } 
  +        finally 
  +        {
               if (reader != null) reader.close();
           }
           return buffer.toString();
  @@ -514,13 +582,17 @@
        */
   
       public void serializeObject(File file, Object object)
  -    throws IOException {
  +    throws IOException 
  +    {
           FileOutputStream fos = new FileOutputStream(file);
  -        try {
  +        try 
  +        {
               ObjectOutputStream oos = new ObjectOutputStream(new 
BufferedOutputStream(fos));
               oos.writeObject(object);
               oos.flush();
  -        } finally {
  +        } 
  +        finally 
  +        {
               if (fos != null) fos.close();
           }
       }
  @@ -533,13 +605,17 @@
        * @exception IOException IOError
        */
       public Object deserializeObject(File file)
  -    throws IOException, ClassNotFoundException {
  +    throws IOException, ClassNotFoundException 
  +    {
           FileInputStream fis = new FileInputStream(file);
           Object object = null;
  -        try {
  +        try 
  +        {
               ObjectInputStream ois = new ObjectInputStream(new 
BufferedInputStream(fis));
               object = ois.readObject();
  -        } finally {
  +        } 
  +        finally 
  +        {
               if (fis != null) fis.close();
           }
           return object;
  
  
  
  1.18      +75 -149   
avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/AbstractJispFilesystemStore.java
  
  Index: AbstractJispFilesystemStore.java
  ===================================================================
  RCS file: 
/home/cvs/avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/AbstractJispFilesystemStore.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- AbstractJispFilesystemStore.java  25 Aug 2003 09:20:30 -0000      1.17
  +++ AbstractJispFilesystemStore.java  25 Aug 2003 09:50:56 -0000      1.18
  @@ -62,14 +62,9 @@
   import com.coyotegulch.jisp.KeyNotFound;
   import com.coyotegulch.jisp.KeyObject;
   
  -import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.thread.ThreadSafe;
   import org.apache.excalibur.store.Store;
   
  -import EDU.oswego.cs.dl.util.concurrent.FIFOReadWriteLock;
  -import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
  -import EDU.oswego.cs.dl.util.concurrent.Sync;
  -
   /**
    * This store is based on the Jisp library
    * (http://www.coyotegulch.com/jisp/index.html). This store uses B-Tree indexes
  @@ -81,7 +76,7 @@
    * @version CVS $Id$
    */
   public abstract class AbstractJispFilesystemStore
  -extends AbstractLogEnabled
  +extends AbstractReadWriteStore
   implements Store, ThreadSafe {
   
       /** The directory repository */
  @@ -93,9 +88,6 @@
       /** And the index */
       protected BTreeIndex m_Index;
   
  -    /** The lock */
  -    protected ReadWriteLock lock = new FIFOReadWriteLock();
  -    
       /**
        * Sets the repository's location
        */
  @@ -136,40 +128,29 @@
        * @param key the Key object
        * @return the Object associated with Key Object
        */
  -    public Object get(Object key) 
  +    protected Object doGet(Object key) 
       {
           Object value = null;
  -        Sync sync = this.lock.writeLock();
  -        try
  +
  +        try 
           {
  -            sync.acquire();
  -            try 
  +            value = m_Database.read(this.wrapKeyObject(key), m_Index);
  +            if (getLogger().isDebugEnabled()) 
               {
  -                value = m_Database.read(this.wrapKeyObject(key), m_Index);
  -                if (getLogger().isDebugEnabled()) 
  +                if (value != null) 
                   {
  -                    if (value != null) 
  -                    {
  -                        getLogger().debug("Found key: " + key);
  -                    } 
  -                    else 
  -                    {
  -                        getLogger().debug("NOT Found key: " + key);
  -                    }
  +                    getLogger().debug("Found key: " + key);
  +                } 
  +                else 
  +                {
  +                    getLogger().debug("NOT Found key: " + key);
                   }
  -            } 
  -            catch (Exception e) 
  -            {
  -                getLogger().error("get(..): Exception", e);
  -            }
  -            finally 
  -            {
  -                sync.release();
               }
  -        }
  -        catch (InterruptedException ignore)
  -        {
           } 
  +        catch (Exception e) 
  +        {
  +            getLogger().error("get(..): Exception", e);
  +        }
           
           return value;
       }
  @@ -181,7 +162,7 @@
        * @param value the value object
        * @exception  IOException
        */
  -    public void store(Object key, Object value)
  +    protected void doStore(Object key, Object value)
       throws IOException 
       {
   
  @@ -195,29 +176,16 @@
   
           if (value instanceof Serializable) 
           {
  -            Sync sync = this.lock.writeLock();
  -            try
  -            {
  -                sync.acquire();
  -
  -                try 
  -                {
  -                    KeyObject[] keyArray = new KeyObject[1];
  -                    keyArray[0] = this.wrapKeyObject(key);
  -                    m_Database.write(keyArray, (Serializable) value);
  -                } 
  -                catch (Exception e) 
  -                {
  -                    getLogger().error("store(..): Exception", e);
  -                }
  -                finally 
  -                {
  -                    sync.release();
  -                }
  -            }
  -            catch (InterruptedException ignore)
  +            try 
               {
  +                KeyObject[] keyArray = new KeyObject[1];
  +                keyArray[0] = this.wrapKeyObject(key);
  +                m_Database.write(keyArray, (Serializable) value);
               } 
  +            catch (Exception e) 
  +            {
  +                getLogger().error("store(..): Exception", e);
  +            }
           } 
           else 
           {
  @@ -226,31 +194,24 @@
       }
   
       /**
  -     *  Holds the given object in the indexed data file.
  -     *
  -     * @param key the key object
  -     * @param value the value object
  -     * @exception IOException
  -     */
  -    public void hold(Object key, Object value)
  -    throws IOException 
  -    {
  -        // store is synced!
  -        this.store(key, value);
  -    }
  -
  -    /**
        * Frees some values of the data file.<br>
        * TODO: implementation
        */
       public void free() 
       {
  +        // if we ever implement this, we should implement doFree()
  +    }
  +
  +    /* (non-Javadoc)
  +     * @see org.apache.excalibur.store.impl.AbstractReadWriteStore#doFree()
  +     */
  +    protected void doFree() {
       }
   
       /**
        * Clear the Store of all elements
        */
  -    public void clear() 
  +    protected void doClear() 
       {
           
           if (getLogger().isDebugEnabled()) 
  @@ -258,41 +219,29 @@
               getLogger().debug("clear(): Clearing the database ");
           }
   
  -        Sync sync = this.lock.writeLock();
  -        try
  +        try 
           {
  -            sync.acquire();
  -            try 
  +            final BTreeIterator iter = new BTreeIterator(m_Index);
  +            Object tmp;
  +            do 
               {
  -                final BTreeIterator iter = new BTreeIterator(m_Index);
  -                Object tmp;
  -                do 
  +                tmp = iter.getKey();
  +                if ( tmp != null ) 
                   {
  -                    tmp = iter.getKey();
  -                    if ( tmp != null ) 
  +                    if (getLogger().isDebugEnabled()) 
                       {
  -                        if (getLogger().isDebugEnabled()) 
  -                        {
  -                            getLogger().debug("clear(): Removing key: " + 
tmp.toString());
  -                        }
  -                        iter.moveNext();
  -                        this.remove( tmp );
  +                        getLogger().debug("clear(): Removing key: " + 
tmp.toString());
                       }
  -                } 
  -                while (tmp != null);
  +                    iter.moveNext();
  +                    this.remove( tmp );
  +                }
               } 
  -            catch (Exception ignore) 
  -            {
  -                getLogger().error("store(..): Exception", ignore);
  -            }
  -            finally 
  -            {
  -                sync.release();
  -            }
  -        }
  -        catch (InterruptedException ignore)
  -        {
  +            while (tmp != null);
           } 
  +        catch (Exception ignore) 
  +        {
  +            getLogger().error("store(..): Exception", ignore);
  +        }
       }
   
       /**
  @@ -300,38 +249,26 @@
        *
        * @param key the key object
        */
  -    public void remove(Object key)
  +    protected void doRemove(Object key)
       {
           if (getLogger().isDebugEnabled()) 
           {
               getLogger().debug("remove(..) Remove item");
           }
   
  -        Sync sync = this.lock.writeLock();
  -        try
  +        try 
           {
  -            sync.acquire();
  -            try 
  -            {
  -                KeyObject[] keyArray = new KeyObject[1];
  -                keyArray[0] = this.wrapKeyObject(key);
  -                m_Database.remove(keyArray);
  -            } 
  -            catch (KeyNotFound ignore) 
  -            {
  -            } 
  -            catch (Exception e) 
  -            {
  -                getLogger().error("remove(..): Exception", e);
  -            }
  -            finally 
  -            {
  -                sync.release();
  -            }
  -        }
  -        catch (InterruptedException ignore)
  +            KeyObject[] keyArray = new KeyObject[1];
  +            keyArray[0] = this.wrapKeyObject(key);
  +            m_Database.remove(keyArray);
  +        } 
  +        catch (KeyNotFound ignore) 
           {
           } 
  +        catch (Exception e) 
  +        {
  +            getLogger().error("remove(..): Exception", e);
  +        }
       }
   
       /**
  @@ -340,37 +277,25 @@
        * @param key the key object
        * @return true if Key exists and false if not
        */
  -    public boolean containsKey(Object key) 
  +    protected boolean doContainsKey(Object key) 
       {
           long res = -1;
   
  -        Sync sync = this.lock.readLock();
  -        try
  +        try 
           {
  -            sync.acquire();
  -            try 
  +            res = m_Index.findKey(this.wrapKeyObject(key));
  +            if (getLogger().isDebugEnabled()) 
               {
  -                res = m_Index.findKey(this.wrapKeyObject(key));
  -                if (getLogger().isDebugEnabled()) 
  -                {
  -                    getLogger().debug("containsKey(..): res=" + res);
  -                }
  -            } 
  -            catch (KeyNotFound ignore) 
  -            {
  -            } 
  -            catch (Exception e)
  -            {
  -                getLogger().error("containsKey(..): Exception", e);
  -            }
  -            finally 
  -            {
  -                sync.release();
  +                getLogger().debug("containsKey(..): res=" + res);
               }
  -        }
  -        catch (InterruptedException ignore)
  +        } 
  +        catch (KeyNotFound ignore) 
           {
           } 
  +        catch (Exception e)
  +        {
  +            getLogger().error("containsKey(..): Exception", e);
  +        }
   
           if (res > 0) 
           {
  @@ -387,7 +312,7 @@
        *
        * @return  Enumeration Object with all existing keys
        */
  -    public Enumeration keys() 
  +    protected Enumeration doGetKeys() 
       {
           try 
           {
  @@ -399,7 +324,7 @@
           }
       }
   
  -    public int size() 
  +    protected int doGetSize() 
       {
           return m_Index.count();
       }
  @@ -489,4 +414,5 @@
               return ((JispKey) tmp).getKey();
           }
       }
  +
   }
  
  
  
  1.1                  
avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/AbstractReadWriteStore.java
  
  Index: AbstractReadWriteStore.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"  
      must not be used to endorse or promote products derived from this  software 
      without  prior written permission. For written permission, please contact 
      [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   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  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, 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 the Apache Software  Foundation. For more  information on the 
   Apache Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.excalibur.store.impl;
  
  import java.io.IOException;
  import java.util.Collections;
  import java.util.Enumeration;
  
  import EDU.oswego.cs.dl.util.concurrent.FIFOReadWriteLock;
  import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
  import EDU.oswego.cs.dl.util.concurrent.Sync;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.excalibur.store.Store;
  
  /**
   * This is a base implementation for stores that are synchronized by
   * using a read/write lock.
   * 
   * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
   * @version CVS $Id: AbstractReadWriteStore.java,v 1.1 2003/08/25 09:50:56 cziegeler 
Exp $
   */
  public abstract class AbstractReadWriteStore
  extends AbstractLogEnabled
  implements Store, ThreadSafe {
  
      /** The lock */
      protected ReadWriteLock lock = new FIFOReadWriteLock();
      
      /**
       * Returns a Object from the store associated with the Key Object
       *
       * @param key the Key object
       * @return the Object associated with Key Object
       */
      public Object get(Object key) 
      {
          Object value = null;
          Sync sync = this.lock.writeLock();
          try
          {
              sync.acquire();
              try 
              {
                  this.doGet(key);
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
          } 
          
          return value;
      }
  
      /**
       *  Store the given object in the indexed data file.
       *
       * @param key the key object
       * @param value the value object
       * @exception  IOException
       */
      public void store(Object key, Object value)
      throws IOException 
      {
          Sync sync = this.lock.writeLock();
          try
          {
              sync.acquire();
  
              try 
              {
                  this.doStore(key, value);
              } 
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
          } 
      }
  
      /**
       * Frees some values of the data file.<br>
       */
      public void free() 
      {
          Sync sync = this.lock.writeLock();
          try
          {
              sync.acquire();
  
              try 
              {
                  this.doFree();
              } 
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
          } 
      }
  
      /**
       * Clear the Store of all elements
       */
      public void clear() 
      {
          
          if (getLogger().isDebugEnabled()) 
          {
              getLogger().debug("clear(): Clearing the database ");
          }
  
          Sync sync = this.lock.writeLock();
          try
          {
              sync.acquire();
              try 
              {
                  this.doClear();
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
          } 
      }
  
      /**
       * Removes a value from the data file with the given key.
       *
       * @param key the key object
       */
      public void remove(Object key)
      {
          Sync sync = this.lock.writeLock();
          try
          {
              sync.acquire();
              try 
              {
                  this.doRemove(key);
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
          } 
      }
  
      /**
       *  Test if the the index file contains the given key
       *
       * @param key the key object
       * @return true if Key exists and false if not
       */
      public boolean containsKey(Object key) 
      {
          Sync sync = this.lock.readLock();
          try
          {
              sync.acquire();
              try 
              {
                  return this.doContainsKey(key);
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
              return false;
          } 
      }
  
      /**
       * Returns a Enumeration of all Keys in the indexed file.<br>
       *
       * @return  Enumeration Object with all existing keys
       */
      public Enumeration keys() 
      {
          Sync sync = this.lock.readLock();
          try
          {
              sync.acquire();
              try 
              {
                  return this.doGetKeys();
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
              return Collections.enumeration(Collections.EMPTY_LIST);
          } 
      }
  
      public int size() 
      {
          Sync sync = this.lock.readLock();
          try
          {
              sync.acquire();
              try 
              {
                  return this.doGetSize();
              }
              finally 
              {
                  sync.release();
              }
          }
          catch (InterruptedException ignore)
          {
              return 0;
          } 
      }
  
      /**
       * Get the object associated to the given unique key.
       */
      protected abstract Object doGet( Object key );
  
      /**
       * Store the given object. It is up to the
       * caller to ensure that the key has a persistent state across
       * different JVM executions.
       */
      protected abstract void doStore( Object key, Object value ) throws IOException;
  
      /**
       * Try to free some used memory. The transient store can simply remove
       * some hold data, the persistent store can free all memory by
       * writing the data to a persistent store etc.
       */
      protected abstract void doFree();
  
      /**
       * Remove the object associated to the given key.
       */
      protected abstract void doRemove( Object key );
  
      /**
       * Clear the Store of all data it holds 
       */
      protected abstract void doClear();
  
      /**
       * Indicates if the given key is associated to a contained object.
       */
      protected abstract boolean doContainsKey( Object key );
  
      /**
       * Returns the list of used keys as an Enumeration of Objects.
       */
      protected abstract Enumeration doGetKeys();
  
      /**
       * Returns count of the objects in the store, or -1 if could not be
       * obtained.
       */
      protected abstract int doGetSize();
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to