1055557 : 3.3.0

`Trees removed inside transaction can automatically come back`

Resolved by support for creating and removing trees within transactions.

1174352 : 3.3.0

`Transaction commit and abort cannot be performed from a different Thread`

A ReentrantLock was replaced by a Semaphore to allow modification of locked 
state by different threads.

1167056 : 3.3.0

`Value returned from Accumulator#update() is non-transactional`

The issue was unintended use of a value returned from this method. The Accumulator 
API was reworked to avoid confusion.

1161062 : 3.3.0

`Missing public constructor for com.persistit.SessionId`

Added.

1159313 : 3.3.0

`Deadlock in Bug882219Test`

We determined that a deadlock exists in the Java 7 implementation of
AbstractInterruptibleChannel independent of Persistit. Bug number 9002674 was 
assigned by the Oracle Java Bug Database. In the meantime, the test has been
disabled to avoid hung builds.

1157809 : 3.3.0

`Appending value to a Key causes an ArrayIndexOutOfBoundsException`

An attempt to append overflow the backing store of a ``com.persistit.Key`` now
throws a ``com.persistit.exceptions.KeyTooLongException``.

1133039 : 3.3.0

`Pruning incomplete on simple DUPLICATE_KEY error`

The actual cause of this bug was inadequate pruning velocity when cleaning up transactions 
using the new ``com.persistit.Exchange#lock`` method. Locked elements are now
pruned synchronously to avoid overloading the cleanup manager. 

1126868 : 3.3.0

`Lock table not pruned`

See 1133039 above.

1126297 : 3.3.0

'Assertion failure in TransactionIndexBucket#allocateTransactionStatus'

Corrected by allowing a different thread than the one that created it to
abort a transaction.


1076517 : 3.2.2

`InUseExceptions in stress tests`

Stress tests occasionally experienced InUseExceptions, usually signifying
a deadlock. Two mechanisms were discovered and fixed. Note that an InUseException
occurs when an attempt to lock a resource such as a Tree or a Buffer is
unsatisfied for 60 seconds (the current default timeout).  This exception can
occur for reasons other than deadlock such as an extraordinarily slow I/O 
operation or as a result of a debug breakpoint in sensitive code.

1079288 : 3.2.2

`Persistit build success is sensitive to locale`

One Persistit unit test depended on locale-specific text formatting, and therefore
failed when built in a locale which does not conform to en_US formatting rules. 

1079406 : 3.2.2

`Design flaw makes Persistit needlessly difficult to use in Spring Framework`

Persistit initialization API was modified to make it easy to create and use
a Persistit instance within Spring Framework.

1081659 : 3.2.2

`isNull(true) leaves Value in unsafe state for stream mode get`

The implementation of isNull(boolean) added in Version 3.2.1 contained a bug that
made stream-mode get operations fail.

1074372 : 3.2.2

`Stress tests induce RebalanceException`

Code was added to handle a rare situation
in which removing a key at the boundary between two pages requires one of the pages to split. Formerly this condition
was not handled properly and instead caused the application thread to receive a RebalanceException.

1076403 : 3.2.1

`NPE while starting AdminUI`

Localized property files are used for text labels in the AdminUI. Only an
English file was provided by default so starting the UI in another language
would case a NullPointerException. Move the current English property file
to the default name so it is always selected.

1073357 : 3.2.1

`Value.getType() is not reliable for CLASS_REREF`

A special internal tag, CLASS_REFREF, is used when appending the same object 
multiple times to a Value in stream mode. This is so cycles can be handled
correctly in a generic object graph. The getType() method, which returns the
Class of the encoded object without fully decoding it, did not always return
the most specific specific Class for this internal tag.

1046049 : 3.2.1

`Filtered traverse in LTEQ direction appears not to work`

A bug in the com.persistit.KeyFilter caused reverse-direction traversal using
a KeyFilter with a range term to return incorrect results.

1042960 : 3.2.1

`Value.isNull slightly non-intuitive in stream mode`

When operating on a Value in stream mode it is a common pattern to check if the
current position is null before attempting to decode it. There is little reason
to then decode if it is null. A new method was added, isNull(boolean skipIfNull),
that can be used to perform this in a single call.

1023549 : 3.2.1

`traverse(EQ, false, 0) returns incorrect result`

A traverse with the given parameters should return true if the key exists, without
fetching any of the value bytes. If the given key was removed and then immediately
traversed for existence, true would be returned instead of false.

1065677 : 3.2.0

`Persistit not recoverable after hard crash`

A system experienced a sequence of events, including being killed several times at 
inopportune times by the OOM Killer, that left its journal in an unrecoverable state.
Specifically, there was a journal file that contained lots of updated pages, but no
checkpoint record.  Due to a bug in the RecoveryManager code, the system timestamp
was set incorrectly and led to an out-of-order page update sequence.  While this bug
would be difficult to recreate by any natural circumstances, it is critical because
of potential data loss.

1064565 : 3.2.0

`Accumulator state sometimes missing from checkpoint`

Occasionally the state of an Accumulator was incorrect after normal system restart.
The cause was a race in the checkpoint code. This is a critical bug due to potential
data loss.

1062315 : 3.2.0

`Assertion failure in TransactionIndexBucket#allocateTransactionStatus`

An assert was observed in an 8-hour stress test run.  The underlying cause was
a brief race condition and was harmless. The race has been fixed. 

1058650 : 3.2.0

`IllegalStateException due to out-of-order MVVs`

Stress tests experienced an occasional occurrence of an IllegalStateException due
to out-of-order versions in an MVV value.  The condition was transient and did not
cause data loss. The underlying cause has been fixed.

