Merge lp:~pbeaman/akiban-persistit/buffer-pool-warmup-sorted into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Peter Beaman
Approved revision: 385
Merged at revision: 358
Proposed branch: lp:~pbeaman/akiban-persistit/buffer-pool-warmup-sorted
Merge into: lp:akiban-persistit
Prerequisite: lp:~pbeaman/akiban-persistit/eclipse-canonical-format
Diff against target: 1248 lines (+735/-26) (has conflicts)
15 files modified
doc/Configuration.rst (+13/-1)
src/main/java/com/persistit/BufferPool.java (+165/-3)
src/main/java/com/persistit/CheckpointManager.java (+6/-0)
src/main/java/com/persistit/Configuration.java (+92/-11)
src/main/java/com/persistit/JournalManager.java (+52/-1)
src/main/java/com/persistit/MediatedFileChannel.java (+1/-1)
src/main/java/com/persistit/Persistit.java (+30/-3)
src/main/java/com/persistit/logging/LogBase.java (+9/-0)
src/test/java/com/persistit/IOFailureTest.java (+1/-1)
src/test/java/com/persistit/StressRunner.java (+2/-0)
src/test/java/com/persistit/TrackingFileChannel.java (+175/-0)
src/test/java/com/persistit/WarmupTest.java (+105/-3)
src/test/java/com/persistit/stress/PreloadMixtureTxn1.java (+82/-0)
src/test/java/com/persistit/unit/PersistitUnitTestCase.java (+2/-1)
src/test/java/com/persistit/unit/UnitTestProperties.java (+0/-1)
Text conflict in src/main/java/com/persistit/BufferPool.java
Text conflict in src/main/java/com/persistit/CheckpointManager.java
Text conflict in src/main/java/com/persistit/Configuration.java
Text conflict in src/main/java/com/persistit/JournalManager.java
Text conflict in src/main/java/com/persistit/Persistit.java
Text conflict in src/test/java/com/persistit/WarmupTest.java
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/buffer-pool-warmup-sorted
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Approve
Review via email: mp+121320@code.launchpad.net

This proposal supersedes a proposal from 2012-08-24.

Description of the change

This proposal is a re-work of the original buffer pool warm-up code. Instead of creating a text file, this version stores the inventory in the system volume. It also loads pages in file-address order to reduce I/O time. There is a new stress test that pushes this into a medium-sized buffer pool (25K pages) but we still need to test it with a 1M page pool in TPCC or some other big test.

There are two config options, one to turn on inventory recording and the other to enable pre-loading pages. They are separate so that a server can start up without waiting for the pre-load but still be set to perform the inventory function.

Other changes include Configuration, Configuration.rst (documentation), etc.

To post a comment you must log in.
Revision history for this message
Nathan Williams (nwilliams) wrote : Posted in a previous version of this proposal

This has a pre-req of the reformatting, but it doesn't look to have kicked in.

Could you try resubmitting? If that doesn't work then I'll do the diff manually for review.

Revision history for this message
Peter Beaman (pbeaman) wrote :

Resubmitted to try to get a clean diff.

Revision history for this message
Nathan Williams (nwilliams) wrote :

The diff on LP is still wonky, but I checked out locally and everything is fine.

Changes look good, just a few questions below.

The inventory is taken in the checkpoint thread. How does the run time of the inventory scale with the size of the pool? You mentioned a 25K test, but the 1M is also a realistic size (even in our nightlies).

Along the same lines, have you tried this under any load?

Lastly, it is also done on close(). If this takes even in the 10s of seconds, we might want add an option for that.

review: Needs Information
Revision history for this message
Nathan Williams (nwilliams) wrote :

Talked with Peter about this offline and the points I raised were what he alluded to in the merge description.

Summary:
- Writing 1M records, non-transactionally, is a sub-second activity
- Start-up reading of the pages will be the slow part, perhaps minutes
- There are progress messages and this is the tradeoff to not have it spread out over hours
- And most importantly, this defaults to OFF

Given all that, putting this in is low risk and timing on large pools can be done soon^TM.

review: Approve
Revision history for this message
Akiban Build User (build-akiban) wrote :

There were 3 failures during build/test:

* job persistit-build failed at build number 408: http://172.16.20.104:8080/job/persistit-build/408/

* view must-pass failed: sql-parser-build is blue_anime

* view must-pass failed: persistit-build is yellow

review: Needs Fixing
Revision history for this message
Peter Beaman (pbeaman) wrote :

Fix WarmupTest

Revision history for this message
Akiban Build User (build-akiban) wrote :

There were 2 failures during build/test:

* job persistit-build failed at build number 410: http://172.16.20.104:8080/job/persistit-build/410/

* view must-pass failed: persistit-build is yellow

review: Needs Fixing
385. By Peter Beaman

