Changeset 30270 for gs2-extensions

Show
Ignore:
Timestamp:
28.09.2015 11:02:08 (4 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

Files:
1 modified

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    }