[Mulgara-svn] r1156 - trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa
pag at mulgara.org
pag at mulgara.org
Sat Aug 23 01:46:10 UTC 2008
Author: pag
Date: 2008-08-22 18:46:09 -0700 (Fri, 22 Aug 2008)
New Revision: 1156
Modified:
trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java
Log:
Updated the put()/find() interface, added the setNodePool() method (to support the new put/find interface), and cleaned up formatting. Also the reduced the scope of synchronization around transaction operations to allow the node pool to synchronize in its own way.
Modified: trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java
===================================================================
--- trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java 2008-08-23 01:42:11 UTC (rev 1155)
+++ trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java 2008-08-23 01:46:09 UTC (rev 1156)
@@ -191,6 +191,9 @@
/** Maps gNodes to SPObjects. */
private GN2SPOCache gn2spoCache = new GN2SPOCache();
+ /** The node pool to use with this string pool. */
+ private XANodePool xaNodePool;
+
/** Indicates that the current phase has been written to. */
private boolean dirty = true;
@@ -275,6 +278,14 @@
/**
+ * @see org.mulgara.store.xa.XAStringPool#setNodePool(org.mulgara.store.xa.XANodePool)
+ */
+ public void setNodePool(XANodePool xaNodePool) {
+ this.xaNodePool = xaNodePool;
+ }
+
+
+ /**
* Gets the PhaseNumber attribute of the XAStringPoolImpl object
*
* @return The PhaseNumber value
@@ -298,16 +309,44 @@
}
/**
+ * Adds a new SObject into the string pool, returning the new gNode that is associated
+ * with this object.
+ * @param spObject The object to store.
+ * @return The new gNode for the object.
+ * @throws StringPoolException If the string pool could not store the object.
+ * @throws NodePoolException If the node pool could not allocate a gNode.
+ */
+ public long put(SPObject spObject) throws StringPoolException, NodePoolException {
+ long gNode = xaNodePool.newNode();
+ putInternal(gNode, spObject);
+ return gNode;
+ }
+
+ /**
* Adds a new graph node / SPObject pair into the string pool. An error will
* result if the graph node or the SPObject (or both) already exists in the
* pool.
- *
* @param gNode The graph node to add.
* @param spObject The SPObject to add.
* @throws StringPoolException if the graph node or the SPObject already
* exists in the pool.
*/
- public synchronized void put(
+ @Deprecated
+ public synchronized void put(long gNode, SPObject spObject) throws StringPoolException {
+ putInternal(gNode, spObject);
+ }
+
+
+ /**
+ * Adds a new graph node / SPObject pair into the string pool. An error will
+ * result if the graph node or the SPObject (or both) already exists in the
+ * pool.
+ * @param gNode The graph node to add.
+ * @param spObject The SPObject to add.
+ * @throws StringPoolException if the graph node or the SPObject already
+ * exists in the pool.
+ */
+ private synchronized void putInternal(
long gNode, SPObject spObject
) throws StringPoolException {
checkInitialized();
@@ -377,6 +416,20 @@
}
+ /**
+ * @see org.mulgara.store.xa.XAStringPool#findGNode(org.mulgara.store.stringpool.SPObject, boolean)
+ */
+ public synchronized long findGNode(SPObject spObject, boolean create) throws StringPoolException {
+ checkInitialized();
+ if (xaNodePool == null) throw new IllegalArgumentException("nodePool is null");
+ return currentPhase.findGNode(spObject, xaNodePool);
+ }
+
+
+ /**
+ * @see org.mulgara.store.stringpool.StringPool#findGNode(org.mulgara.store.stringpool.SPObject, org.mulgara.store.nodepool.NodePool)
+ */
+ @Deprecated
public synchronized long findGNode(SPObject spObject, NodePool nodePool) throws StringPoolException {
checkInitialized();
if (nodePool == null) throw new IllegalArgumentException("nodePool parameter is null");
@@ -473,18 +526,18 @@
/**
- * METHOD TO DO
+ * @see org.mulgara.store.xa.SimpleXAResource#release()
*/
- public void release() {
- // NO-OP
+ public void release() throws SimpleXAResourceException {
+ if (xaNodePool != null) xaNodePool.release();
}
/**
- * METHOD TO DO
+ * @see org.mulgara.store.xa.SimpleXAResource#refresh()
*/
- public void refresh() {
- // NO-OP
+ public void refresh() throws SimpleXAResourceException {
+ if (xaNodePool != null) xaNodePool.refresh();
}
@@ -562,124 +615,127 @@
/**
- * METHOD TO DO
- *
- * @throws SimpleXAResourceException EXCEPTION TO DO
+ * Writes all transactional data to disk, in preparation for a full commit.
+ * @throws SimpleXAResourceException Occurs due to an IO error when writing data to disk.
*/
- public synchronized void prepare() throws SimpleXAResourceException {
- checkInitialized();
-
- if (prepared) {
- // prepare already performed.
- throw new SimpleXAResourceException("prepare() called twice.");
- }
-
- try {
- // Perform a prepare.
- recordingPhaseToken = currentPhase.use();
- Phase recordingPhase = currentPhase;
- new Phase();
-
- // Ensure that all data associated with the phase is on disk.
- avlFile.force();
- for (int i = 0; i < NR_BLOCK_FILES; ++i) {
- blockFiles[i].force();
+ public void prepare() throws SimpleXAResourceException {
+ // TODO: This synchronization is probably redundant due to the global lock in StringPoolSession
+ synchronized(this) {
+ checkInitialized();
+
+ if (prepared) {
+ // prepare already performed.
+ throw new SimpleXAResourceException("prepare() called twice.");
}
- gNodeToDataFile.force();
-
- // Write the metaroot.
- int newPhaseIndex = 1 - phaseIndex;
- int newPhaseNumber = phaseNumber + 1;
-
- Block block = metarootBlocks[newPhaseIndex];
- block.putInt(IDX_VALID, 0); // should already be invalid.
- block.putInt(IDX_PHASE_NUMBER, newPhaseNumber);
- logger.debug("Writing string pool metaroot for phase: " + newPhaseNumber);
- recordingPhase.writeToBlock(block, HEADER_SIZE_LONGS);
- block.write();
- metarootFile.force();
- block.putInt(IDX_VALID, 1);
- block.write();
- metarootFile.force();
-
- phaseIndex = newPhaseIndex;
- phaseNumber = newPhaseNumber;
- prepared = true;
- } catch (IOException ex) {
- logger.error("I/O error while performing prepare.", ex);
- throw new SimpleXAResourceException(
- "I/O error while performing prepare.", ex
- );
- } finally {
- if (!prepared) {
- // Something went wrong!
- logger.error("Prepare failed.");
- if (recordingPhaseToken != null) {
- recordingPhaseToken.release();
- recordingPhaseToken = null;
+
+ try {
+ // Perform a prepare.
+ recordingPhaseToken = currentPhase.use();
+ Phase recordingPhase = currentPhase;
+ new Phase();
+
+ // Ensure that all data associated with the phase is on disk.
+ avlFile.force();
+ for (int i = 0; i < NR_BLOCK_FILES; ++i) {
+ blockFiles[i].force();
}
+ gNodeToDataFile.force();
+
+ // Write the metaroot.
+ int newPhaseIndex = 1 - phaseIndex;
+ int newPhaseNumber = phaseNumber + 1;
+
+ Block block = metarootBlocks[newPhaseIndex];
+ block.putInt(IDX_VALID, 0); // should already be invalid.
+ block.putInt(IDX_PHASE_NUMBER, newPhaseNumber);
+ logger.debug("Writing string pool metaroot for phase: " + newPhaseNumber);
+ recordingPhase.writeToBlock(block, HEADER_SIZE_LONGS);
+ block.write();
+ metarootFile.force();
+ block.putInt(IDX_VALID, 1);
+ block.write();
+ metarootFile.force();
+
+ phaseIndex = newPhaseIndex;
+ phaseNumber = newPhaseNumber;
+ prepared = true;
+ } catch (IOException ex) {
+ logger.error("I/O error while performing prepare.", ex);
+ throw new SimpleXAResourceException("I/O error while performing prepare.", ex);
+ } finally {
+ if (!prepared) {
+ // Something went wrong!
+ logger.error("Prepare failed.");
+ if (recordingPhaseToken != null) {
+ recordingPhaseToken.release();
+ recordingPhaseToken = null;
+ }
+ }
}
}
+ if (xaNodePool != null) xaNodePool.prepare();
}
/**
- * METHOD TO DO
- *
- * @throws SimpleXAResourceException EXCEPTION TO DO
+ * Writes to the meta-root file to make all the transaction data written in {@link #prepare()}
+ * suddenly valid.
+ * @throws SimpleXAResourceException Error due to IO problems.
*/
- public synchronized void commit() throws SimpleXAResourceException {
- if (!prepared) {
- // commit without prepare.
- throw new SimpleXAResourceException(
- "commit() called without previous prepare()."
- );
- }
-
- // Perform a commit.
- try {
- // Invalidate the metaroot of the old phase.
- Block block = metarootBlocks[1 - phaseIndex];
- block.putInt(IDX_VALID, 0);
- block.write();
- metarootFile.force();
-
- // Release the token for the previously committed phase.
- synchronized (committedPhaseLock) {
- if (committedPhaseToken != null) {
- committedPhaseToken.release();
+ public void commit() throws SimpleXAResourceException {
+ // TODO: This synchronization is probably redundant due to the global lock in StrinPoolSession
+ synchronized (this) {
+ if (!prepared) {
+ // commit without prepare.
+ throw new SimpleXAResourceException("commit() called without previous prepare().");
+ }
+
+ // Perform a commit.
+ try {
+ // Invalidate the metaroot of the old phase.
+ Block block = metarootBlocks[1 - phaseIndex];
+ block.putInt(IDX_VALID, 0);
+ block.write();
+ metarootFile.force();
+
+ // Release the token for the previously committed phase.
+ synchronized (committedPhaseLock) {
+ if (committedPhaseToken != null) committedPhaseToken.release();
+ committedPhaseToken = recordingPhaseToken;
}
- committedPhaseToken = recordingPhaseToken;
- }
- recordingPhaseToken = null;
- } catch (IOException ex) {
- logger.fatal("I/O error while performing commit.", ex);
- throw new SimpleXAResourceException(
- "I/O error while performing commit.", ex
- );
- } finally {
- prepared = false;
- if (recordingPhaseToken != null) {
- // Something went wrong!
- recordingPhaseToken.release();
recordingPhaseToken = null;
-
- logger.error("Commit failed. Calling close().");
- try {
- close();
- } catch (Throwable t) {
- logger.error("Exception on forced close()", t);
+ } catch (IOException ex) {
+ logger.fatal("I/O error while performing commit.", ex);
+ throw new SimpleXAResourceException("I/O error while performing commit.", ex);
+ } finally {
+ prepared = false;
+ if (recordingPhaseToken != null) {
+ // Something went wrong!
+ recordingPhaseToken.release();
+ recordingPhaseToken = null;
+
+ logger.error("Commit failed. Calling close().");
+ try {
+ close();
+ } catch (Throwable t) {
+ logger.error("Exception on forced close()", t);
+ }
}
}
}
+ if (xaNodePool != null) xaNodePool.commit();
}
/**
- * METHOD TO DO
+ * Returns an array which contains a list of the phase numbers for all valid
+ * phases in the metaroot file. The array will contain zero, one or two
+ * elements. There will be no valid phases if no prepares have been
+ * successfully performed since the SimpleXAResource was initially created.
*
- * @return RETURNED VALUE TO DO
- * @throws SimpleXAResourceException EXCEPTION TO DO
+ * @return the array of valid phase numbers.
+ * @throws SimpleXAResourceException if {@link #selectPhase} or {@link #clear}
+ * has already been called.
*/
public synchronized int[] recover() throws SimpleXAResourceException {
if (currentPhase != null) {
@@ -780,39 +836,42 @@
/**
- * METHOD TO DO
- *
- * @throws SimpleXAResourceException EXCEPTION TO DO
+ * Drops all data in the current transaction, recovering any used resources.
+ * @throws SimpleXAResourceException Caused by any IO errors.
*/
- public synchronized void rollback() throws SimpleXAResourceException {
- checkInitialized();
- try {
- if (prepared) {
- // Restore phaseIndex and phaseNumber to their previous values.
- phaseIndex = 1 - phaseIndex;
- --phaseNumber;
- recordingPhaseToken = null;
- prepared = false;
-
- // Invalidate the metaroot of the other phase.
- Block block = metarootBlocks[1 - phaseIndex];
- block.putInt(IDX_VALID, 0);
- block.write();
- metarootFile.force();
- }
- } catch (IOException ex) {
- throw new SimpleXAResourceException(
- "I/O error while performing rollback (invalidating metaroot)", ex
- );
- } finally {
+ public void rollback() throws SimpleXAResourceException {
+ // TODO: This synchronization is probably redundant due to the global lock in StringPoolSession
+ synchronized (this) {
+ checkInitialized();
try {
- new Phase(committedPhaseToken.getPhase());
+ if (prepared) {
+ // Restore phaseIndex and phaseNumber to their previous values.
+ phaseIndex = 1 - phaseIndex;
+ --phaseNumber;
+ recordingPhaseToken = null;
+ prepared = false;
+
+ // Invalidate the metaroot of the other phase.
+ Block block = metarootBlocks[1 - phaseIndex];
+ block.putInt(IDX_VALID, 0);
+ block.write();
+ metarootFile.force();
+ }
} catch (IOException ex) {
throw new SimpleXAResourceException(
- "I/O error while performing rollback (new committed phase)", ex
+ "I/O error while performing rollback (invalidating metaroot)", ex
);
+ } finally {
+ try {
+ new Phase(committedPhaseToken.getPhase());
+ } catch (IOException ex) {
+ throw new SimpleXAResourceException(
+ "I/O error while performing rollback (new committed phase)", ex
+ );
+ }
}
}
+ if (xaNodePool != null) xaNodePool.rollback();
}
@@ -1041,6 +1100,12 @@
}
+ /** Sets the node pool for this string pool. */
+ public void setNodePool(XANodePool xaNodePool) {
+ /* no-op */
+ }
+
+
/**
* Gets the SPObjectFactory associated with this StringPool implementation.
*/
@@ -1050,19 +1115,18 @@
/**
- * Adds a new graph node / SPString pair into the string pool. An existing
- * graph node and SPString may only be added if that exact pair already
- * exists, otherwise an error will result.
- *
- * @param gNode The graph node to add.
- * @param spObject PARAMETER TO DO
- * @throws UnsupportedOperationException since this string pool is read
- * only.
+ * @see org.mulgara.store.stringpool.StringPool#put(org.mulgara.store.stringpool.SPObject)
*/
+ public long put(SPObject spObject) {
+ throw new UnsupportedOperationException("Trying to modify a read-only string pool.");
+ }
+
+
+ /**
+ * @see org.mulgara.store.stringpool.StringPool#put(long, org.mulgara.store.stringpool.SPObject)
+ */
public void put(long gNode, SPObject spObject) {
- throw new UnsupportedOperationException(
- "Trying to modify a read-only string pool."
- );
+ throw new UnsupportedOperationException("Trying to modify a read-only string pool.");
}
@@ -1084,7 +1148,7 @@
/**
* Finds the graph node matching a given SPObject.
*
- * @param spObject PARAMETER TO DO
+ * @param spObject The object being searched for.
* @return The graph node. <code>Graph.NONE</code> if not found.
* @throws StringPoolException EXCEPTION TO DO
*/
@@ -1093,11 +1157,17 @@
}
+ @Deprecated
public synchronized long findGNode(SPObject spObject, NodePool nodePool) throws StringPoolException {
throw new UnsupportedOperationException("Trying to modify a read-only string pool.");
}
+ public synchronized long findGNode(SPObject spObject, boolean create) throws StringPoolException {
+ if (create) throw new UnsupportedOperationException("Trying to modify a read-only string pool.");
+ return phase.findGNode(spObject, null);
+ }
+
/**
* Finds and returns the SPObject corresponding to <var>gNode</var>, or
* <code>null</code> if no such graph node is in the pool.
More information about the Mulgara-svn
mailing list