Fix WarmupTest (again)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'doc/Configuration.rst'
--- doc/Configuration.rst 2012-06-11 21:25:37 +0000
+++ doc/Configuration.rst 2012-08-27 21:56:20 +0000
@@ -221,7 +221,7 @@
221 ``serialOverride``, ``constructorOverride``: (``com.persistit.Configuration#setSerialOverride`` ``com.persistit.Configuration#setConstructorOverride``) 221 ``serialOverride``, ``constructorOverride``: (``com.persistit.Configuration#setSerialOverride`` ``com.persistit.Configuration#setConstructorOverride``)
222 Control aspects of object serialization. See :ref:`Serialization`.222 Control aspects of object serialization. See :ref:`Serialization`.
223223
224 ``showgui``: (``com.persistit.Configuration#setShowGUI``), True of False. 224 ``showgui``: (``com.persistit.Configuration#setShowGUI``), True or False (default).
225 If true, Persistit attempts to create and display an instance of the AdminUI utility panel within the current JVM. 225 If true, Persistit attempts to create and display an instance of the AdminUI utility panel within the current JVM.
226 Alternatively, AdminUI uses RMI and can be launched and run remotely if ``rmiport`` or ``rmihost`` has been 226 Alternatively, AdminUI uses RMI and can be launched and run remotely if ``rmiport`` or ``rmihost`` has been
227 specified.227 specified.
@@ -231,6 +231,18 @@
231 install a logging adapter to reroute messages through Log4J, SLF4J or other logger. The ``logfile`` property is used 231 install a logging adapter to reroute messages through Log4J, SLF4J or other logger. The ``logfile`` property is used
232 only when no adapter has been installed.232 only when no adapter has been installed.
233233
234 ``bufferinventory``: (``com.persistit.Configuration#setBufferInventoryEnabled``), True or False (default).
235 If true, Persistit periodically records an inventory of all the buffes in the buffers pools to the System Volume. The inventory
236 enables Persistit to preload the buffer pools then next time it starts up with approximately the same pages that were present
237 before shutdown. To enable buffer preloading, the bufferpreload property must also be true.
238
239 ``bufferpreload``: (``com.persistit.Configuration#setBufferPreloadEnabled``), True or False (default).
240 If true, and if a buffer pool inventory was previously recorded, Persistit attempts to "warm up" the buffer pool
241 by preloading pages that were present in the buffer pool when Persistit last shut down. This may allow a freshly started
242 Persistit instance to begin service a workload similar to what it had previously been processing without incurring the
243 cost of many random disk reads to load pages.
244
245
234For all integer-valued properties, the suffix “K” may be used to represent kilo, “M” for mega, “G” for giga and “T” for tera. For example, “2M” represents the value 2,097,152.246For all integer-valued properties, the suffix “K” may be used to represent kilo, “M” for mega, “G” for giga and “T” for tera. For example, “2M” represents the value 2,097,152.
235247
236A Configuration Example248A Configuration Example
237249
=== modified file 'src/main/java/com/persistit/BufferPool.java'
--- src/main/java/com/persistit/BufferPool.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/BufferPool.java 2012-08-27 21:56:20 +0000
@@ -18,13 +18,20 @@
18import java.io.BufferedReader;18import java.io.BufferedReader;
19import java.io.BufferedWriter;19import java.io.BufferedWriter;
20import java.io.DataOutputStream;20import java.io.DataOutputStream;
21<<<<<<< TREE
21import java.io.File;22import java.io.File;
22import java.io.FileReader;23import java.io.FileReader;
23import java.io.FileWriter;24import java.io.FileWriter;
24import java.io.IOException;25import java.io.IOException;
26=======
27import java.io.IOException;
28>>>>>>> MERGE-SOURCE
25import java.nio.ByteBuffer;29import java.nio.ByteBuffer;
30import java.util.ArrayList;
26import java.util.Arrays;31import java.util.Arrays;
32import java.util.Collections;
27import java.util.HashSet;33import java.util.HashSet;
34import java.util.List;
28import java.util.Set;35import java.util.Set;
29import java.util.concurrent.atomic.AtomicBoolean;36import java.util.concurrent.atomic.AtomicBoolean;
30import java.util.concurrent.atomic.AtomicInteger;37import java.util.concurrent.atomic.AtomicInteger;
@@ -32,6 +39,7 @@
32import java.util.concurrent.atomic.AtomicLongArray;39import java.util.concurrent.atomic.AtomicLongArray;
33import java.util.concurrent.locks.ReentrantLock;40import java.util.concurrent.locks.ReentrantLock;
3441
42import com.persistit.JournalManager.PageNode;
35import com.persistit.exception.InUseException;43import com.persistit.exception.InUseException;
36import com.persistit.exception.InvalidPageAddressException;44import com.persistit.exception.InvalidPageAddressException;
37import com.persistit.exception.InvalidPageStructureException;45import com.persistit.exception.InvalidPageStructureException;
@@ -92,6 +100,17 @@
92 */100 */
93 private final static int WRITE_AGE_THRESHOLD_RATIO = 4;101 private final static int WRITE_AGE_THRESHOLD_RATIO = 4;
94102
103 private final static String INVENTORY_TREE_NAME = "_buffers";
104 /**
105 * Maximum number of buffer inventory versions to retain
106 */
107 private final static int INVENTORY_VERSIONS = 3;
108
109 /**
110 * Preload log multiple
111 */
112 private final static int INVENTORY_PRELOAD_LOG_MESSAGE_MULTIPLE = 10000;
113
95 /**114 /**
96 * The Persistit instance that references this BufferPool.115 * The Persistit instance that references this BufferPool.
97 */116 */
@@ -201,16 +220,21 @@
201 private volatile long _writerPollInterval = DEFAULT_WRITER_POLL_INTERVAL;220 private volatile long _writerPollInterval = DEFAULT_WRITER_POLL_INTERVAL;
202221
203 private volatile int _pageWriterTrancheSize = PAGE_WRITER_TRANCHE_SIZE;222 private volatile int _pageWriterTrancheSize = PAGE_WRITER_TRANCHE_SIZE;
223<<<<<<< TREE
204224
205 /**225 /**
206 * Polling interval for PageCacher226 * Polling interval for PageCacher
207 */227 */
208 private volatile long _cacherPollInterval;228 private volatile long _cacherPollInterval;
209229
230=======
231
232>>>>>>> MERGE-SOURCE
210 /**233 /**
211 * The PAGE_WRITER IOTaskRunnable234 * The PAGE_WRITER IOTaskRunnable
212 */235 */
213 private PageWriter _writer;236 private PageWriter _writer;
237<<<<<<< TREE
214238
215 /**239 /**
216 * The PAGE_CACHER IOTaskRunnable240 * The PAGE_CACHER IOTaskRunnable
@@ -219,6 +243,9 @@
219243
220 private String _defaultLogPath;244 private String _defaultLogPath;
221245
246=======
247
248>>>>>>> MERGE-SOURCE
222 /**249 /**
223 * Construct a BufferPool with the specified count of <code>Buffer</code>s250 * Construct a BufferPool with the specified count of <code>Buffer</code>s
224 * of the specified size.251 * of the specified size.
@@ -289,6 +316,7 @@
289 throw e;316 throw e;
290 }317 }
291 _writer = new PageWriter();318 _writer = new PageWriter();
319<<<<<<< TREE
292 _cacher = new PageCacher();320 _cacher = new PageCacher();
293 }321 }
294322
@@ -320,6 +348,8 @@
320 } catch (final IOException e) {348 } catch (final IOException e) {
321 throw new PersistitException(e);349 throw new PersistitException(e);
322 }350 }
351=======
352>>>>>>> MERGE-SOURCE
323 }353 }
324354
325 void startThreads() throws PersistitException {355 void startThreads() throws PersistitException {
@@ -329,9 +359,7 @@
329 void close() {359 void close() {
330 _closed.set(true);360 _closed.set(true);
331 _persistit.waitForIOTaskStop(_writer);361 _persistit.waitForIOTaskStop(_writer);
332 _persistit.waitForIOTaskStop(_cacher);
333 _writer = null;362 _writer = null;
334 _cacher = null;
335 }363 }
336364
337 /**365 /**
@@ -340,7 +368,6 @@
340 */368 */
341 void crash() {369 void crash() {
342 IOTaskRunnable.crash(_writer);370 IOTaskRunnable.crash(_writer);
343 IOTaskRunnable.crash(_cacher);
344 }371 }
345372
346 void flush(final long timestamp) throws PersistitInterruptedException {373 void flush(final long timestamp) throws PersistitInterruptedException {
@@ -432,6 +459,7 @@
432 buffer.populateInfo(array[index]);459 buffer.populateInfo(array[index]);
433 }460 }
434 }461 }
462<<<<<<< TREE
435463
436 private void populateWarmupFile() throws PersistitException {464 private void populateWarmupFile() throws PersistitException {
437 final File file = new File(_defaultLogPath);465 final File file = new File(_defaultLogPath);
@@ -461,6 +489,8 @@
461 throw new PersistitException(e);489 throw new PersistitException(e);
462 }490 }
463 }491 }
492=======
493>>>>>>> MERGE-SOURCE
464494
465 private boolean selected(final Buffer buffer, final int includeMask, final int excludeMask) {495 private boolean selected(final Buffer buffer, final int includeMask, final int excludeMask) {
466 return ((includeMask == 0) || (buffer.getStatus() & includeMask) != 0)496 return ((includeMask == 0) || (buffer.getStatus() & includeMask) != 0)
@@ -1402,6 +1432,7 @@
1402 return isFlushing() ? 0 : _writerPollInterval;1432 return isFlushing() ? 0 : _writerPollInterval;
1403 }1433 }
1404 }1434 }
1435<<<<<<< TREE
14051436
1406 /**1437 /**
1407 * Implementation of PAGE_CACHER thread1438 * Implementation of PAGE_CACHER thread
@@ -1431,6 +1462,8 @@
1431 return isFlushing() ? 0 : _cacherPollInterval;1462 return isFlushing() ? 0 : _cacherPollInterval;
1432 }1463 }
1433 }1464 }
1465=======
1466>>>>>>> MERGE-SOURCE
14341467
1435 @Override1468 @Override
1436 public String toString() {1469 public String toString() {
@@ -1486,4 +1519,133 @@
1486 }1519 }
1487 stream.flush();1520 stream.flush();
1488 }1521 }
1522
1523 void recordBufferInventory(final long timestamp) throws PersistitException {
1524 final Exchange exchange = getBufferInventoryExchange();
1525 /*
1526 * Advisory only - transaction integrity not needed
1527 */
1528 exchange.ignoreTransactions();
1529 try {
1530 int total = 0;
1531 exchange.clear().append(_bufferSize).append(timestamp).append(Key.BEFORE);
1532 final Value value = exchange.getValue();
1533 final int clockValueBefore = _clock.get();
1534 for (int index = 0; index < _buffers.length; index++) {
1535 final Buffer buffer = _buffers[index];
1536 long page1 = -1, page2 = -1;
1537 Volume volume1 = null, volume2 = null;
1538 if (buffer != null && buffer.isValid()) {
1539 while (true) {
1540 page1 = buffer.getPageAddress();
1541 volume1 = buffer.getVolume();
1542 page2 = buffer.getPageAddress();
1543 volume2 = buffer.getVolume();
1544 if (page1 == page2 && volume1 == volume2) {
1545 break;
1546 }
1547 Util.spinSleep();
1548 }
1549 if (volume1 != null && !volume1.isTemporary()) {
1550 value.clear().setStreamMode(true);
1551 value.put(volume1.getHandle());
1552 value.put(page1);
1553 exchange.to(index).store();
1554 total++;
1555 }
1556 }
1557 }
1558 final int clockValueAfter = _clock.get();
1559 exchange.cut();
1560 value.clear().setStreamMode(true);
1561 value.put(_bufferCount);
1562 value.put(total);
1563 value.put(clockValueBefore);
1564 value.put(clockValueAfter);
1565 value.put(System.currentTimeMillis());
1566 exchange.store();
1567 int count = 0;
1568 while (exchange.previous()) {
1569 if (++count > INVENTORY_VERSIONS) {
1570 exchange.remove(Key.GTEQ);
1571 }
1572 }
1573 } catch (final PersistitException e) {
1574 _persistit.getLogBase().bufferInventoryException.log(e);
1575 }
1576 }
1577
1578 void preloadBufferInventory() {
1579 int count = 0;
1580 int total = 0;
1581 try {
1582 final JournalManager jman = _persistit.getJournalManager();
1583 final Exchange exchange = getBufferInventoryExchange();
1584 final Value value = exchange.getValue();
1585 final List<PageNode> pageNodes = new ArrayList<PageNode>();
1586 boolean foundInventory = false;
1587 exchange.clear().append(_bufferSize).append(Key.AFTER);
1588 while (exchange.previous()) {
1589 if (exchange.getValue().isDefined()) {
1590 foundInventory = true;
1591 break;
1592 }
1593 }
1594 if (!foundInventory) {
1595 return;
1596 }
1597 value.setStreamMode(true);
1598 /* int bufferCount = */value.getInt();
1599 total = value.getInt();
1600 /* int clockValueBefore = */value.getInt();
1601 /* int clockValueAfter = */value.getInt();
1602 final long systemTime = value.getLong();
1603
1604 _persistit.getLogBase().bufferInventoryLoad.log(systemTime);
1605
1606 exchange.append(Key.BEFORE);
1607
1608 while (exchange.next()) {
1609 value.setStreamMode(true);
1610 final int volumeHandle = value.getInt();
1611 final long pageAddress = value.getLong();
1612 final PageNode pn = new PageNode(volumeHandle, pageAddress);
1613 pageNodes.add(pn);
1614 }
1615
1616 Collections.sort(pageNodes, PageNode.READ_COMPARATOR);
1617 for (final PageNode pn : pageNodes) {
1618 final Volume vol = jman.volumeForHandle(pn.getVolumeHandle());
1619 if (vol == null) {
1620 continue;
1621 }
1622 try {
1623 final Buffer buff = get(vol, pn.getPageAddress(), false, true);
1624 buff.release();
1625 count++;
1626 if ((count % INVENTORY_PRELOAD_LOG_MESSAGE_MULTIPLE) == 0) {
1627 _persistit.getLogBase().bufferInventoryProgress.log(count, total);
1628 }
1629 if (count >= _bufferCount) {
1630 //
1631 // If the buffer pool is now smaller, no need to load
1632 // more pages
1633 //
1634 break;
1635 }
1636 } catch (final PersistitException e) {
1637 // ignore it
1638 }
1639 }
1640 } catch (final PersistitException e) {
1641 _persistit.getLogBase().bufferInventoryException.log(e);
1642 } finally {
1643 _persistit.getLogBase().bufferInventoryProgress.log(count, total);
1644 }
1645 }
1646
1647 private Exchange getBufferInventoryExchange() throws PersistitException {
1648 final Volume sysvol = _persistit.getSystemVolume();
1649 return _persistit.getExchange(sysvol, INVENTORY_TREE_NAME, true);
1650 }
1489}1651}
14901652
=== modified file 'src/main/java/com/persistit/CheckpointManager.java'
--- src/main/java/com/persistit/CheckpointManager.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/CheckpointManager.java 2012-08-27 21:56:20 +0000
@@ -201,6 +201,7 @@
201 void pollCreateCheckpoint() throws PersistitException {201 void pollCreateCheckpoint() throws PersistitException {
202 final long now = System.nanoTime();202 final long now = System.nanoTime();
203 if (_lastCheckpointNanos + _checkpointIntervalNanos < now) {203 if (_lastCheckpointNanos + _checkpointIntervalNanos < now) {
204 _persistit.recordBufferPoolInventory();
204 createCheckpoint();205 createCheckpoint();
205 }206 }
206 }207 }
@@ -252,12 +253,17 @@
252 _currentCheckpoint = new Checkpoint(txn.getStartTimestamp(), System.currentTimeMillis());253 _currentCheckpoint = new Checkpoint(txn.getStartTimestamp(), System.currentTimeMillis());
253 _outstandingCheckpoints.add(_currentCheckpoint);254 _outstandingCheckpoints.add(_currentCheckpoint);
254 _persistit.getLogBase().checkpointProposed.log(_currentCheckpoint);255 _persistit.getLogBase().checkpointProposed.log(_currentCheckpoint);
256<<<<<<< TREE
255 return _currentCheckpoint;257 return _currentCheckpoint;
256 } catch (final InterruptedException ie) {258 } catch (final InterruptedException ie) {
259=======
260 } catch (final InterruptedException ie) {
261>>>>>>> MERGE-SOURCE
257 throw new PersistitInterruptedException(ie);262 throw new PersistitInterruptedException(ie);
258 } finally {263 } finally {
259 txn.end();264 txn.end();
260 }265 }
266 return _currentCheckpoint;
261 } finally {267 } finally {
262 _persistit.setSessionId(saveSessionId);268 _persistit.setSessionId(saveSessionId);
263 }269 }
264270
=== modified file 'src/main/java/com/persistit/Configuration.java'
--- src/main/java/com/persistit/Configuration.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/Configuration.java 2012-08-27 21:56:20 +0000
@@ -263,8 +263,13 @@
263 /**263 /**
264 * Property name for the "append only" property.264 * Property name for the "append only" property.
265 */265 */
266<<<<<<< TREE
266 public final static String APPEND_ONLY_PROPERTY = "appendonly";267 public final static String APPEND_ONLY_PROPERTY = "appendonly";
267268
269=======
270 public final static String APPEND_ONLY_PROPERTY_NAME = "appendonly";
271
272>>>>>>> MERGE-SOURCE
268 /**273 /**
269 * Property name for the "ignore missing volumes" property.274 * Property name for the "ignore missing volumes" property.
270 */275 */
@@ -274,13 +279,27 @@
274 * Property name to specify the default {@link SplitPolicy}.279 * Property name to specify the default {@link SplitPolicy}.
275 */280 */
276 public final static String SPLIT_POLICY_PROPERTY_NAME = "splitpolicy";281 public final static String SPLIT_POLICY_PROPERTY_NAME = "splitpolicy";
282<<<<<<< TREE
277283
278 /**284 /**
279 * Property name to specify the"buffer inventory" property name.285 * Property name to specify the"buffer inventory" property name.
286=======
287
288 /**
289 * Property name to specify whether buffer preloading is enabled.
290 */
291 public final static String BUFFER_PRELOAD_PROPERTY_NAME = "bufferpreload";
292
293 /**
294 * Property name to specify whether buffer inventory is enabled.
295>>>>>>> MERGE-SOURCE
280 */296 */
281 public final static String BUFFER_INVENTORY_PROPERTY_NAME = "bufferinventory";297 public final static String BUFFER_INVENTORY_PROPERTY_NAME = "bufferinventory";
298<<<<<<< TREE
282299
283 public final static String BUFFER_POLLING_INTERVAL_PROPERTY = "bufferpollinginterval";300 public final static String BUFFER_POLLING_INTERVAL_PROPERTY = "bufferpollinginterval";
301=======
302>>>>>>> MERGE-SOURCE
284303
285 /**304 /**
286 * Property name to specify the default {@link JoinPolicy}.305 * Property name to specify the default {@link JoinPolicy}.
@@ -634,9 +653,14 @@
634 private int rmiServerPort;653 private int rmiServerPort;
635 private boolean jmx = true;654 private boolean jmx = true;
636 private boolean appendOnly;655 private boolean appendOnly;
656<<<<<<< TREE
637 private String bufferInventoryPathName;657 private String bufferInventoryPathName;
638 private long bufferInventoryPollInterval = 3000000; // default five minute658 private long bufferInventoryPollInterval = 3000000; // default five minute
639 // polling659 // polling
660=======
661 private boolean bufferInventoryEnabled;
662 private boolean bufferPreloadEnabled;
663>>>>>>> MERGE-SOURCE
640 private boolean ignoreMissingVolumes;664 private boolean ignoreMissingVolumes;
641 private String tmpVolDir;665 private String tmpVolDir;
642 private int tmpVolPageSize;666 private int tmpVolPageSize;
@@ -715,9 +739,7 @@
715 }739 }
716740
717 void loadProperties() throws InvalidVolumeSpecificationException {741 void loadProperties() throws InvalidVolumeSpecificationException {
718 setBufferInventoryPathName(getProperty(BUFFER_INVENTORY_PROPERTY_NAME));742 setAppendOnly(getBooleanProperty(APPEND_ONLY_PROPERTY_NAME, false));
719 setBufferInventoryPollingInterval(getLongProperty(BUFFER_POLLING_INTERVAL_PROPERTY, bufferInventoryPollInterval));
720 setAppendOnly(getBooleanProperty(APPEND_ONLY_PROPERTY, false));
721 setCommitPolicy(getProperty(COMMIT_POLICY_PROPERTY_NAME));743 setCommitPolicy(getProperty(COMMIT_POLICY_PROPERTY_NAME));
722 setConstructorOverride(getBooleanProperty(CONSTRUCTOR_OVERRIDE_PROPERTY_NAME, false));744 setConstructorOverride(getBooleanProperty(CONSTRUCTOR_OVERRIDE_PROPERTY_NAME, false));
723 setIgnoreMissingVolumes(getBooleanProperty(IGNORE_MISSING_VOLUMES_PROPERTY, false));745 setIgnoreMissingVolumes(getBooleanProperty(IGNORE_MISSING_VOLUMES_PROPERTY, false));
@@ -737,6 +759,8 @@
737 setShowGUI(getBooleanProperty(SHOW_GUI_PROPERTY_NAME, false));759 setShowGUI(getBooleanProperty(SHOW_GUI_PROPERTY_NAME, false));
738 setSplitPolicy(getProperty(SPLIT_POLICY_PROPERTY_NAME));760 setSplitPolicy(getProperty(SPLIT_POLICY_PROPERTY_NAME));
739 setSysVolume(getProperty(SYSTEM_VOLUME_PROPERTY_NAME, DEFAULT_SYSTEM_VOLUME_NAME));761 setSysVolume(getProperty(SYSTEM_VOLUME_PROPERTY_NAME, DEFAULT_SYSTEM_VOLUME_NAME));
762 setBufferInventoryEnabled(getBooleanProperty(BUFFER_INVENTORY_PROPERTY_NAME, false));
763 setBufferPreloadEnabled(getBooleanProperty(BUFFER_PRELOAD_PROPERTY_NAME, false));
740764
741 loadPropertiesBufferSpecifications();765 loadPropertiesBufferSpecifications();
742 loadPropertiesVolumeSpecifications();766 loadPropertiesVolumeSpecifications();
@@ -1548,8 +1572,7 @@
1548 /**1572 /**
1549 * <p>1573 * <p>
1550 * Set a pattern that identifies classes to be serialized using standard1574 * Set a pattern that identifies classes to be serialized using standard
1551 * Java serialization rather than Persistit's default serialization. TODO1575 * Java serialization rather than Persistit's default serialization.
1552 * Link to Serialization section of user_guide.html.
1553 * </p>1576 * </p>
1554 * <p>1577 * <p>
1555 * Default value is <code>null</code><br />1578 * Default value is <code>null</code><br />
@@ -1559,6 +1582,8 @@
1559 * @param serialOverride1582 * @param serialOverride
1560 * the serial override pattern to set1583 * the serial override pattern to set
1561 * @see DefaultCoderManager1584 * @see DefaultCoderManager
1585 * @see <a
1586 * href="http://www.akiban.com/ak-docs/admin/persistit/Serialization.html">Serialization</a>
1562 */1587 */
1563 public void setSerialOverride(final String serialOverride) {1588 public void setSerialOverride(final String serialOverride) {
1564 this.serialOverride = serialOverride;1589 this.serialOverride = serialOverride;
@@ -1579,8 +1604,7 @@
1579 * a public no-argument constructor. If so, then that constructor is used1604 * a public no-argument constructor. If so, then that constructor is used
1580 * when deserializing in the {@link DefaultObjectCoder}; if not then1605 * when deserializing in the {@link DefaultObjectCoder}; if not then
1581 * Persistit uses private methods within the JDK to emulate standard Java1606 * Persistit uses private methods within the JDK to emulate standard Java
1582 * serialization logic. TODO Link to Serialization section of1607 * serialization logic.
1583 * user_guide.html.
1584 * </p>1608 * </p>
1585 * <p>1609 * <p>
1586 * Default value is <code>false</code><br />1610 * Default value is <code>false</code><br />
@@ -1589,6 +1613,8 @@
1589 * 1613 *
1590 * @param constructorOverride1614 * @param constructorOverride
1591 * the constructorOverride to set1615 * the constructorOverride to set
1616 * @see <a
1617 * href="http://www.akiban.com/ak-docs/admin/persistit/Serialization.html">Serialization</a>
1592 */1618 */
1593 public void setConstructorOverride(final boolean constructorOverride) {1619 public void setConstructorOverride(final boolean constructorOverride) {
1594 this.constructorOverride = constructorOverride;1620 this.constructorOverride = constructorOverride;
@@ -1791,7 +1817,7 @@
1791 /**1817 /**
1792 * Return the value defined by {@link #setAppendOnly}1818 * Return the value defined by {@link #setAppendOnly}
1793 * 1819 *
1794 * @return the whether to start Persistit in append-only mode1820 * @return <true>true</code> if append-only mode is enabled at startup
1795 */1821 */
1796 public boolean isAppendOnly() {1822 public boolean isAppendOnly() {
1797 return appendOnly;1823 return appendOnly;
@@ -1807,17 +1833,18 @@
1807 * </p>1833 * </p>
1808 * <p>1834 * <p>
1809 * Default value is <code>false</code><br />1835 * Default value is <code>false</code><br />
1810 * Property name is {@value #APPEND_ONLY_PROPERTY}1836 * Property name is {@value #APPEND_ONLY_PROPERTY_NAME}
1811 * </p>1837 * </p>
1812 * 1838 *
1813 * @param appendOnly1839 * @param appendOnly
1814 * <code>true</code> to start Persistit in append-only only1840 * <code>true</code> to start Persistit in append-only mode
1815 */1841 */
1816 public void setAppendOnly(final boolean appendOnly) {1842 public void setAppendOnly(final boolean appendOnly) {
1817 this.appendOnly = appendOnly;1843 this.appendOnly = appendOnly;
1818 }1844 }
18191845
1820 /**1846 /**
1847<<<<<<< TREE
1821 * Return the path name defined by {@link #getBufferInventoryPathName}1848 * Return the path name defined by {@link #getBufferInventoryPathName}
1822 * 1849 *
1823 * @return the path where file to warm-up Persistit with sample buffer data1850 * @return the path where file to warm-up Persistit with sample buffer data
@@ -1874,10 +1901,64 @@
1874 bufferInventoryPollInterval = Util.rangeCheck(seconds, 60L, Long.MAX_VALUE) * 1000L;1901 bufferInventoryPollInterval = Util.rangeCheck(seconds, 60L, Long.MAX_VALUE) * 1000L;
1875 }1902 }
18761903
1904=======
1905 * Return the value defined by {@link #setBufferInventoryEnabled}
1906 *
1907 * @return <code>true</code> if periodic buffer pool inventory recording is
1908 * enabled
1909 */
1910 public boolean isBufferInventoryEnabled() {
1911 return bufferInventoryEnabled;
1912 }
1913
1914 /**
1915 * <p>
1916 * Control whether Persistit periodically records an inventory of its buffer
1917 * pools to enable buffer pool preloading on a subsequent startup.
1918 * </p>
1919 * <p>
1920 * Default value is <code>false</code><br />
1921 * Property name is {@value #BUFFER_INVENTORY_PROPERTY_NAME}
1922 *
1923 * @param bufferInventoryEnabled
1924 * <code>true</code> to enable periodic buffer inventory behavior
1925 */
1926 public void setBufferInventoryEnabled(final boolean bufferInventoryEnabled) {
1927 this.bufferInventoryEnabled = bufferInventoryEnabled;
1928 }
1929
1930 /**
1931 * Return the value defined by {@link #setBufferPreloadEnabled}
1932 *
1933 * @return <code>true</code> if the option to preload buffer pools is
1934 * enabled
1935 */
1936 public boolean isBufferPreloadEnabled() {
1937 return bufferPreloadEnabled;
1938 }
1939
1940 /**
1941 * <p>
1942 * Control whether Persistit attempts to preload (warm up) the buffer pools
1943 * by preloading pages recorded in a previously generated inventory.
1944 * </p>
1945 * <p>
1946 * Default value is <code>false</code><br />
1947 * Property name is {@value #BUFFER_INVENTORY_PROPERTY_NAME}
1948 *
1949 * @param bufferPreloadEnabled
1950 * <code>true</code> to enable buffer pool preloading during
1951 * startup
1952 */
1953 public void setBufferPreloadEnabled(final boolean bufferPreloadEnabled) {
1954 this.bufferPreloadEnabled = bufferPreloadEnabled;
1955 }
1956
1957>>>>>>> MERGE-SOURCE
1877 /**1958 /**
1878 * Return the value defined by {@link #setIgnoreMissingVolumes(boolean)}1959 * Return the value defined by {@link #setIgnoreMissingVolumes(boolean)}
1879 * 1960 *
1880 * @return the whether to start Persistit in ignore-missing-volumes mode1961 * @return <code>true</code>to enable ignore-missing-volumes mode
1881 */1962 */
1882 public boolean isIgnoreMissingVolumes() {1963 public boolean isIgnoreMissingVolumes() {
1883 return ignoreMissingVolumes;1964 return ignoreMissingVolumes;
18841965
=== modified file 'src/main/java/com/persistit/JournalManager.java'
--- src/main/java/com/persistit/JournalManager.java 2012-08-23 15:24:42 +0000
+++ src/main/java/com/persistit/JournalManager.java 2012-08-27 21:56:20 +0000
@@ -690,6 +690,29 @@
690 final ByteBuffer bb = buffer.getByteBuffer();690 final ByteBuffer bb = buffer.getByteBuffer();
691691
692 final Volume volume = buffer.getVolume();692 final Volume volume = buffer.getVolume();
693 final PageNode pn = lookupUpPageNode(pageAddress, volume);
694 if (pn == null) {
695 return false;
696 }
697 bb.position(0);
698 final long recordPageAddress = readPageBufferFromJournal(pn, bb);
699 _persistit.getIOMeter().chargeReadPageFromJournal(volume, pageAddress, bufferSize, pn.getJournalAddress(),
700 buffer.getIndex());
701
702 if (pageAddress != recordPageAddress) {
703 throw new CorruptJournalException("Record at " + pn + " is not volume/page " + buffer.toString());
704 }
705
706 if (bb.limit() != bufferSize) {
707 throw new CorruptJournalException("Record at " + pn + " is wrong size: expected/actual=" + bufferSize + "/"
708 + bb.limit());
709 }
710 _readPageCount++;
711 buffer.getVolume().getStatistics().bumpReadCounter();
712 return true;
713 }
714
715 PageNode lookupUpPageNode(final long pageAddress, final Volume volume) {
693 PageNode pnLookup = null;716 PageNode pnLookup = null;
694 synchronized (this) {717 synchronized (this) {
695 final Integer volumeHandle = _volumeToHandleMap.get(volume);718 final Integer volumeHandle = _volumeToHandleMap.get(volume);
@@ -699,7 +722,7 @@
699 }722 }
700723
701 if (pnLookup == null) {724 if (pnLookup == null) {
702 return false;725 return null;
703 }726 }
704727
705 final PageNode pn = new PageNode(pnLookup.getVolumeHandle(), pnLookup.getPageAddress(),728 final PageNode pn = new PageNode(pnLookup.getVolumeHandle(), pnLookup.getPageAddress(),
@@ -714,6 +737,7 @@
714 * new checkpoints and that keeps the copier from deleting it.737 * new checkpoints and that keeps the copier from deleting it.
715 */738 */
716 if (pnLookup.isInvalid()) {739 if (pnLookup.isInvalid()) {
740<<<<<<< TREE
717 return false;741 return false;
718 }742 }
719743
@@ -733,6 +757,11 @@
733 _readPageCount++;757 _readPageCount++;
734 buffer.getVolume().getStatistics().bumpReadCounter();758 buffer.getVolume().getStatistics().bumpReadCounter();
735 return true;759 return true;
760=======
761 return null;
762 }
763 return pn;
764>>>>>>> MERGE-SOURCE
736 }765 }
737766
738 private long readPageBufferFromJournal(final PageNode pn, final ByteBuffer bb) throws PersistitIOException,767 private long readPageBufferFromJournal(final PageNode pn, final ByteBuffer bb) throws PersistitIOException,
@@ -1829,6 +1858,10 @@
18291858
1830 PageNode _previous;1859 PageNode _previous;
18311860
1861 PageNode(final int volumeHandle, final long pageAddress) {
1862 this(volumeHandle, pageAddress, Long.MIN_VALUE, -1);
1863 }
1864
1832 PageNode(final int volumeHandle, final long pageAddress, final long journalAddress, final long timestamp) {1865 PageNode(final int volumeHandle, final long pageAddress, final long journalAddress, final long timestamp) {
1833 this._volumeHandle = volumeHandle;1866 this._volumeHandle = volumeHandle;
1834 this._pageAddress = pageAddress;1867 this._pageAddress = pageAddress;
@@ -1949,9 +1982,27 @@
1949 final static Comparator<PageNode> READ_COMPARATOR = new Comparator<PageNode>() {1982 final static Comparator<PageNode> READ_COMPARATOR = new Comparator<PageNode>() {
19501983
1951 @Override1984 @Override
1985<<<<<<< TREE
1952 public int compare(final PageNode a, final PageNode b) {1986 public int compare(final PageNode a, final PageNode b) {
1953 return a.getJournalAddress() > b.getJournalAddress() ? 1 : a.getJournalAddress() < b1987 return a.getJournalAddress() > b.getJournalAddress() ? 1 : a.getJournalAddress() < b
1954 .getJournalAddress() ? -1 : 0;1988 .getJournalAddress() ? -1 : 0;
1989=======
1990 public int compare(final PageNode a, final PageNode b) {
1991 if (!a.isInvalid() && !b.isInvalid()) {
1992 return a.getJournalAddress() > b.getJournalAddress() ? 1 : a.getJournalAddress() < b
1993 .getJournalAddress() ? -1 : 0;
1994 }
1995 if (a.isInvalid() && !b.isInvalid()) {
1996 return -1;
1997 }
1998 if (!a.isInvalid() && b.isInvalid()) {
1999 return 1;
2000 }
2001 if (a._volumeHandle != b._volumeHandle) {
2002 return a._volumeHandle - b._volumeHandle;
2003 }
2004 return a._pageAddress > b._pageAddress ? 1 : a._pageAddress < b._pageAddress ? -1 : 0;
2005>>>>>>> MERGE-SOURCE
1955 }2006 }
1956 };2007 };
19572008
19582009
=== modified file 'src/main/java/com/persistit/MediatedFileChannel.java'
--- src/main/java/com/persistit/MediatedFileChannel.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/MediatedFileChannel.java 2012-08-27 21:56:20 +0000
@@ -342,7 +342,7 @@
342 * 342 *
343 * @param channel343 * @param channel
344 */344 */
345 void setErrorInjectingChannelForTests(final FileChannel channel) {345 void injectChannelForTests(final FileChannel channel) {
346 ((TestChannelInjector) channel).setChannel(_channel);346 ((TestChannelInjector) channel).setChannel(_channel);
347 _channel = channel;347 _channel = channel;
348 }348 }
349349
=== modified file 'src/main/java/com/persistit/Persistit.java'
--- src/main/java/com/persistit/Persistit.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/Persistit.java 2012-08-27 21:56:20 +0000
@@ -403,6 +403,7 @@
403403
404 private final AtomicBoolean _suspendShutdown = new AtomicBoolean(false);404 private final AtomicBoolean _suspendShutdown = new AtomicBoolean(false);
405 private final AtomicBoolean _suspendUpdates = new AtomicBoolean(false);405 private final AtomicBoolean _suspendUpdates = new AtomicBoolean(false);
406 private final AtomicBoolean _enableBufferInventory = new AtomicBoolean(false);
406407
407 private UtilControl _localGUI;408 private UtilControl _localGUI;
408409
@@ -588,9 +589,7 @@
588 initializeVolumes();589 initializeVolumes();
589 startJournal();590 startJournal();
590 startBufferPools();591 startBufferPools();
591 if (_configuration.getBufferInventoryPathName() != null) {592 preloadBufferPools();
592 warmupBufferPools();
593 }
594 finishRecovery();593 finishRecovery();
595 startCheckpointManager();594 startCheckpointManager();
596 startTransactionIndexPollTask();595 startTransactionIndexPollTask();
@@ -699,6 +698,7 @@
699 _defaultSplitPolicy = _configuration.getSplitPolicy();698 _defaultSplitPolicy = _configuration.getSplitPolicy();
700 _defaultJoinPolicy = _configuration.getJoinPolicy();699 _defaultJoinPolicy = _configuration.getJoinPolicy();
701 _defaultCommitPolicy = _configuration.getCommitPolicy();700 _defaultCommitPolicy = _configuration.getCommitPolicy();
701 _enableBufferInventory.set(_configuration.isBufferInventoryEnabled());
702 }702 }
703703
704 void startCheckpointManager() {704 void startCheckpointManager() {
@@ -718,11 +718,33 @@
718 pool.startThreads();718 pool.startThreads();
719 }719 }
720 }720 }
721<<<<<<< TREE
721722
722 void warmupBufferPools() throws PersistitException {723 void warmupBufferPools() throws PersistitException {
723 final String pathName = _configuration.getBufferInventoryPathName();724 final String pathName = _configuration.getBufferInventoryPathName();
724 for (final BufferPool pool : _bufferPoolTable.values()) {725 for (final BufferPool pool : _bufferPoolTable.values()) {
725 pool.warmupBufferPool(pathName, pool.toString());726 pool.warmupBufferPool(pathName, pool.toString());
727=======
728
729 void recordBufferPoolInventory() {
730 final long timestamp = _timestampAllocator.getCurrentTimestamp();
731 if (_enableBufferInventory.get()) {
732 for (final BufferPool pool : _bufferPoolTable.values()) {
733 try {
734 pool.recordBufferInventory(timestamp);
735 } catch (PersistitException e) {
736 getLogBase().bufferInventoryException.log(e);
737 }
738 }
739 }
740 }
741
742 void preloadBufferPools() throws PersistitException {
743 if (_configuration.isBufferPreloadEnabled()) {
744 for (final BufferPool pool : _bufferPoolTable.values()) {
745 pool.preloadBufferInventory();
746 }
747>>>>>>> MERGE-SOURCE
726 }748 }
727 }749 }
728750
@@ -974,9 +996,13 @@
974 * 996 *
975 * @throws IllegalStateException997 * @throws IllegalStateException
976 */998 */
999<<<<<<< TREE
9771000
978 // TODO - why not one pool.1001 // TODO - why not one pool.
979 public void releaseExchange(final Exchange exchange, final boolean secure) {1002 public void releaseExchange(final Exchange exchange, final boolean secure) {
1003=======
1004 public void releaseExchange(final Exchange exchange, final boolean secure) {
1005>>>>>>> MERGE-SOURCE
980 if (exchange == null) {1006 if (exchange == null) {
981 return;1007 return;
982 }1008 }
@@ -1638,6 +1664,7 @@
1638 }1664 }
1639 }1665 }
1640 }1666 }
1667 recordBufferPoolInventory();
16411668
1642 /*1669 /*
1643 * The copier is responsible for background pruning of aborted1670 * The copier is responsible for background pruning of aborted
16441671
=== modified file 'src/main/java/com/persistit/logging/LogBase.java'
--- src/main/java/com/persistit/logging/LogBase.java 2012-08-15 16:11:36 +0000
+++ src/main/java/com/persistit/logging/LogBase.java 2012-08-27 21:56:20 +0000
@@ -244,6 +244,15 @@
244 @Message("ERROR|Too many journal files %,d")244 @Message("ERROR|Too many journal files %,d")
245 public final LogItem tooManyJournalFilesError = PersistitLogMessage.empty();245 public final LogItem tooManyJournalFilesError = PersistitLogMessage.empty();
246246
247 @Message("INFO|Preloading buffer pool inventory recorded at %tc")
248 public final LogItem bufferInventoryLoad = PersistitLogMessage.empty();
249
250 @Message("INFO|Preloaded %,d of %,d buffers")
251 public final LogItem bufferInventoryProgress = PersistitLogMessage.empty();
252
253 @Message("WARNING|Exception while writing buffer pool inventory %s")
254 public final LogItem bufferInventoryException = PersistitLogMessage.empty();
255
247 public static String recurring(final String message, final int count, final long duration) {256 public static String recurring(final String message, final int count, final long duration) {
248 return String.format(RECURRING, message, count, duration);257 return String.format(RECURRING, message, count, duration);
249 }258 }
250259
=== modified file 'src/test/java/com/persistit/IOFailureTest.java'
--- src/test/java/com/persistit/IOFailureTest.java 2012-08-15 16:11:36 +0000
+++ src/test/java/com/persistit/IOFailureTest.java 2012-08-27 21:56:20 +0000
@@ -57,7 +57,7 @@
5757
58 private ErrorInjectingFileChannel errorInjectingChannel(final FileChannel channel) {58 private ErrorInjectingFileChannel errorInjectingChannel(final FileChannel channel) {
59 final ErrorInjectingFileChannel eimfc = new ErrorInjectingFileChannel();59 final ErrorInjectingFileChannel eimfc = new ErrorInjectingFileChannel();
60 ((MediatedFileChannel) channel).setErrorInjectingChannelForTests(eimfc);60 ((MediatedFileChannel) channel).injectChannelForTests(eimfc);
61 return eimfc;61 return eimfc;
62 }62 }
6363
6464
=== modified file 'src/test/java/com/persistit/StressRunner.java'
--- src/test/java/com/persistit/StressRunner.java 2012-08-15 16:11:36 +0000
+++ src/test/java/com/persistit/StressRunner.java 2012-08-27 21:56:20 +0000
@@ -31,6 +31,7 @@
31import com.persistit.stress.MixtureTxn1;31import com.persistit.stress.MixtureTxn1;
32import com.persistit.stress.MixtureTxn2;32import com.persistit.stress.MixtureTxn2;
33import com.persistit.stress.PersistitMap1;33import com.persistit.stress.PersistitMap1;
34import com.persistit.stress.PreloadMixtureTxn1;
34import com.persistit.stress.StartStop;35import com.persistit.stress.StartStop;
35import com.persistit.stress.Stress10Suite;36import com.persistit.stress.Stress10Suite;
36import com.persistit.stress.Stress12txnSuite;37import com.persistit.stress.Stress12txnSuite;
@@ -79,6 +80,7 @@
79 _classes.add(Stress12txnSuite.class);80 _classes.add(Stress12txnSuite.class);
80 _classes.add(Stress4Suite.class);81 _classes.add(Stress4Suite.class);
81 _classes.add(Stress8txnSuite.class);82 _classes.add(Stress8txnSuite.class);
83 _classes.add(PreloadMixtureTxn1.class);
82 }84 }
8385
84 private final static String DURATION_PARAM = "duration=";86 private final static String DURATION_PARAM = "duration=";
8587
=== added file 'src/test/java/com/persistit/TrackingFileChannel.java'
--- src/test/java/com/persistit/TrackingFileChannel.java 1970-01-01 00:00:00 +0000
+++ src/test/java/com/persistit/TrackingFileChannel.java 2012-08-27 21:56:20 +0000
@@ -0,0 +1,175 @@
1/**
2 * Copyright © 2012 Akiban Technologies, Inc. All rights reserved.
3 *
4 * This program and the accompanying materials are made available
5 * under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * This program may also be available under different license terms.
10 * For more information, see www.akiban.com or contact licensing@akiban.com.
11 *
12 * Contributors:
13 * Akiban Technologies, Inc.
14 */
15
16package com.persistit;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertTrue;
20import static org.junit.Assert.fail;
21import java.io.IOException;
22import java.nio.ByteBuffer;
23import java.nio.MappedByteBuffer;
24import java.nio.channels.FileChannel;
25import java.nio.channels.FileLock;
26import java.nio.channels.ReadableByteChannel;
27import java.nio.channels.WritableByteChannel;
28import java.util.ArrayList;
29import java.util.List;
30
31import com.persistit.MediatedFileChannel.TestChannelInjector;
32
33/**
34 * <p>
35 * A {@link FileChannel} implementation that simulates IOExceptions under
36 * control of a unit test program. This class implements only those methods used
37 * by Persistit; many methods of FileChannel throw
38 * {@link UnsupportedOperationException}.
39 * </p>
40 *
41 * @author peter
42 *
43 */
44class TrackingFileChannel extends FileChannel implements TestChannelInjector {
45
46 volatile FileChannel _channel;
47
48 final List<Long> _writePositions = new ArrayList<Long>();
49
50 final List<Long> _readPositions = new ArrayList<Long>();
51
52 @Override
53 public void setChannel(final FileChannel channel) {
54 _channel = channel;
55 }
56
57 @Override
58 protected void implCloseChannel() throws IOException {
59 _channel.close();
60 }
61
62 @Override
63 public void force(final boolean metaData) throws IOException {
64 _channel.force(metaData);
65 }
66
67 @Override
68 public int read(final ByteBuffer byteBuffer, final long position) throws IOException {
69 _readPositions.add(position);
70 return _channel.read(byteBuffer, position);
71 }
72
73 @Override
74 public long size() throws IOException {
75 return _channel.size();
76 }
77
78 @Override
79 public FileChannel truncate(final long size) throws IOException {
80 return _channel.truncate(size);
81 }
82
83 @Override
84 public synchronized FileLock tryLock(final long position, final long size, final boolean shared) throws IOException {
85 return _channel.tryLock(position, size, shared);
86 }
87
88 @Override
89 public int write(final ByteBuffer byteBuffer, final long position) throws IOException {
90 _writePositions.add(position);
91 final int written = _channel.write(byteBuffer, position);
92 return written;
93 }
94
95 /*
96 * --------------------------------
97 *
98 * Persistit does not use these methods and so they are Unsupported. Note
99 * that it would be difficult to support the relative read/write methods
100 * because the channel size is unavailable after it is closed. Therefore a
101 * client of this class must maintain its own position counter and cannot
102 * use the relative-addressing calls.
103 *
104 * --------------------------------
105 */
106 @Override
107 public FileLock lock(final long position, final long size, final boolean shared) throws IOException {
108 throw new UnsupportedOperationException();
109 }
110
111 @Override
112 public MappedByteBuffer map(final MapMode arg0, final long arg1, final long arg2) throws IOException {
113 throw new UnsupportedOperationException();
114 }
115
116 @Override
117 public long position() throws IOException {
118 throw new UnsupportedOperationException();
119 }
120
121 @Override
122 public FileChannel position(final long arg0) throws IOException {
123 throw new UnsupportedOperationException();
124 }
125
126 @Override
127 public int read(final ByteBuffer byteBuffer) throws IOException {
128 throw new UnsupportedOperationException();
129 }
130
131 @Override
132 public long read(final ByteBuffer[] arg0, final int arg1, final int arg2) throws IOException {
133 throw new UnsupportedOperationException();
134 }
135
136 @Override
137 public long transferFrom(final ReadableByteChannel arg0, final long arg1, final long arg2) throws IOException {
138 throw new UnsupportedOperationException();
139 }
140
141 @Override
142 public long transferTo(final long arg0, final long arg1, final WritableByteChannel arg2) throws IOException {
143 throw new UnsupportedOperationException();
144 }
145
146 @Override
147 public int write(final ByteBuffer byteBuffer) throws IOException {
148 throw new UnsupportedOperationException();
149 }
150
151 @Override
152 public long write(final ByteBuffer[] arg0, final int arg1, final int arg2) throws IOException {
153 throw new UnsupportedOperationException();
154 }
155
156 public List<Long> getWritePositionList() {
157 return _writePositions;
158 }
159
160 public List<Long> getReadPositionList() {
161 return _readPositions;
162 }
163
164 public void assertOrdered(boolean read, boolean forward) {
165 final List<Long> list = read ? _readPositions : _writePositions;
166 long previous = forward ? -1 : Long.MAX_VALUE;
167 for (final Long position : list) {
168 if (forward) {
169 assertTrue("Position should be larger", position > previous);
170 } else {
171 assertTrue("Position should be smaller", position < previous);
172 }
173 }
174 }
175}
0176
=== modified file 'src/test/java/com/persistit/WarmupTest.java'
--- src/test/java/com/persistit/WarmupTest.java 2012-08-15 16:11:36 +0000
+++ src/test/java/com/persistit/WarmupTest.java 2012-08-27 21:56:20 +0000
@@ -15,8 +15,14 @@
1515
16package com.persistit;16package com.persistit;
1717
18import static org.junit.Assert.assertEquals;18<<<<<<< TREE
1919import static org.junit.Assert.assertEquals;
20
21=======
22import static org.junit.Assert.assertEquals;
23import static org.junit.Assert.assertTrue;
24
25>>>>>>> MERGE-SOURCE
20import java.util.Properties;26import java.util.Properties;
2127
22import org.junit.Test;28import org.junit.Test;
@@ -24,14 +30,28 @@
24import com.persistit.unit.PersistitUnitTestCase;30import com.persistit.unit.PersistitUnitTestCase;
2531
26public class WarmupTest extends PersistitUnitTestCase {32public class WarmupTest extends PersistitUnitTestCase {
2733<<<<<<< TREE
34
35=======
36
37 @Override
38 protected Properties getProperties(final boolean cleanup) {
39 final Properties p = super.getProperties(cleanup);
40 p.setProperty("bufferinventory", "true");
41 p.setProperty("bufferpreload", "true");
42 return p;
43 }
44
45>>>>>>> MERGE-SOURCE
28 @Test46 @Test
29 public void testWarmup() throws Exception {47 public void testWarmup() throws Exception {
30 Exchange ex = _persistit.getExchange("persistit", "WarmupTest", true);48 Exchange ex = _persistit.getExchange("persistit", "WarmupTest", true);
49 BufferPool pool = ex.getBufferPool();
31 for (int i = 1; i <= 1000; i++) {50 for (int i = 1; i <= 1000; i++) {
32 ex.getValue().put(RED_FOX);51 ex.getValue().put(RED_FOX);
33 ex.clear().append(i).store();52 ex.clear().append(i).store();
34 }53 }
54<<<<<<< TREE
3555
36 // Assumption: only one buffer pool is created56 // Assumption: only one buffer pool is created
37 int poolCount = 0;57 int poolCount = 0;
@@ -63,5 +83,87 @@
63 }83 }
64 }84 }
65 assertEquals(poolCount, poolCount1);85 assertEquals(poolCount, poolCount1);
86=======
87
88 final Buffer[] buff = new Buffer[100];
89 for (int i = 0; i < pool.getBufferCount(); ++i) {
90 buff[i] = pool.getBufferCopy(i);
91 }
92
93 final Configuration config = _persistit.getConfiguration();
94 ex = null;
95 _persistit.close();
96
97 _persistit = new Persistit();
98 _persistit.initialize(config);
99 ex = _persistit.getExchange("persistit", "WarmupTest", false);
100 pool = ex.getBufferPool();
101
102 for (int i = 0; i < pool.getBufferCount(); ++i) {
103 final Buffer bufferCopy = pool.getBufferCopy(i);
104 assertEquals(bufferCopy.getPageAddress(), buff[i].getPageAddress());
105 assertEquals(bufferCopy.getPageType(), buff[i].getPageType());
106 assertEquals(bufferCopy.getBufferSize(), buff[i].getBufferSize());
107 }
108 }
109
110 @Test
111 public void readOrderIsSequential() throws Exception {
112
113 Exchange ex = _persistit.getExchange("persistit", "WarmupTest", true);
114 BufferPool pool = ex.getBufferPool();
115
116 final int full = pool.getBufferCount() * (pool.getBufferSize() / RED_FOX.length());
117 /*
118 * Overflow the buffer pool
119 */
120 for (int i = 1; i <= full * 3; i++) {
121 ex.getValue().put(RED_FOX);
122 ex.clear().append(i).store();
123 }
124 /*
125 * Pull some low-address pages in to scramble the pool
126 */
127 for (int i = full * 2; i >= 0; i -= 1000) {
128 ex.clear().append(i).fetch();
129 }
130 /*
131 * Verify that buffers in pool now have somewhat scrambled page
132 * addresses
133 */
134 int breaks = 0;
135 long previous = -1;
136
137 for (int i = 0; i < pool.getBufferCount(); i++) {
138 final Buffer b = pool.getBufferCopy(i);
139 assertTrue("Every buffer should be valid at this point", b.isValid());
140 if (b.getPageAddress() < previous) {
141 breaks++;
142 }
143 previous = b.getPageAddress();
144 }
145
146 assertTrue("Buffer pool should have scrambled page address", breaks > 0);
147
148 final Configuration config = _persistit.getConfiguration();
149 ex = null;
150 pool = null;
151 _persistit.copyBackPages();
152 _persistit.close();
153
154 _persistit = new Persistit();
155 config.setBufferInventoryEnabled(false);
156 config.setBufferPreloadEnabled(false);
157 _persistit.initialize(config);
158
159 final Volume volume = _persistit.getVolume("persistit");
160 final MediatedFileChannel mfc = (MediatedFileChannel) volume.getStorage().getChannel();
161 final TrackingFileChannel tfc = new TrackingFileChannel();
162 mfc.injectChannelForTests(tfc);
163 pool = volume.getStructure().getPool();
164 pool.preloadBufferInventory();
165 assertTrue("Preload should have loaded pages from journal file", tfc.getReadPositionList().size() > 0);
166 tfc.assertOrdered(true, true);
167>>>>>>> MERGE-SOURCE
66 }168 }
67}169}
68170
=== added file 'src/test/java/com/persistit/stress/PreloadMixtureTxn1.java'
--- src/test/java/com/persistit/stress/PreloadMixtureTxn1.java 1970-01-01 00:00:00 +0000
+++ src/test/java/com/persistit/stress/PreloadMixtureTxn1.java 2012-08-27 21:56:20 +0000
@@ -0,0 +1,82 @@
1/**
2 * Copyright © 2012 Akiban Technologies, Inc. All rights reserved.
3 *
4 * This program and the accompanying materials are made available
5 * under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * This program may also be available under different license terms.
10 * For more information, see www.akiban.com or contact licensing@akiban.com.
11 *
12 * Contributors:
13 * Akiban Technologies, Inc.
14 */
15
16package com.persistit.stress;
17
18import com.persistit.Configuration;
19import com.persistit.Persistit;
20import com.persistit.Transaction.CommitPolicy;
21import com.persistit.stress.unit.Stress1;
22import com.persistit.stress.unit.Stress2txn;
23import com.persistit.stress.unit.Stress3;
24import com.persistit.stress.unit.Stress3txn;
25import com.persistit.stress.unit.Stress5;
26import com.persistit.stress.unit.Stress6;
27import com.persistit.stress.unit.Stress8txn;
28
29public class PreloadMixtureTxn1 extends AbstractSuite {
30 private final static int CYCLES = 4;
31
32 static String name() {
33 return PreloadMixtureTxn1.class.getSimpleName();
34 }
35
36 public static void main(final String[] args) throws Exception {
37 new PreloadMixtureTxn1(args).runTest();
38 }
39
40 public PreloadMixtureTxn1(final String[] args) {
41 super(name(), args);
42 setDuration(getDuration() / CYCLES);
43 }
44
45 @Override
46 public void runTest() throws Exception {
47
48 deleteFiles(substitute("$datapath$/persistit*"));
49
50 for (int iteration = 0; iteration < CYCLES; iteration++) {
51 clear();
52 add(new Stress1("repeat=10 count=25000"));
53 add(new Stress1("repeat=10 count=25000"));
54 add(new Stress2txn("repeat=10 count=2500 size=4000 seed=118"));
55 add(new Stress2txn("repeat=2 count=25000 seed=119"));
56 add(new Stress3("repeat=5 count=25000 seed=119"));
57 add(new Stress3txn("repeat=5 count=25000 seed=120"));
58 add(new Stress3txn("repeat=5 count=25000"));
59 add(new Stress5("repeat=5 count=25000"));
60 add(new Stress6("repeat=5 count=1000 size=250"));
61 add(new Stress6("repeat=10 count=1000 size=250"));
62 add(new Stress8txn("repeat=2 count=1000 size=1000 seed=1"));
63 add(new Stress8txn("repeat=2 count=1000 size=1000 seed=2"));
64 add(new Stress8txn("repeat=2 count=1000 size=1000 seed=3"));
65 add(new Stress8txn("repeat=2 count=1000 size=1000 seed=4"));
66
67 final Configuration configuration = makeConfiguration(16384, "25000", CommitPolicy.SOFT);
68 configuration.setLogFile(configuration.getLogFile() + "_" + iteration);
69 configuration.setBufferInventoryEnabled(true);
70 configuration.setBufferPreloadEnabled(true);
71
72 final Persistit persistit = new Persistit();
73 persistit.initialize(configuration);
74
75 try {
76 execute(persistit);
77 } finally {
78 persistit.close();
79 }
80 }
81 }
82}
083
=== modified file 'src/test/java/com/persistit/unit/PersistitUnitTestCase.java'
--- src/test/java/com/persistit/unit/PersistitUnitTestCase.java 2012-08-15 16:11:36 +0000
+++ src/test/java/com/persistit/unit/PersistitUnitTestCase.java 2012-08-27 21:56:20 +0000
@@ -47,7 +47,8 @@
47 protected Persistit _persistit = new Persistit();47 protected Persistit _persistit = new Persistit();
4848
49 protected Properties getProperties(final boolean cleanup) {49 protected Properties getProperties(final boolean cleanup) {
50 return UnitTestProperties.getProperties(cleanup);50 final Properties p = UnitTestProperties.getProperties(cleanup);
51 return p;
51 }52 }
5253
53 @Before54 @Before
5455
=== modified file 'src/test/java/com/persistit/unit/UnitTestProperties.java'
--- src/test/java/com/persistit/unit/UnitTestProperties.java 2012-08-07 21:11:28 +0000
+++ src/test/java/com/persistit/unit/UnitTestProperties.java 2012-08-27 21:56:20 +0000
@@ -43,7 +43,6 @@
43 p.setProperty("tmpvoldir", "${datapath}");43 p.setProperty("tmpvoldir", "${datapath}");
44 p.setProperty("rmiport", System.getProperty("rmiport", "8081"));44 p.setProperty("rmiport", System.getProperty("rmiport", "8081"));
45 p.setProperty("jmx", "true");45 p.setProperty("jmx", "true");
46 p.setProperty("bufferinventory", "/tmp/persistit_test_data");
47 return p;46 return p;
48 }47 }
4948

Subscribers

People subscribed via source and target branches