Author: byrne
Date: Wed May 17 12:16:29 2006
New Revision: 407356
URL: http://svn.apache.org/viewvc?rev=407356&view=rev
Log:
Changes to include and automatic flush collections that have had document changes. Its currently set to run every minute but can be adjusted or
later a configure parameter can be set to override the default.
Also added a shutdown hook to help catch unclean Java shutdowns. This hook just insure that open databases that haven't been closed get properly
closed.
Todd Byrne
Added:
xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java (with props)
xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java (with props)
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/Database.java
Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/Database.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/Database.java?rev=407356&r1=407355&r2=407356&view=diff
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/Database.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/Database.java Wed May 17 12:16:29 2006
@@ -60,7 +60,12 @@
public static final String DBROOT_DEFAULT = "./db/";
private static final Map databases = new HashMap(); // String to Database
-
+ private static final DatabaseShutdownHandler shutdownHandler = new DatabaseShutdownHandler();
+ static {
+ // sets up our golbal observer. will automatically flush document
+ // changes to disk.
+ DBObserver.setInstance(new DatabaseChangeObserver());
+ }
/**
* This will return an instance of a Database for the given
* name if one has already been loaded, otherwise it will
@@ -142,38 +147,59 @@
private boolean sysInit;
private SystemCollection systemCollection;
private FileOutputStream lock;
-
+ private boolean closed;
public Database() {
super();
this.docCache = new DocumentCache();
this.engine = new QueryEngine(this);
+ shutdownHandler.registerDatabase(this);
+ closed = false;
}
-
/**
- * @see org.apache.xindice.core.DBObject#close()
+ * Checks to see if it has been closed to insure that it doesn't try to do it
+ * twice.
+ *
+ * @param removeFromShutdown If true removes its self from the shutdown hook
*/
- public boolean close() throws DBException {
- if (log.isDebugEnabled()) {
- log.debug("Shutting down database: '" + getName() + "'");
- }
+ protected synchronized boolean close(boolean removeFromShutdown) throws DBException {
- flushConfig();
- super.close();
+ if(removeFromShutdown) {
+ // we have already been closed so no need to do this again.
+ shutdownHandler.removeDatabase(this);
+ }
+ // check to see if we have already been closed.
+ if(!closed)
+ {
+ if(log.isDebugEnabled()) {
+ log.debug("Shutting down database: '" + getName() + "'");
+ }
- // Release database lock
- try {
- this.lock.close();
- } catch (IOException e) {
- // Ignore IO exception
- }
- this.lock = null;
+ flushConfig();
+ super.close();
- synchronized (databases) {
- databases.remove(getName());
- }
+ // Release database lock
+ try {
+ this.lock.close();
+ }
+ catch(IOException e) {
+ // Ignore IO exception
+ }
+ this.lock=null;
+ synchronized(databases) {
+ databases.remove(getName());
+ }
+ closed = true;
+ }
return true;
+ }
+ /**
+ * @see org.apache.xindice.core.DBObject#close()
+ * @see org.apache.xindice.core.Database#close(boolean removeFromShutdown)
+ */
+ public boolean close() throws DBException {
+ return close(true);
}
/**
Added: xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java?rev=407356&view=auto
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java Wed May 17 12:16:29 2006
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.xindice.core;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.xindice.core.data.Key;
+import org.apache.xindice.core.data.Record;
+import org.apache.xindice.util.Configuration;
+import org.w3c.dom.Document;
+
+/**
+ * DatabaseChangeObserver is going to handle changes to collections by
+ * flushing the apporate collection Filer.
+ *
+ * This current version we are only going to worry about document changes and
+ * their Filer storage are kept updated.
+ *
+ * <a href="mailto:[email protected]">Todd Byrne</a>
+ */
+public class DatabaseChangeObserver extends DBObserver {
+ private static final Log log = LogFactory.getLog(DatabaseChangeObserver.class);
+ // by using a hashtable instead of a queue collections only get added once.
+ private Hashtable collectionDirtyFlags;
+ private Timer flushTimer;
+ /** One minute flush period **/
+ private long FLUSH_PERIOD = 1000 * 60;
+ public DatabaseChangeObserver() {
+ collectionDirtyFlags = new Hashtable();
+ flushTimer = new Timer(true);
+ flushTimer.schedule(new FlushTask(),FLUSH_PERIOD,FLUSH_PERIOD);
+ }
+ /**
+ * Queues the collection to be flushed by the FlushTask synchronized
+ * by the hashtable
+ * @param col Collection
+ * @param key Key
+ * @throws DBException
+ */
+ public void dropDocument(Collection col, Key key) throws DBException {
+ collectionDirtyFlags.put(col,Boolean.TRUE);
+ }
+ /**
+ *
+ * @param col Collection
+ * @param key Key
+ * @param document Document
+ * @param create boolean
+ * @throws DBException
+ */
+ public void putDocument(Collection col, Key key, Document document, boolean create) throws DBException {
+ collectionDirtyFlags.put(col,Boolean.TRUE);
+ }
+
+ /**
+ *
+ * @param col Collection
+ * @throws DBException
+ */
+ public void createCollection(Collection col) throws DBException {
+ }
+
+ /**
+ *
+ * @param col Collection
+ * @param record Record
+ * @param document Document
+ * @throws DBException
+ */
+ public void loadDocument(Collection col, Record record, Document document) throws DBException {
+ }
+ /**
+ *
+ * @param col Collection
+ * @throws DBException
+ */
+ public void dropCollection(Collection col) throws DBException {
+ }
+
+ /**
+ *
+ * @param db Database
+ * @param cfg Configuration
+ */
+ public void flushDatabaseConfig(Database db, Configuration cfg) {
+ }
+
+ /**
+ *
+ * @param col Collection
+ * @param cfg Configuration
+ */
+ public void setCollectionConfig(Collection col, Configuration cfg) {
+ }
+
+ /**
+ *
+ * @param db Database
+ * @param collections Map
+ * @param cfg Configuration
+ */
+ public void setDatabaseConfig(Database db, Map collections, Configuration cfg) {
+ }
+ /**
+ * FlushTask handles the work of
+ */
+ private class FlushTask extends TimerTask{
+ public FlushTask(){
+ }
+ public void run(){
+
+ synchronized(collectionDirtyFlags) {
+
+ Iterator collections = collectionDirtyFlags.entrySet().iterator();
+ int flushCount = 0;
+ while(collections.hasNext())
+ {
+ Map.Entry e = (Map.Entry)collections.next();
+ Collection c = (Collection)e.getKey();
+ try
+ {
+ // don't need to flush indexes because everytime a document
+ // gets added the indexes get flushed.
+ c.getFiler().flush();
+ flushCount ++;
+ }
+ catch(DBException ex) {
+ log.error("Couldn't flush collection: " + c.getName() , ex);
+ }
+ }
+ log.info("Successfully flushed " + flushCount + " collections out of " +
+ collectionDirtyFlags.size());
+ collectionDirtyFlags.clear();
+ }
+ }
+ }
+
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseChangeObserver.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java?rev=407356&view=auto
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java Wed May 17 12:16:29 2006
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.xindice.core;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Going to handle the JVM Shutdown hook and insuring clean shutdown
+ * of all registered Database Intances.
+ *
+ * <a href="mailto:[email protected]">Todd Byrne</a>
+ */
+public class DatabaseShutdownHandler implements Runnable{
+
+ private Hashtable databases;
+
+ public DatabaseShutdownHandler() {
+ databases = new Hashtable();
+ Runtime.getRuntime().addShutdownHook(new Thread(this));
+ }
+ /**
+ * @param db database to register
+ */
+ public void registerDatabase(Database db) {
+ databases.put(db, Boolean.TRUE);
+ }
+ /**
+ * @param db removed the database from the hashtable
+ */
+ public void removeDatabase(Database db) {
+ databases.remove(db);
+ }
+ /**
+ * Cleans up any unclosed databases before the JVM exits.
+ */
+ public void run() {
+ synchronized(databases) {
+ Iterator dbs = databases.entrySet().iterator();
+ while(dbs.hasNext())
+ {
+ Database db = (Database)((Map.Entry)dbs.next()).getKey();
+
+ // synch again on the db object just incase a close operation
+ // is happening on a different thread
+ synchronized(db) {
+ // call close but don't bother removing the db from the database
+ // table
+ try {
+ db.close(false);
+ System.out.println("Dirty close on: " + db.getName());
+ }
+ catch(DBException ex) {
+ }
+ }
+ }
+ databases.clear();
+ }
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/core/DatabaseShutdownHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.