Ignore:
Timestamp:
2015-09-28T11:02:08+13:00 (9 years ago)
Author:
jmt12
Message:

Changes to support a static cache of connections, factory methods to access them, and a simplified open allowing only for the clear_if_first flag

File:
1 edited

Legend:

Unmodified
Added
Removed
  • gs2-extensions/tdb/trunk/src/java/org/greenstone/tdbjava/TDBJava.java

    r30193 r30270  
    2323import java.lang.System;
    2424import java.util.Enumeration;
     25import java.util.HashMap;
    2526
    2627import org.greenstone.tdbjava.TDBJavaException;
     
    5253    implements Closeable
    5354{
     55
     56    /** A cache of TDBJava objects that have been created keyed by filepath */
     57    private static HashMap<String, TDBJava> connection_cache;
     58
    5459    static
    5560    {
    5661    // Load native library mapping at runtime (libTDBJava.so)
    5762    System.loadLibrary("TDBJava");
    58     }
     63    connection_cache = new HashMap<String, TDBJava>();
     64    }
     65
     66    /** @function getConnection(String)
     67     * Factory method - uses an existing cached TDBJava otherwise creates
     68     * a new one.  This should get around the issue with a single process of
     69     * the libTDBJava.so above throwing EBUSY errors when trying to open
     70     * multiple copies of the same database.
     71     */
     72    public static TDBJava getConnection(String filename)
     73    throws TDBJavaException
     74    {
     75    TDBJava the_connection = connection_cache.get(filename);
     76    if (null == the_connection) {
     77        the_connection = new TDBJava(filename);
     78        connection_cache.put(filename, the_connection);
     79    }
     80    // Keep track of the number of times this connection has been
     81    // handed out
     82    the_connection.registerCaller();
     83    return the_connection;
     84    }
     85    /** getConnection(String) **/
     86
     87    public static TDBJava newConnection(String filename)
     88    throws TDBJavaException
     89    {
     90    TDBJava the_connection = connection_cache.get(filename);
     91    if (null == the_connection) {
     92        the_connection = new TDBJava(filename);
     93        connection_cache.put(filename, the_connection);
     94    }
     95    // delete all the records in an open connection
     96    Enumeration keys = the_connection.keys();
     97    while (keys.hasMoreElements()) {
     98        the_connection.delete((String) keys.nextElement());
     99    }
     100    // Keep track of the number of times this connection has been
     101    // handed out
     102    the_connection.registerCaller();
     103    return the_connection;
     104    }
     105    /** newConnection(String) **/
    59106
    60107    /* ===== Declare mappings to native methods ===== */
     
    144191    private int    open_flags;
    145192
     193    /** We need to keep a reference of the number of times this connection
     194     * has been opened, and not process a close until they have *all* asked
     195     * to close. */
     196    private int caller_count;
     197
    146198    /** The TDB handle for the database file, or 0 if the database has
    147199     * been closed.  Java doesn't understand it, but it stores it and
     
    153205     *
    154206     * @param filename the disk filename in which the data will be stored
    155      * @param flags any of TDB_DEFAULT, TDB_CLEAR_IF_FIRST, TDB_INTERNAL, and
    156      * TDB_NOLOCK
    157      *
    158207     */
    159208    public TDBJava(String filename)
    160209    throws TDBJavaException
    161210    {
    162     this(filename, TDBJava.TDB_DEFAULT, TDBJava.O_DEFAULT);
    163     }
    164 
     211    this.filename = filename;
     212    this.tdb_flags = TDBJava.TDB_DEFAULT;
     213    this.open_flags = TDBJava.O_DEFAULT;
     214    this.dbf = this.tdbOpen(this.filename, this.tdb_flags, this.open_flags);
     215    this.caller_count = 0;
     216    // Replacement for System.runFinalizersOnExit(true);
     217    Thread shutdown_thread = new TDBJavaShutdownThread(this);
     218    Runtime.getRuntime().addShutdownHook(shutdown_thread);
     219    }
     220    /** TDBJava(String) **/
     221
     222    /** @function TDBJava(String, int)
     223     * @param filename the disk filename in which the data will be stored
     224     * @param tdb_flags any of TDB_DEFAULT, TDB_CLEAR_IF_FIRST, TDB_INTERNAL,
     225     *                  and TDB_NOLOCK
     226     */
     227    /*
    165228    public TDBJava(String filename, int tdb_flags)
    166229    throws TDBJavaException
    167230    {
    168     this(filename, tdb_flags, TDBJava.O_DEFAULT);
    169     }
    170 
     231    }
     232    */
     233    /** **/
     234
     235    /* disabled for now to simplify caching
     236     *
    171237    public TDBJava(String filename, int tdb_flags, int open_flags)
    172238    throws TDBJavaException
     
    180246    Runtime.getRuntime().addShutdownHook(shutdown_thread);
    181247    }
     248    */
     249
     250    /** @function registerCaller()
     251     */
     252    public synchronized void registerCaller()
     253    {
     254    this.caller_count++;
     255    }
     256    /** registerCaller() **/
    182257
    183258    /** Close the database file if it is still open.
     
    187262    {
    188263    if (this.dbf != 0) {
    189         this.tdbClose(this.dbf);
    190     }
    191     // opened or created
    192     this.dbf = 0;
    193     }
     264        if (this.caller_count == 1) {
     265        this.tdbClose(this.dbf);
     266        this.dbf = 0;
     267        // And remove from the cache
     268        connection_cache.remove(this.filename);
     269        }
     270        else {
     271        this.caller_count--;
     272        }
     273    }
     274    }
     275    /** close() **/
    194276
    195277    /** Close the database when the TDBJava is garbage-collected.
     
    198280    throws TDBJavaException
    199281    {
     282    // If we've got here, then we can't have any callers left
     283    this.caller_count = 0;
    200284    this.close();
    201285    }
Note: See TracChangeset for help on using the changeset viewer.