1058254 : 3.2.0

`Join on range delete can change successor keys`

A range delete that crosses at least two page boundaries can write an incorrect key 
when merging records; this causes it and subsequent keys within the page to be wrong 
and also leads to a discontinuity between the max key in the page and the first key 
of its right sibling.

1056489 : 3.2.0

`MVV and step visibility and pruning errors`

Transactions using +step+ values (see com.persisit.Transaction#setStep) sometimes resulted
in inconsistent states.

1053680 : 3.2.0

`Page deallocation can permanently lose pages`

When removing records causes deallocation of chain of pages configured in a particular way, 
a garbage page, and possibly many pages linked to it, may be stranded in a volume. 
The result is irrecoverable loss of space in the volume file.

1047973 : 3.2.0

`O(N*N) Loop in JournalManager#cleanupPageList`

Bad code in this method causes periodic performance degradation in 4-hour TPCC test. The 
CPU cost of this algorithm scales as the square of the number of pages in the page list, 
and the work is done within a globally blocking synchronized block.

1045971 : 3.2.0

`Dynamically loaded volumes not recovered "cleanly"`

When a program creates new volumes using VolumeSpecifications, they subsequently 
cause a "missing volume" warning from the journal copier and prevent the removal 
of journal files containing the references. The journal files accumulate seemingly 
without end, and each initialization of the database seems to process more and 
more of the old transactions.

See discussion about regarding the useOldVSpec property.

1044513 : 3.1.7

`AssertionError in IntegrityCheckTest`

A bug in unit test code caused spurious assertion errors.

1044397 : 3.1.7

`IntegrityCheck throws ArrayIndexOutOfBoundsException`

IntegrityCheck and the CLI ``pview`` command were not immune to
certain inconsistent byte patterns in a corrupt page, making them
inadequate for diagnosing a severely corrupted database.

1041293 : 3.1.7

`Mismatched buffer pool sizes and volume page size results in NPE`

Attempting to open a Volume with a valid page size S resulted in a
NullPointerException if there was no buffer pool having page size
S specified. This same condition how throws an IllegalStateException.

1043536 : 3.1.7

`Build fails: persistit-coverage hangs with deadlock`

A bug in a unit test left a deadlock condition under certain race
conditions. Speed variations caused by clover instrumentation
triggered frequent occurrences.

1036422 : 3.1.6

`CommitPolicy HARD can soak CPU`

With CommitPolicy HARD we observed a CPU-soaking loop in the commit
logic.

1032701 : 3.1.5

`Interrupt causes Thread to exit without releasing claims`

If a thread was interrupted at an inopportune time (for example,
by query cancellation in Akiban Server), a page in the buffer pool
could be left in a locked state blocking all further progress. The
only remedy was to stop and restart the JVM.

1028016 : 3.1.4

`Old Journal Files Not Being Deleted`

If a volume was removed from the configuration and Persistit was
then restarted, the associated journal files would not be removed
due to internal safety checks. To support intentional removal of a
volume, a new configuration option was added.

See the ``Detecting and Ignoring Missing Volumes`` feature description
for more details.


1024857,1026207 : 3.1.4

`Class Index Updates Causing Write-Write Dependencies`

Custom classes that are serialized into keys or values through a
custom KeyCoder or ValueCoder are given a unique identifier.  The
identifier was determined within an application transaction the
first time a class was written and stored in an internal tree.  This
would cause seemingly spurious aborts if multiple application threads
simultaneously attempted to store the first instance of a given
class. The identifier is now committed within an independent
transaction.

1028050,1028134 : 3.1.4

`Accumulator Memory Usage and Transaction Step Policy`

Each individual change to an Accumulator was previously stored as
an individual Delta object. For long running transactions that
heavily utilized Accumulators, this would cause excessive memory
usage. These unique instances are now eliminated in most scenarios,
resulting in stable memory utilization in all but pathological
cases.

Additionally, the Accumulator handling of the Transaction step value
was inconsistent with how it was treated through an Exchange.  Now,
both classes allow a transaction at a given step N to see any update
created by that transaction at a step less N.


1005206 : 3.1.2

`Infinite Loop When Repacking Buffer`

This could occur if a buffer required restructuring during pruning
of a long value that was previously stored under a transaction.
Upon the next save of this buffer to disk (e.g.  shutdown), an
infinite loop would occur.


1010079 : 3.1.2

`Corruption Exceptions During Various Operations`

NOTE: Only the message indicates a database corruption. The data
volume is actually correct and intact.

This could occur if pruning a buffer containing a long record
previously stored under a transaction required removal of keys and
then that buffer was reused without further modification. A parallel
structure associated with the every Buffer, the FastIndex, was not
maintained during this operation.

1012856 : 3.1.2

`Slow Accumulator Operations`

If a thread starting a new transaction was interrupted during the
call to begin(), there was a chance for an internal object to wind
up in an invalid state. This invalid state caused no visible
consequences other than slower than expected Accumulator actions
if this had occurred many times.


1017957 : 3.1.2

`B+Tree Corruption in Stress Test`

An extremely rare combination of events corrupted memory structures
causing an incorrect key-pointer pair to be inserted while deleting
records in a key range. The bug was detected in an 8-hour stress
test run.

1018526 : 3.1.2

`Very long recovery time due to many temporary tree IT records`

Every Tree created in a temporary volume was being assigned a tree
handle recorded permanently in the journal.  In one case the result
was a journal containing millions of IT (Identify Tree) records,
and these caused normal recovery to take a very long time. The fix
keeps temporary trees out of the journal and removes IT records
which may have been added previously.



