summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2008-03-21 04:04:09 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2008-03-21 04:04:09 +0000
commitca15878cc1c40b87d38acd3e735da1f80c25c01d (patch)
tree6745b3b98b470446c8984df5d0d914abd62e67fe
parentd7da2f605b2acd08a8ba3a49c00c343b292979fb (diff)
downloadjackcess-ca15878cc1c40b87d38acd3e735da1f80c25c01d.tar.gz
jackcess-ca15878cc1c40b87d38acd3e735da1f80c25c01d.zip
allow for TempBufferHolder which does not maintain reference (cleans up addRows)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@289 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r--src/java/com/healthmarketscience/jackcess/Index.java5
-rw-r--r--src/java/com/healthmarketscience/jackcess/Table.java43
-rw-r--r--src/java/com/healthmarketscience/jackcess/TempBufferHolder.java68
-rw-r--r--src/java/com/healthmarketscience/jackcess/TempPageHolder.java12
-rw-r--r--src/java/com/healthmarketscience/jackcess/UsageMap.java2
5 files changed, 91 insertions, 39 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/Index.java b/src/java/com/healthmarketscience/jackcess/Index.java
index 4307279..fe8fa23 100644
--- a/src/java/com/healthmarketscience/jackcess/Index.java
+++ b/src/java/com/healthmarketscience/jackcess/Index.java
@@ -177,7 +177,7 @@ public class Index implements Comparable<Index> {
private int _modCount;
/** temp buffer used to writing the index */
private final TempBufferHolder _indexBufferH =
- TempBufferHolder.newHolder(false, true);
+ TempBufferHolder.newHolder(TempBufferHolder.Type.SOFT, true);
/** FIXME, for now, we can't write multi-page indexes or indexes using the funky primary key compression scheme */
boolean _readOnly;
@@ -504,7 +504,8 @@ public class Index implements Comparable<Index> {
byte[] valuePrefix = null;
boolean firstEntry = true;
TempBufferHolder tmpEntryBufferH =
- TempBufferHolder.newHolder(true, true, ByteOrder.BIG_ENDIAN);
+ TempBufferHolder.newHolder(TempBufferHolder.Type.HARD, true,
+ ByteOrder.BIG_ENDIAN);
for (int i = 0; i < entryMaskLength; i++) {
byte entryMask = indexPage.get(entryMaskPos + i);
diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java
index 6523bc1..c69fc89 100644
--- a/src/java/com/healthmarketscience/jackcess/Table.java
+++ b/src/java/com/healthmarketscience/jackcess/Table.java
@@ -111,13 +111,17 @@ public class Table
private int _modCount;
/** page buffer used to update data pages when adding rows */
private final TempPageHolder _addRowBufferH =
- TempPageHolder.newHolder(false);
+ TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
/** page buffer used to update the table def page */
private final TempPageHolder _tableDefBufferH =
- TempPageHolder.newHolder(false);
+ TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
/** buffer used to writing single rows of data */
private final TempBufferHolder _singleRowBufferH =
- TempBufferHolder.newHolder(false, true);
+ TempBufferHolder.newHolder(TempBufferHolder.Type.SOFT, true);
+ /** "buffer" used to writing multi rows of data (will create new buffer on
+ every call) */
+ private final TempBufferHolder _multiRowBufferH =
+ TempBufferHolder.newHolder(TempBufferHolder.Type.NONE, true);
/** common cursor for iterating through the table, kept here for historic
reasons */
@@ -203,7 +207,7 @@ public class Table
}
public RowState createRowState() {
- return new RowState(true);
+ return new RowState(TempBufferHolder.Type.HARD);
}
protected UsageMap.PageCursor getOwnedPagesCursor() {
@@ -1100,7 +1104,7 @@ public class Table
* Add a single row to this table and write it to disk
*/
public void addRow(Object... row) throws IOException {
- addRows(Collections.singletonList(row));
+ addRows(Collections.singletonList(row), _singleRowBufferH);
}
/**
@@ -1110,15 +1114,26 @@ public class Table
* @param rows List of Object[] row values
*/
public void addRows(List<? extends Object[]> rows) throws IOException {
+ addRows(rows, _multiRowBufferH);
+ }
+
+ /**
+ * Add multiple rows to this table, only writing to disk after all
+ * rows have been written, and every time a data page is filled. This
+ * is much more efficient than calling <code>addRow</code> multiple times.
+ * @param rows List of Object[] row values
+ * @param writeRowBufferH TempBufferHolder used to generate buffers for
+ * writing the row data
+ */
+ private void addRows(List<? extends Object[]> rows,
+ TempBufferHolder writeRowBufferH)
+ throws IOException
+ {
ByteBuffer[] rowData = new ByteBuffer[rows.size()];
Iterator<? extends Object[]> iter = rows.iterator();
for (int i = 0; iter.hasNext(); i++) {
- // note, use the cached _singleRowBufferH for the first row. this will
- // speed up single row writes
- rowData[i] = createRow(
- iter.next(), getFormat().MAX_ROW_SIZE,
- ((i == 0) ? _singleRowBufferH.getPageBuffer(getPageChannel()) :
- getPageChannel().createPageBuffer()));
+ rowData[i] = createRow(iter.next(), getFormat().MAX_ROW_SIZE,
+ writeRowBufferH.getPageBuffer(getPageChannel()));
if (rowData[i].limit() > getFormat().MAX_ROW_SIZE) {
throw new IOException("Row size " + rowData[i].limit() +
" is too large");
@@ -1589,7 +1604,7 @@ public class Table
private RowStatus _rowStatus = RowStatus.INIT;
/** buffer used for reading overflow pages */
private final TempPageHolder _overflowRowBufferH =
- TempPageHolder.newHolder(false);
+ TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
/** the row buffer which contains the final data (after following any
overflow pointers) */
private ByteBuffer _finalRowBuffer;
@@ -1605,8 +1620,8 @@ public class Table
data */
private int _lastModCount;
- private RowState(boolean hardRowBuffer) {
- _headerRowBufferH = TempPageHolder.newHolder(hardRowBuffer);
+ private RowState(TempBufferHolder.Type headerType) {
+ _headerRowBufferH = TempPageHolder.newHolder(headerType);
_rowValues = new Object[Table.this.getColumnCount()];
_lastModCount = Table.this._modCount;
}
diff --git a/src/java/com/healthmarketscience/jackcess/TempBufferHolder.java b/src/java/com/healthmarketscience/jackcess/TempBufferHolder.java
index d94c9ee..9afae0b 100644
--- a/src/java/com/healthmarketscience/jackcess/TempBufferHolder.java
+++ b/src/java/com/healthmarketscience/jackcess/TempBufferHolder.java
@@ -17,6 +17,20 @@ public abstract class TempBufferHolder {
private static final Reference<ByteBuffer> EMPTY_BUFFER_REF =
new SoftReference<ByteBuffer>(null);
+ /**
+ * The caching type for the buffer holder.
+ */
+ public enum Type {
+ /** a hard reference is maintained to the created buffer */
+ HARD,
+ /** a soft reference is maintained to the created buffer (may be garbage
+ collected if memory gets tight) */
+ SOFT,
+ /** no reference is maintained to a created buffer (new buffer every
+ time) */
+ NONE;
+ }
+
/** whether or not every get automatically rewinds the buffer */
private final boolean _autoRewind;
/** ByteOrder for all allocated buffers */
@@ -39,32 +53,34 @@ public abstract class TempBufferHolder {
/**
* Creates a new TempBufferHolder.
- * @param hard iff true, the TempBufferHolder will maintain a hard reference
- * to the current buffer, otherwise will maintain a
- * SoftReference.
+ * @param type the type of reference desired for any created buffer
* @param autoRewind whether or not every get automatically rewinds the
* buffer
*/
- public static TempBufferHolder newHolder(boolean hard, boolean autoRewind) {
- return newHolder(hard, autoRewind, PageChannel.DEFAULT_BYTE_ORDER);
+ public static TempBufferHolder newHolder(Type type, boolean autoRewind) {
+ return newHolder(type, autoRewind, PageChannel.DEFAULT_BYTE_ORDER);
}
/**
* Creates a new TempBufferHolder.
- * @param hard iff true, the TempBufferHolder will maintain a hard reference
- * to the current buffer, otherwise will maintain a
- * SoftReference.
+ * @param type the type of reference desired for any created buffer
* @param autoRewind whether or not every get automatically rewinds the
* buffer
* @param order byte order for all allocated buffers
*/
- public static TempBufferHolder newHolder(boolean hard, boolean autoRewind,
+ public static TempBufferHolder newHolder(Type type, boolean autoRewind,
ByteOrder order)
{
- if(hard) {
+ switch(type) {
+ case HARD:
return new HardTempBufferHolder(autoRewind, order);
+ case SOFT:
+ return new SoftTempBufferHolder(autoRewind, order);
+ case NONE:
+ return new NoneTempBufferHolder(autoRewind, order);
+ default:
+ throw new IllegalStateException("Unknown type " + type);
}
- return new SoftTempBufferHolder(autoRewind, order);
}
/**
@@ -112,7 +128,7 @@ public abstract class TempBufferHolder {
protected abstract void setNewBuffer(ByteBuffer newBuffer);
/**
- * TempBufferHolder which has a hard reference to the buffer buffer.
+ * TempBufferHolder which has a hard reference to the buffer.
*/
private static final class HardTempBufferHolder extends TempBufferHolder
{
@@ -139,7 +155,7 @@ public abstract class TempBufferHolder {
}
/**
- * TempBufferHolder which has a soft reference to the buffer buffer.
+ * TempBufferHolder which has a soft reference to the buffer.
*/
private static final class SoftTempBufferHolder extends TempBufferHolder
{
@@ -158,8 +174,6 @@ public abstract class TempBufferHolder {
protected void setNewBuffer(ByteBuffer newBuffer) {
_buffer.clear();
_buffer = new SoftReference<ByteBuffer>(newBuffer);
-// // FIXME, enable for testing (make this automatic)
-// _buffer = new PhantomReference<ByteBuffer>(newBuffer, null);
}
@Override
@@ -168,5 +182,29 @@ public abstract class TempBufferHolder {
}
}
+ /**
+ * TempBufferHolder which has a no reference to the buffer.
+ */
+ private static final class NoneTempBufferHolder extends TempBufferHolder
+ {
+ private NoneTempBufferHolder(boolean autoRewind, ByteOrder order) {
+ super(autoRewind, order);
+ }
+
+ @Override
+ public ByteBuffer getExistingBuffer() {
+ return null;
+ }
+
+ @Override
+ protected void setNewBuffer(ByteBuffer newBuffer) {
+ // nothing to do
+ }
+
+ @Override
+ public void clear() {
+ // nothing to do
+ }
+ }
}
diff --git a/src/java/com/healthmarketscience/jackcess/TempPageHolder.java b/src/java/com/healthmarketscience/jackcess/TempPageHolder.java
index f1fbcd6..d310a30 100644
--- a/src/java/com/healthmarketscience/jackcess/TempPageHolder.java
+++ b/src/java/com/healthmarketscience/jackcess/TempPageHolder.java
@@ -44,19 +44,17 @@ public final class TempPageHolder {
buffer has been discarded since the last page read */
private int _bufferModCount;
- private TempPageHolder(boolean hard) {
- _buffer = TempBufferHolder.newHolder(hard, false);
+ private TempPageHolder(TempBufferHolder.Type type) {
+ _buffer = TempBufferHolder.newHolder(type, false);
_bufferModCount = _buffer.getModCount();
}
/**
* Creates a new TempPageHolder.
- * @param hard iff true, the TempPageHolder will maintain a hard reference
- * to the current page buffer, otherwise will maintain a
- * SoftReference.
+ * @param type the type of reference desired for any create page buffers
*/
- public static TempPageHolder newHolder(boolean hard) {
- return new TempPageHolder(hard);
+ public static TempPageHolder newHolder(TempBufferHolder.Type type) {
+ return new TempPageHolder(type);
}
/**
diff --git a/src/java/com/healthmarketscience/jackcess/UsageMap.java b/src/java/com/healthmarketscience/jackcess/UsageMap.java
index 64656ba..9b286e6 100644
--- a/src/java/com/healthmarketscience/jackcess/UsageMap.java
+++ b/src/java/com/healthmarketscience/jackcess/UsageMap.java
@@ -638,7 +638,7 @@ public class UsageMap
{
/** Buffer that contains the current reference map page */
private final TempPageHolder _mapPageHolder =
- TempPageHolder.newHolder(false);
+ TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
private ReferenceHandler()
throws IOException