Merge lp:~pbeaman/akiban-persistit/release-notes-3.2.7 into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Peter Beaman
Approved revision: 428
Merged at revision: 427
Proposed branch: lp:~pbeaman/akiban-persistit/release-notes-3.2.7
Merge into: lp:akiban-persistit
Diff against target: 978 lines (+224/-167)
15 files modified
doc/GettingStarted.rst (+4/-2)
doc/Management.rst (+1/-1)
doc/ReleaseNotes.rst (+77/-23)
doc/build/src/AsciiDocIndex.java (+68/-70)
doc/build/src/AsciiDocPrep.java (+12/-16)
doc/build/src/SphinxDocPrep.java (+24/-18)
doc/conf.py (+2/-2)
src/main/java/com/persistit/Exchange.java (+5/-5)
src/main/java/com/persistit/Key.java (+1/-1)
src/main/java/com/persistit/Management.java (+1/-3)
src/main/java/com/persistit/Task.java (+3/-3)
src/main/java/com/persistit/Value.java (+2/-2)
src/main/java/com/persistit/mxbeans/ManagementMXBean.java (+1/-1)
src/main/java/com/persistit/mxbeans/TransactionIndexMXBean.java (+7/-7)
src/main/javadoc/overview.html (+16/-13)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/release-notes-3.2.7
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Approve
Review via email: mp+155117@code.launchpad.net

Description of the change

Release note and documentation upgrade.

I found numerous problems in the documentation, including mismatched tags in Javadoc comments and problems in the .rst files. I also found that the document preparation tools (SphinxDocPrep and AsciiDocIndex) were (a) always broken, and (b) even more broken when applied to the output of Java 7's version of Javadoc. I fixed those programs up just enough to make credible looking output (e.g., correctly linking method names to Javadoc.)

One change I made in the documentation format is to remove the arguments from method names in the documents. So, for example instead of something like "the append(boolean) method appends primitives and object values (sort of)" the generated document now reads "the append method appends primitives...". I think this is preferable.

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

I didn't look at the doc helper code changes too closely, but everything else looks good.

review: Approve
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 562: http://172.16.20.104:8080/job/persistit-build/562/

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

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

Trying this again. Not sure why the plugin was unavailable this time.

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

Failed again, this time due to bug1159313. Will diagnose that tomorrow.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/GettingStarted.rst'
2--- doc/GettingStarted.rst 2012-11-30 22:56:42 +0000
3+++ doc/GettingStarted.rst 2013-03-23 22:07:26 +0000
4@@ -125,7 +125,7 @@
5 Initialization and Configuration
6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7
8-Before accessing any data, ``HelloWorld.java`` calls the ``com.persistit.Persistit#initialize()``. This sets up the memory configuration for buffers and the path names of Persistit volume and journal files. Alternative methods accept configuration information from a ``com.persistit.Configuration`` object, a ``java.util.Properties`` object, a specified properties file, or by default from the file named ``persistit.properties`` in the current working directory.
9+Before accessing any data, ``HelloWorld.java`` calls the ``com.persistit.Persistit#initialize()`` method. This sets up the memory configuration for buffers and the path names of Persistit volume and journal files. Alternative methods accept configuration information from a ``com.persistit.Configuration`` object, a ``java.util.Properties`` object, a specified properties file, or by default from the file named ``persistit.properties`` in the current working directory.
10
11 In this example, ``persistit.properties`` looks like this::
12
13@@ -246,7 +246,9 @@
14 KeyFilters
15 ^^^^^^^^^^
16
17-A ``com.persistit.KeyFilter`` can be supplied to restrict the results traversal operation in a convenient and
18+A ``com.persistit.KeyFilter`` can be supplied to restrict the results returned by the ``com.persistit.Exchange#traverse`` methods. You can specify discrete values or ranges for values of individual key segments and apply other simple predicates.
19+
20+See :ref:`Basic-API`.
21
22 Transactions
23 ^^^^^^^^^^^^
24
25=== modified file 'doc/Management.rst'
26--- doc/Management.rst 2012-06-11 21:25:37 +0000
27+++ doc/Management.rst 2013-03-23 22:07:26 +0000
28@@ -93,7 +93,7 @@
29 Executing a Task from a JMX Client
30 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31
32-The ``com.persistit.mxbeans.ManagementMXBean#execute`` and ``com.persistit.mxbeans.ManagementMXBean#launch`` methods are exposed as operations on the ``com.persistit.mxbeans.ManagementMXBean``. You can invoke tasks
33+The ``com.persistit.mxbeans.ManagementMXBean#execute`` and ``com.persistit.mxbeans.ManagementMXBean#launch`` methods are exposed as operations on the ``com.persistit.mxbeans.ManagementMXBean`` object. You can invoke tasks
34
35 - via ``jconsole`` by typing the desired command line as the argument of the ``execute`` operation.
36 - via a third-party JMX client such as ``jmxterm``.
37
38=== modified file 'doc/ReleaseNotes.rst'
39--- doc/ReleaseNotes.rst 2012-11-30 22:56:42 +0000
40+++ doc/ReleaseNotes.rst 2013-03-23 22:07:26 +0000
41@@ -1,16 +1,16 @@
42 ************************************
43-Akiban Persistit Version 3.2.2
44+Akiban Persistit Version 3.2.7
45 ************************************
46
47 Overview
48 ========
49-See http://www.akiban.com/akiban-persistit for a summary of features and benefits, licensing information and how to get support.
50+See http://akiban.github.com/persistit for a summary of features and benefits, licensing information and how to get support.
51
52 Documentation
53 =============
54-Users Guide: http://www.akiban.com/ak-docs/admin/persistit
55+Users Guide: http://akiban.github.com/persistit/docs
56
57-JavaDoc: http://www.akiban.com/sites/all/libraries/persistit-api/index.html
58+JavaDoc: http://akiban.github.com/persistit/javadoc/index.html
59
60 Building Akiban-Persistit
61 =========================
62@@ -29,15 +29,23 @@
63 Building and Running the Examples
64 ---------------------------------
65
66-Small examples are located in the ``examples`` directory. Each has a short README file describing the example, and an Ant build script (http://ant.apache.org). After building the main akiban-persisit jar file using Maven, you may run::
67+Small examples are located in the ``examples`` directory. Each has a short README file describing the
68+example, and an Ant build script (http://ant.apache.org). After building the main akiban-persisit jar file using Maven, you may run::
69
70 ant run
71
72 in each of the examples subdirectories to build and run the examples.
73
74+Java 7 versus Java 6
75+--------------------
76+Persistit compiles and runs successfully under either Java 6 or Java 7. However, when compiled with Java 7, the resulting classes are
77+incompatible with Java 6 due to a change in the ``java.nio.channels.FileChannel`` class introduced in Java 7.
78+See `FileChannel incompatibility introduced between 6 and 7 <http://mail.openjdk.java.net/pipermail/nio-dev/2012-July/001788.html>`_. Classes
79+compiled under Java 6 run correctly in Java 7.
80+
81 Buffer Pool Configuration
82 =========================
83-For optimal performance, proper configuration of the Persistit buffer pool is required. See section "Configuring the Buffer Pool" in the configuration document http://www.akiban.com/ak-docs/admin/persistit/Configuration.html
84+For optimal performance, proper configuration of the Persistit buffer pool is required. See section "Configuring the Buffer Pool" in the configuration document http://akiban.github.com/persistit/docs/Configuration.html
85
86 .. note:: Especially when used with multi-gigabyte heaps, the default Hotspot JVM server heuristics are be suboptimal for Persistit applications. Persistit is usually configured to allocate a large fraction of the heap to Buffer instances that are allocated at startup and held for the duration of the Persistit instance. For efficient operation, all of the Buffer instances must fit in the tenured (old) generation of the heap to avoid very significant garbage collector overhead. Use either -XX:NewSize or -Xmn to adjust the relative sizes of the new and old generations.
87
88@@ -50,6 +58,9 @@
89 +---------+--------------------+--------------------------------------------------------------------------+
90 | Version | Release Date | Summary |
91 +=========+====================+==========================================================================+
92+| 3.2.7 | March 22, 2013 | Several new API features, including TreeBuilder, Traverse Visitor, |
93+| | | and Lock. Fix several non-critical bugs. |
94++---------+--------------------+--------------------------------------------------------------------------+
95 | 3.2.2 | November 30, 2012 | Better support for Spring Framework. Fix rare but serious bugs found in |
96 | | | stress tests. Fix issue related to locale and make sure Persistit builds |
97 | | | everywhere. |
98@@ -83,6 +94,65 @@
99 Changes and New Features
100 ========================
101
102+Persistit 3.2.7 - TreeBuilder
103+-----------------------------------------------------
104+Inserting a large set of records with non-sequential keys causes significant I/O overhead. Once the size
105+of the Tree is larger than available main memory, each insertion can result in a disk write (to flush a page
106+to disk so that its buffer can be reused) and a disk read (to read a different page into the buffer).
107+
108+The ``com.persistit.TreeBuilder`` class provides a more efficient way to load a large set of records with
109+non-sequential keys. TreeBuilder creates a set of files containing partially-sorted records. From these,
110+TreeBuilder performs a merge-sort to complete the operation.
111+
112+TreeBuilder is effective only for inserting large sets of non-sequential records. For example, in tests we have
113+loaded a billion records with keys generated as UUID instances. See the API documentation for
114+``com.persistit.TreeBuilder`` for more information.
115+
116+Persistit 3.2.7 - Traverse Visitor
117+-----------------------------------------------------
118+The ``com.persistit.Exchange#traverse`` methods provide Persistit's fundamental mechanism for iterating
119+over a collection of keys within a Tree. Each call to ``traverse`` (or ``com.persistit.Exchange#next`` or
120+``com.persistit.Exchange#previous``) performs a significant amount of set-up and tear-down activity.
121+
122+To better support code that visits a large number of records by calling one of the ``traverse`` methods in a loop, this
123+release adds a more efficient mechanism based on the visitor pattern. See ``com.persistit.Exchange.TraverseVisitor``
124+for details.
125+
126+Persistit 3.2.7 - Lock to avoid Write Skew Anomalies
127+-----------------------------------------------------
128+Persistit transactions implement Snapshot Isolation to prevent concurrent transactions from interfering with
129+each other. See ``com.persistit.Transaction`` for details.
130+
131+Snapshot Isolation is a well-known protocol for multi-version concurrency control. It is employed by many
132+commercial databases because it offers lock-free serializable read transactions and frequently permits very high
133+throughput for concurrent execution of update transactions. And for many (but not all) transactions
134+it offers fully serializable execution of concurrent transactions (meaning that the effect of executing
135+a set of transactions concurrently is identical to running them serially in some order).
136+
137+The non-serializable exception case is called "Write Skew." See the `Wikipedia <http://wikipedia.org/wiki/Snapshot_isolation>`_
138+article for a brief description of write skew.
139+
140+In Persistit the issue arises when two (or more) concurrent transactions modify records with different keys
141+in such a way that an integrity constraint which each transaction running alone would enforce is violated.
142+For example, two concurrent transactions may write to separate data items X and Y in a way that
143+violates an invariant that neither transaction alone would have permitted. Because the write operations
144+are to different keys, no write conflict is detected, and both transactions are permitted to commit. The
145+result is a database state that could not have occurred if the transactions had run sequentially in any order.
146+
147+A well-known solution is to modify the transaction logic to perform an additional write operation to a common
148+key. The ``com.persistit.Exchange#lock`` method provides a convenient and efficient mechanism for doing so. The``lock``
149+method does not actually lock anything, but is so-named because it serves a similar function.
150+
151+Persistit 3.2.7 - Miscellaneous Issues
152+-----------------------------------------------------
153+Changes needed to build and run Persistit on Mac OSX under Java 7 were made.
154+
155+A new CLI command to display the contents of a Persistit volume file was added. The command
156+
157+ volumeinfo file=/path/to/volume/file
158+
159+displays all of the meta data contained in the volume file.
160+
161 Persistit 3.2.2 - Spring Framework
162 -----------------------------------------------------
163 Prior to this release Persistit was needlessly difficult to configure and initialize within Spring Framework.
164@@ -238,7 +308,7 @@
165
166 https://bugs.launchpad.net/akiban-persistit/+bug/985117
167
168-Out of Memory Error, Direct Memory Buffer. Can cause failed transactions under extreme load
169+Out of Memory Error, Direct Memory Buffer. Can cause failed transactions under extreme load
170 conditions as a result of threads getting backed up writing to the journal file. However,
171 this error is transient and recoverable by by retrying the failed transaction.
172
173@@ -253,19 +323,3 @@
174 The primary consumer is the PersistitMap. As a result of this bug Persistit may not generate
175 java.util.ConcurrentModificationException when it is supposed to.
176
177-Multi-Version-Values sometimes not fully pruned
178--------------------------------------------------------------
179-
180-https://bugs.launchpad.net/akiban-persistit/+bug/1000331
181-
182-Multi-version values are not always pruned properly causing volume growth. The number of
183-MVV records and their overhead size can be obtaining by running the IntegrityCheck task.
184-
185-* Workaround 1: Run the IntegrityCheck task (CLI command icheck) with the -P option which will prune the MVVs. This will remove obsolete MVV instances and in many cases free up pages in which new data can be stored. However, it will not reduce the actual size of the volume file.
186-
187-* Workaround 2: To reduce the size of the volume you can use the CLI commands ``save`` and ``load`` to reload the data into a newly created volume file. See http://www.akiban.com/ak-docs/admin/persistit/Management.html#management for more information about these operations.
188-
189-Note: although the methods described here may be helpful in reducing MVV clutter, Persistit Version 3.2.0 significantly improves the algorithms used to prune obsolete versions and the
190-techniques described here are unlikely to be necessary.
191-
192-
193
194=== modified file 'doc/build/src/AsciiDocIndex.java'
195--- doc/build/src/AsciiDocIndex.java 2012-08-02 04:45:28 +0000
196+++ doc/build/src/AsciiDocIndex.java 2013-03-23 22:07:26 +0000
197@@ -29,9 +29,8 @@
198 import com.persistit.exception.PersistitException;
199
200 public class AsciiDocIndex {
201- private final static String NOISY_STRINGS[] = { "\r", "\n", "<B>", "</B>",
202- "<b>", "</b>", "<CODE>", "</CODE>", "<code>", "</code>", "<TT>",
203- "</TT>", "<tt>", "</tt>", "<FONT>", "</FONT>", "<font>", "</font>" };
204+ private final static String NOISY_STRINGS[] = { "\r", "\n", "<B>", "</B>", "<b>", "</b>", "<CODE>", "</CODE>",
205+ "<code>", "</code>", "<TT>", "</TT>", "<tt>", "</tt>", "<FONT>", "</FONT>", "<font>", "</font>" };
206
207 // Charset and decoder for ISO-8859-15
208 private final static Charset charset = Charset.forName("ISO-8859-15");
209@@ -41,8 +40,8 @@
210 // Regex Pattern to pull various attributes and fields out of the anchor
211 // tags in Javadoc index-NN.html files.
212 //
213- private final static Pattern PATTERN = Pattern
214- .compile(".*(<A HREF=\"(.*?)\"( *title=\"(.*?)\")?.*?>(.*)</A>)");
215+ private final static Pattern PATTERN = Pattern.compile(
216+ "(<a href=\"(\\./com/persistit.*?)\" *(title=\"(.*?)\")?.*?>(.*?)</a>)", Pattern.CASE_INSENSITIVE);
217
218 private int _count;
219
220@@ -63,17 +62,16 @@
221 *
222 * @throws PersistitException
223 */
224- public int buildIndex(String pathName, String base) throws IOException {
225+ public int buildIndex(final String pathName, String base) throws IOException {
226 File file = new File(pathName);
227
228 // The index generated by the standard Javadoc Doclet is either
229 // at the root of the api tree, in a file called index-all.html, or
230 // in a subdirectory called index-files. This code tries each case.
231 //
232- if (file.exists() && file.isDirectory()
233- && !file.getPath().endsWith("index-files")) {
234- File indexAll = new File(file, "index-all.html");
235- File indexDir = new File(file, "index-files");
236+ if (file.exists() && file.isDirectory() && !file.getPath().endsWith("index-files")) {
237+ final File indexAll = new File(file, "index-all.html");
238+ final File indexDir = new File(file, "index-files");
239 if (indexAll.exists() && !indexAll.isDirectory()) {
240 file = indexAll;
241 } else if (indexDir.exists() && indexDir.isDirectory()) {
242@@ -90,109 +88,110 @@
243 indexOneFile(file, base);
244 }
245 } else {
246- throw new IllegalArgumentException(
247- "Requires the name of a Javadoc API index file, "
248- + "or of a directory containing Javadoc API index files.");
249+ throw new IllegalArgumentException("Requires the name of a Javadoc API index file, "
250+ + "or of a directory containing Javadoc API index files.");
251 }
252 return _count;
253 }
254
255- public void indexOneDirectory(File indexDir, String base)
256- throws IOException {
257- File[] indexFiles = indexDir.listFiles();
258+ public void indexOneDirectory(final File indexDir, final String base) throws IOException {
259+ final File[] indexFiles = indexDir.listFiles();
260 for (int i = 0; i < indexFiles.length; i++) {
261 indexOneFile(indexFiles[i], base);
262 }
263 }
264
265- public void indexOneFile(File file, String base) throws IOException {
266+ public void indexOneFile(final File file, final String base) throws IOException {
267+ FileChannel fc = null;
268 try {
269 System.out.println("Indexing " + file);
270
271- FileChannel fc = new FileInputStream(file).getChannel();
272+ fc = new FileInputStream(file).getChannel();
273
274- MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
275- fc.size());
276- CharBuffer cb = decoder.decode(bb);
277- Matcher matcher = PATTERN.matcher(cb);
278+ final MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
279+ final CharBuffer cb = decoder.decode(bb);
280+ final Matcher matcher = PATTERN.matcher(cb);
281
282 while (matcher.find()) {
283- String wholeTag = matcher.group(1);
284- String href = matcher.group(2);
285- String url = base + "/" + fixDotSlash(href);
286- String title = matcher.group(4);
287- String text = matcher.group(5);
288+ final String wholeTag = matcher.group(1);
289+ final String href = matcher.group(2);
290+ final String url = base + "/" + fixDotSlash(href);
291+ final String title = matcher.group(4);
292+ final String text = matcher.group(5);
293
294 indexOneTerm(wholeTag, href, url, title, text);
295
296 }
297- fc.close();
298- } catch (IOException e) {
299+ } catch (final IOException e) {
300 System.err.println();
301 e.printStackTrace();
302 throw e;
303+ } finally {
304+ if (fc != null) {
305+ fc.close();
306+ }
307 }
308 }
309
310- private void indexOneTerm(String wholeTag, String href, String url,
311- String title, String text) {
312+ private void indexOneTerm(final String wholeTag, String href, final String url, final String title, String text) {
313+
314 text = cleanupNoise(text);
315 href = fixDotSlash(href);
316
317- int pHtml = href.lastIndexOf(".html");
318+ final int pHtml = href.lastIndexOf(".html");
319+ if (pHtml == -1) {
320+ return;
321+ }
322
323- int pPackageSummary = href.indexOf("/package-summary");
324+ final int pPackageSummary = href.indexOf("/package-summary");
325 if (pPackageSummary > 0) {
326 //
327 // Enumerate the package name segments
328 // The HREF starts with "./", which is chopped off here.
329 //
330- String packageName = href.substring(0, pPackageSummary).replace(
331- '/', '.');
332+ final String packageName = href.substring(0, pPackageSummary).replace('/', '.');
333
334 int q = -1;
335 while (q < packageName.length()) {
336- int p = q + 1;
337+ final int p = q + 1;
338 q = packageName.indexOf('.', p);
339 if (q < 0)
340 q = packageName.length();
341- String term = packageName.substring(p, q);
342- writeTermToPersistit("Package", term, url, packageName);
343+ final String term = packageName.substring(p, q);
344+ saveTerm("Package", term, url);
345 }
346 return;
347 }
348
349- if (href.startsWith("com/") || href.startsWith("java/")
350- || href.startsWith("javax/") || href.startsWith("org/")
351+ if (href.startsWith("com/") || href.startsWith("java/") || href.startsWith("javax/") || href.startsWith("org/")
352 || href.startsWith("COM/") || href.startsWith("ORG/")) {
353- int pHash = href.indexOf('#');
354+ final int pHash = href.indexOf('#');
355 if (pHash == -1) {
356 // This is a class or interface name
357 String category = "Class";
358 if (title.startsWith("interface"))
359 category = "Interface";
360- int pSlash = href.lastIndexOf('/', pHtml - 1);
361+ final int pSlash = href.lastIndexOf('/', pHtml - 1);
362 // String className = href.substring(pSlash + 1, pHtml);
363- String className = href.substring(0, pHtml).replace('/', '.');
364- writeTermToPersistit(category, className, url, text);
365+ final String className = href.substring(0, pHtml).replace('/', '.');
366+ saveTerm(category, className, url);
367 return;
368 }
369
370 else {
371- String className = href.substring(0, pHtml).replace('/', '.');
372- String name = href.substring(pHash + 1);
373- int pLeftParen = name.indexOf('(');
374+ final String className = href.substring(0, pHtml).replace('/', '.');
375+ final String name = href.substring(pHash + 1);
376+ final int pLeftParen = name.indexOf('(');
377 if (pLeftParen == -1) {
378 //
379 // This is a field or a constant. We'll call it a constant
380 // if
381 // it is spelled in upper case.
382 //
383- String uCaseName = name.toUpperCase();
384- String category = name.equals(uCaseName) ? "Constant"
385- : "Field";
386- String displayText = name + " in " + className;
387- writeTermToPersistit(category, name, url, displayText);
388+ final String uCaseName = name.toUpperCase();
389+ final String category = name.equals(uCaseName) ? "Constant" : "Field";
390+ final String displayText = name + " in " + className;
391+ saveTerm(category, name, url);
392 return;
393 } else {
394 //
395@@ -200,25 +199,22 @@
396 // and then if it conforms to the pattern for property
397 // set/get methods, we'll also index the property name.
398 //
399- int pRightParen = name.indexOf(')', pLeftParen);
400+ final int pRightParen = name.indexOf(')', pLeftParen);
401 if (pRightParen == -1) {
402 System.out.println("Missing right paren");
403 System.out.println(wholeTag);
404 return;
405 }
406- String paramList = name.substring(pLeftParen + 1,
407- pRightParen).trim();
408+ final String paramList = name.substring(pLeftParen + 1, pRightParen).trim();
409 // String term = name.substring(0, pLeftParen);
410- String term = (href.substring(0, pHtml) + href
411- .substring(pHtml + 5)).replace('/', '.');
412- writeTermToPersistit("Method", term, url, name);
413- String displayText = name + " in " + className;
414- if (name.startsWith("get") && paramList.length() == 0
415- || name.startsWith("is") && paramList.length() == 0
416- || name.startsWith("set") && paramList.length() > 0
417+ String term = (href.substring(0, pHtml) + href.substring(pHtml + 5)).replace('/', '.');
418+ saveTerm("Method", term, url);
419+ final String displayText = name + " in " + className;
420+ if (name.startsWith("get") && paramList.length() == 0 || name.startsWith("is")
421+ && paramList.length() == 0 || name.startsWith("set") && paramList.length() > 0
422 && paramList.indexOf(',') == -1) {
423 term = term.substring(name.startsWith("is") ? 2 : 3);
424- writeTermToPersistit("Property", term, url, displayText);
425+ saveTerm("Property", term, url);
426 }
427 return;
428 }
429@@ -226,8 +222,10 @@
430 }
431 }
432
433- private void writeTermToPersistit(final String type, final String term,
434- final String url, final String text) {
435+ private void saveTerm(final String type, final String term, final String url) {
436+ if (term.contains("#end")) {
437+ System.out.println(term);
438+ }
439 if ("Method".equals(type)) {
440 methodMap.put(term, url);
441 }
442@@ -236,18 +234,18 @@
443 }
444 }
445
446- private String fixDotSlash(String url) {
447+ private String fixDotSlash(final String url) {
448 if (url.startsWith("./"))
449 return url.substring(2);
450 else
451 return url;
452 }
453
454- private String cleanupNoise(String term) {
455+ private String cleanupNoise(final String term) {
456 boolean changed = false;
457- StringBuffer sb = new StringBuffer(term);
458+ final StringBuffer sb = new StringBuffer(term);
459 for (int i = 0; i < NOISY_STRINGS.length; i++) {
460- String tag = NOISY_STRINGS[i];
461+ final String tag = NOISY_STRINGS[i];
462 for (int p; (p = sb.indexOf(tag)) >= 0;) {
463 sb.delete(p, p + tag.length());
464 changed = true;
465@@ -257,7 +255,7 @@
466 }
467
468 public void index(final String javaDocPathname) throws Exception {
469- String base = "http://www.akiban.com/documentation/apidocs";
470+ final String base = "http://www.akiban.com/documentation/apidocs";
471 buildIndex(javaDocPathname, base);
472 }
473
474
475=== modified file 'doc/build/src/AsciiDocPrep.java'
476--- doc/build/src/AsciiDocPrep.java 2012-05-04 02:05:33 +0000
477+++ doc/build/src/AsciiDocPrep.java 2013-03-23 22:07:26 +0000
478@@ -14,10 +14,8 @@
479 private final static Pattern PERSISTIT_PATTERN = Pattern
480 .compile("(\\+)?(com\\.persistit(?:\\.[a-z]\\w?)*(?:\\.[A-Z]\\w*)+)(?:#(\\w+(?:[\\(\\)\\,a-zA-Z]*)))?(\\+)?");
481
482- private final static String[] ARG_TEMPLATE = { "in|string:|Input file",
483- "out|string:|Output file",
484- "index|string:|Pathname of index-all.html file",
485- "base|string:|Base of generated URLs", };
486+ private final static String[] ARG_TEMPLATE = { "in|string:|Input file", "out|string:|Output file",
487+ "index|string:|Pathname of index-all.html file", "base|string:|Base of generated URLs", };
488
489 private AsciiDocIndex index;
490 private boolean block;
491@@ -26,12 +24,11 @@
492 private String indexPath;
493
494 private void prepare(final String[] args) throws Exception {
495- ArgParser ap = new ArgParser("AsciiDocPrep", args, ARG_TEMPLATE);
496+ final ArgParser ap = new ArgParser("AsciiDocPrep", args, ARG_TEMPLATE);
497 final String inPath = ap.getStringValue("in");
498 final String outPath = ap.getStringValue("out");
499
500- writer = outPath.isEmpty() ? new PrintWriter(System.out)
501- : new PrintWriter(new FileWriter(outPath));
502+ writer = outPath.isEmpty() ? new PrintWriter(System.out) : new PrintWriter(new FileWriter(outPath));
503
504 base = ap.getStringValue("base");
505 if (base.isEmpty()) {
506@@ -51,9 +48,8 @@
507 writer.close();
508 }
509
510- public void processFile(final File file, final int level)
511- throws Exception {
512- BufferedReader reader = new BufferedReader(new FileReader(file));
513+ public void processFile(final File file, final int level) throws Exception {
514+ final BufferedReader reader = new BufferedReader(new FileReader(file));
515 System.out.print("Processing file " + file);
516 String line;
517 while ((line = reader.readLine()) != null) {
518@@ -89,10 +85,10 @@
519 }
520
521 private void processMatch(final Matcher matcher, final StringBuffer sb) {
522- String className = matcher.group(2);
523- String methodName = matcher.group(3);
524+ final String className = matcher.group(2);
525+ final String methodName = matcher.group(3);
526
527- StringBuilder replacement = new StringBuilder("+link:");
528+ final StringBuilder replacement = new StringBuilder("+link:");
529 if (methodName == null) {
530 final String url = index.getClassMap().get(className);
531 if (url == null || url.isEmpty()) {
532@@ -100,9 +96,9 @@
533 } else {
534 replacement.append(url);
535 }
536- replacement.append('[' + className +"]+");
537+ replacement.append('[' + className + "]+");
538 } else {
539- String from = className + "#" + methodName.split("\\(")[0];
540+ final String from = className + "#" + methodName.split("\\(")[0];
541 final SortedMap<String, String> map = index.getMethodMap().tailMap(from);
542 if (map.isEmpty()) {
543 replacement.append("<<<Missing method: " + methodName + ">>>");
544@@ -120,7 +116,7 @@
545 text = text.replace("java.lang.", "");
546 text = text.replace("java.util.", "");
547 replacement.append(url);
548- replacement.append('[' + text +"]+");
549+ replacement.append('[' + text + "]+");
550 }
551 }
552
553
554=== modified file 'doc/build/src/SphinxDocPrep.java'
555--- doc/build/src/SphinxDocPrep.java 2012-09-11 21:34:04 +0000
556+++ doc/build/src/SphinxDocPrep.java 2013-03-23 22:07:26 +0000
557@@ -31,7 +31,7 @@
558 private String indexPath;
559
560 private void prepare(final String[] args) throws Exception {
561- ArgParser ap = new ArgParser("SphinxDocPrep", args, ARG_TEMPLATE);
562+ final ArgParser ap = new ArgParser("SphinxDocPrep", args, ARG_TEMPLATE);
563 final String inPath = ap.getStringValue("in");
564 final String outPath = ap.getStringValue("out");
565
566@@ -56,7 +56,7 @@
567 }
568
569 public void processFile(final File file, final int level) throws Exception {
570- BufferedReader reader = new BufferedReader(new FileReader(file));
571+ final BufferedReader reader = new BufferedReader(new FileReader(file));
572 System.out.print("Processing file " + file);
573 String line;
574 while ((line = reader.readLine()) != null) {
575@@ -109,28 +109,34 @@
576 }
577
578 private void processMatch(final Matcher matcher, final StringBuffer sb) {
579- String className = matcher.group(2);
580- String methodName = matcher.group(3);
581+ final String className = matcher.group(2);
582+ final String methodName = matcher.group(3);
583
584 String replacement;
585 if (methodName == null) {
586- String url = index.getClassMap().get(className);
587+ final String url = index.getClassMap().get(className);
588 if (url == null || url.isEmpty()) {
589 replacement = "<<<Missing class: " + className + ">>>";
590 } else {
591 replacement = "`" + className + " <" + url + ">`_";
592 }
593 } else {
594- String from = className + "#" + methodName.split("\\(")[0];
595+ final String from = className + "#" + methodName.split("\\(")[0];
596 final SortedMap<String, String> map = index.getMethodMap().tailMap(from);
597 String url;
598 if (map.isEmpty()) {
599 replacement = "<<<Missing method: " + methodName + ">>>";
600 } else {
601 final String first = map.firstKey();
602+ if (!first.startsWith(from)) {
603+ replacement = "<<<Missing method: " + methodName + ">>>";
604+ }
605 url = map.get(first);
606 url = url.replace(" ", "%20");
607 String text = first.split("#")[1];
608+ if (!from.contains("(")) {
609+ text = text.split("\\(")[0];
610+ }
611 text = text.replace("com.persistit.encoding.", "");
612 text = text.replace("com.persistit.exception.", "");
613 text = text.replace("com.persistit.logging.", "");
614@@ -148,14 +154,14 @@
615 }
616
617 private void prepareBugList() throws IOException {
618- List<String[]> rows = new ArrayList<String[]>();
619+ final List<String[]> rows = new ArrayList<String[]>();
620 rows.add(new String[] { "Bug Reference", "Fixed in|Version", "Summary" });
621 BufferedReader reader = null;
622 try {
623 String urls = "";
624 String version = "";
625 reader = new BufferedReader(new FileReader("../BugList"));
626- StringBuilder sb = new StringBuilder();
627+ final StringBuilder sb = new StringBuilder();
628 String line = null;
629 while ((line = reader.readLine()) != null) {
630 if (line.isEmpty()) {
631@@ -169,7 +175,7 @@
632 version = "";
633 sb.setLength(0);
634 }
635- String[] split = line.split("\\:");
636+ final String[] split = line.split("\\:");
637 for (final String bug : split[0].trim().split(",")) {
638 if (urls.length() > 0) {
639 urls += '|';
640@@ -188,10 +194,10 @@
641 rows.add(new String[] { urls, version, sb.toString() });
642 }
643
644- int[] maxWidth = new int[3];
645+ final int[] maxWidth = new int[3];
646 for (final String[] row : rows) {
647 for (int i = 0; i < 3; i++) {
648- for (String s : row[i].split("\\|")) {
649+ for (final String s : row[i].split("\\|")) {
650 maxWidth[i] = Math.max(s.length(), maxWidth[i]);
651 }
652 }
653@@ -205,7 +211,7 @@
654 }
655 bugTableLine(sb, true, maxWidth);
656 for (int i = 1; i < rows.size(); i++) {
657- String[] text = rows.get(i);
658+ final String[] text = rows.get(i);
659 for (int l = 0;; l++) {
660 if (bugTableText(sb, text, maxWidth, l)) {
661 break;
662@@ -213,7 +219,7 @@
663 }
664 bugTableLine(sb, false, maxWidth);
665 }
666- } catch (IOException e) {
667+ } catch (final IOException e) {
668 System.out.println(e + " while trying to read BugList");
669 } finally {
670 if (reader != null) {
671@@ -222,7 +228,7 @@
672 }
673 }
674
675- private void bugTableLine(StringBuilder sb, boolean dline, int[] width) {
676+ private void bugTableLine(final StringBuilder sb, final boolean dline, final int[] width) {
677 sb.setLength(0);
678 sb.append('+');
679 for (int j = 0; j < 3; j++) {
680@@ -235,11 +241,11 @@
681 writer.flush();
682 }
683
684- private boolean bugTableText(StringBuilder sb, String[] text, int[] width, int line) {
685- String[] s = new String[3];
686+ private boolean bugTableText(final StringBuilder sb, final String[] text, final int[] width, final int line) {
687+ final String[] s = new String[3];
688 boolean done = true;
689 for (int j = 0; j < 3; j++) {
690- String[] split = text[j].split("\\|");
691+ final String[] split = text[j].split("\\|");
692 if (split.length > line) {
693 done = false;
694 s[j] = split[line];
695@@ -266,6 +272,6 @@
696 }
697
698 public static void main(final String[] args) throws Exception {
699- new SphinxDocPrep().prepare(args);
700+ new SphinxDocPrep().prepare(args);
701 }
702 }
703
704=== modified file 'doc/conf.py'
705--- doc/conf.py 2013-01-25 19:06:51 +0000
706+++ doc/conf.py 2013-03-23 22:07:26 +0000
707@@ -42,7 +42,7 @@
708
709 # General information about the project.
710 project = u'Persistit'
711-copyright = u'2012, Akiban Technologies'
712+copyright = u'2013, Akiban Technologies'
713
714 # The version info for the project you're documenting, acts as replacement for
715 # |version| and |release|, also used in various other places throughout the
716@@ -50,7 +50,7 @@
717 #
718 # version = short X.Y version.
719 # release = full version, including alpha/beta/rc tags.
720-version = '3.2.6'
721+version = '3.2.7'
722 release = version
723
724 # Included while processing every rst file. Used only for working around inability
725
726=== modified file 'src/main/java/com/persistit/Exchange.java'
727--- src/main/java/com/persistit/Exchange.java 2013-03-13 17:40:50 +0000
728+++ src/main/java/com/persistit/Exchange.java 2013-03-23 22:07:26 +0000
729@@ -2777,9 +2777,9 @@
730 * <p>
731 * This method is designed to help applications overcome problems with
732 * "write skew" which is a type of isolation anomaly permitted by Snapshot
733- * Isolation. See, for example,
734- * http://en.wikipedia.org/wiki/Snapshot_isolation for a concise explanation
735- * of Snapshot Isolation and the write skew anomaly.
736+ * Isolation. See, for example, http://wikipedia.org/wiki/Snapshot_isolation
737+ * for a concise explanation of Snapshot Isolation and the write skew
738+ * anomaly.
739 * <p>
740 * </p>
741 * To use this facility an application specifies a key which may or may not
742@@ -3340,7 +3340,7 @@
743
744 /**
745 * Removes all records with keys falling between <code>key1</code> and
746- * </code>key2</code>, left-inclusive.
747+ * <code>key2</code>, left-inclusive.
748 *
749 * @param key1
750 * Start of the deletion range. No record with a key smaller than
751@@ -3354,7 +3354,7 @@
752 * will be removed.
753 *
754 * @return <code>true</code> if one or more records were actually removed,
755- * else </i>false</i>.
756+ * else <i>false</i>.
757 *
758 * @throws PersistitException
759 * if there are any internal errors
760
761=== modified file 'src/main/java/com/persistit/Key.java'
762--- src/main/java/com/persistit/Key.java 2013-03-21 22:38:14 +0000
763+++ src/main/java/com/persistit/Key.java 2013-03-23 22:07:26 +0000
764@@ -2155,7 +2155,7 @@
765
766 /**
767 * Append the next key segment of the supplied <code>Key</code> to this
768- * <code>Key</code. The next key segment is determined by the current index
769+ * <code>Key</code>. The next key segment is determined by the current index
770 * of the key and can be set using the {@link #setIndex(int)} method.
771 *
772 * @param key
773
774=== modified file 'src/main/java/com/persistit/Management.java'
775--- src/main/java/com/persistit/Management.java 2013-03-06 19:09:50 +0000
776+++ src/main/java/com/persistit/Management.java 2013-03-23 22:07:26 +0000
777@@ -494,7 +494,7 @@
778
779 /**
780 * Return a <code>TreeInfo</code> for a specified <code>Volume</code> and
781- * </code>Tree</code>. If Persisit is not initialized, or if no no volume or
782+ * <code>Tree</code>. If Persisit is not initialized, or if no no volume or
783 * tree with corresponding names is found, or if there is a transient error
784 * in acquiring the information, this method returns <code>null</code>.
785 *
786@@ -2338,7 +2338,6 @@
787
788 /**
789 * Return one of the following values:
790- * <p />
791 * <table>
792 * <tr>
793 * <td>Long.MINVALUE</td>
794@@ -2601,7 +2600,6 @@
795
796 /**
797 * Return one of the following values:
798- * <p />
799 * <table>
800 * <tr>
801 * <td>Long.MINVALUE</td>
802
803=== modified file 'src/main/java/com/persistit/Task.java'
804--- src/main/java/com/persistit/Task.java 2012-08-24 13:57:19 +0000
805+++ src/main/java/com/persistit/Task.java 2013-03-23 22:07:26 +0000
806@@ -415,9 +415,9 @@
807
808 /**
809 * Returns a String message describing the current state of this
810- * <code>Task<code>, possibly in greater detail than {@link #getStatus}. The
811- * default implementation returns the same description as <code>getStatus</code>
812- * .
813+ * <code>Task</code>, possibly in greater detail than {@link #getStatus}.
814+ * The default implementation returns the same description as
815+ * <code>getStatus</code>.
816 *
817 * @return A detailed description of this <code>Task</code>'s current state.
818 */
819
820=== modified file 'src/main/java/com/persistit/Value.java'
821--- src/main/java/com/persistit/Value.java 2013-03-06 16:20:57 +0000
822+++ src/main/java/com/persistit/Value.java 2013-03-23 22:07:26 +0000
823@@ -588,8 +588,8 @@
824 }
825
826 /**
827- * Construct a </code>Value</code> object with specified initial encoded
828- * size and default maximum size.
829+ * Construct a <code>Value</code> object with specified initial encoded size
830+ * and default maximum size.
831 *
832 * @param initialSize
833 * Initial size of the encoded value buffer.
834
835=== modified file 'src/main/java/com/persistit/mxbeans/ManagementMXBean.java'
836--- src/main/java/com/persistit/mxbeans/ManagementMXBean.java 2012-08-24 13:57:19 +0000
837+++ src/main/java/com/persistit/mxbeans/ManagementMXBean.java 2013-03-23 22:07:26 +0000
838@@ -118,7 +118,7 @@
839 String transactionReport(int max) throws RemoteException;
840
841 /**
842- * @return the name of the current default <code>CommitPolicy<code>
843+ * @return the name of the current default <code>CommitPolicy</code>
844 */
845 String getDefaultCommitPolicy() throws RemoteException;
846
847
848=== modified file 'src/main/java/com/persistit/mxbeans/TransactionIndexMXBean.java'
849--- src/main/java/com/persistit/mxbeans/TransactionIndexMXBean.java 2012-08-24 13:57:19 +0000
850+++ src/main/java/com/persistit/mxbeans/TransactionIndexMXBean.java 2013-03-23 22:07:26 +0000
851@@ -30,10 +30,10 @@
852 /**
853 * Timestamp known to be less than or equal to the start timestamp of any
854 * currently executing transaction. This value is computed by
855- * <code>updateActiveTransactionCache<code> and is therefore less the
856+ * <code>updateActiveTransactionCache</code> and is therefore less the
857 * timestamp of any currently executing transaction at the instant that
858- * method was called. It is guaranteed that no running transaction
859- * has a lower start timestamp.
860+ * method was called. It is guaranteed that no running transaction has a
861+ * lower start timestamp.
862 *
863 * @return Lower bound on start timestamps of currently active transactions.
864 */
865@@ -41,9 +41,9 @@
866
867 /**
868 * Timestamp recorded at the start of the last invocation of
869- * <code>updateActiveTransactionCache<code>. Any transaction newer than
870- * this ceiling is currently considered active even if it has
871- * already committed or aborted.
872+ * <code>updateActiveTransactionCache</code>. Any transaction newer than
873+ * this ceiling is currently considered active even if it has already
874+ * committed or aborted.
875 *
876 * @return Upper bound on timestamps for which
877 * {@link com.persistit.TransactionIndex#hasConcurrentTransaction(long, long)
878@@ -53,7 +53,7 @@
879
880 /**
881 * Count of active transactions measured when
882- * <code>updateActiveTransactionCache<code> was last called. The count may
883+ * <code>updateActiveTransactionCache</code> was last called. The count may
884 * have changed to due new transactions starting or existing transactions
885 * committing since that invocation, and therefore the value returned by
886 * this method is an estimate.
887
888=== modified file 'src/main/javadoc/overview.html'
889--- src/main/javadoc/overview.html 2012-08-02 04:45:28 +0000
890+++ src/main/javadoc/overview.html 2013-03-23 22:07:26 +0000
891@@ -22,8 +22,8 @@
892 <div id="content">
893 <div id="preamble">
894 <div class="sectionbody">
895-<div class="paragraph"><p>Persistit&#8482; is a small, lightweight Java&#8482; library that provides simple, fast and reliable data persistence for Java applications. It is designed to be embedded in Java application programs and to operate free of administration by the end-user.</p></div>
896-<div class="paragraph"><p>This section provides a brief overview. See <a href="http://www.akiban.com/ak-docs/admin/persistit">http://www.akiban.com/ak-docs/admin/persistit</a> for complete documentation.</p></div>
897+<div class="paragraph"><p>Akiban-Persistit&#8482; is a small, lightweight Java&#8482; library that provides simple, fast and reliable data persistence for Java applications. It is designed to be embedded in Java application programs and to operate free of administration by the end-user.</p></div>
898+<div class="paragraph"><p>This section provides a brief overview. See <a href="http://akiban.github.com/persistit">http://akiban.github.com/persistit</a> for complete documentation.</p></div>
899 </div>
900 </div>
901 <h2 id="_api_overview">API Overview</h2>
902@@ -40,10 +40,13 @@
903 <div class="paragraph"><p>An Exchange is a moderately complex object that requires several thousand bytes of heap space. Memory-constrained applications should construct Exchanges in moderate numbers. An Exchange internally maintains some optimization information such that references to nearby Keys within a tree are accelerated. Performance may benefit from using a different Exchange for each area of the Tree being accessed.</p></div>
904 <div class="paragraph"><p>Persistit offers Exchange pooling to avoid rapidly creating and destroying Exchange objects in multi-threaded applications. In particular, web applications may benefit from using the Exchange pool.</p></div>
905 <div class="paragraph"><p>An Exchange is always associated with a com.persistit.Key and a com.persistit.Value. Typically you work with an Exchange in one of the following patterns:
906-. Modify the Key, perform a <tt>fetch</tt> operation, and extract the Value.
907-. Modify the Key, modify the Value, and then perform a <tt>store</tt> operation.
908-. Modify the Key, and then perform a <tt>remove</tt> operation.
909-. Optionally modify the Key, perform a <tt>traverse</tt> operation, then read the resulting Key and/or Value.</p></div>
910+<ul>
911+<li>Modify the Key, perform a <tt>fetch</tt> operation, and extract the Value.</li>
912+<li>Modify the Key, modify the Value, and then perform a <tt>store</tt> operation.</li>
913+<li>Modify the Key, and then perform a <tt>remove</tt> operation.</li>
914+<li>Optionally modify the Key, perform a <tt>traverse</tt> operation, then read the resulting Key and/or Value.</li>
915+</ul>
916+</p></div>
917 <div class="paragraph"><p>These four methods, plus a few other methods listed here, are the primary low-level interface to the database. Semantics are as follows:</p></div>
918 <div class="hdlist"><table>
919 <tr>
920@@ -53,7 +56,7 @@
921 </td>
922 <td class="hdlist2">
923 <p style="margin-top: 0;">
924-Reads the stored value associated with this Exchange&#8217;s Key and modifies the Exchange’s Value to reflect that value.
925+Reads the stored value associated with this Exchange's Key and modifies the Exchange's Value to reflect that value.
926 </p>
927 </td>
928 </tr>
929@@ -108,7 +111,7 @@
930 </td>
931 <td class="hdlist2">
932 <p style="margin-top: 0;">
933-Modifies the Exchange’s Key and Value to reflect a successor or predecessor key within the tree. (See API documentation for com.persistit.Key for information on the order of traversal.)
934+Modifies the Exchange's Key and Value to reflect a successor or predecessor key within the tree. (See API documentation for com.persistit.Key for information on the order of traversal.)
935 </p>
936 </td>
937 </tr>
938@@ -130,7 +133,7 @@
939 </td>
940 <td class="hdlist2">
941 <p style="margin-top: 0;">
942-Indicates, without modifying the Exchange’s Value or Key objects, whether there is a successor or predecessor key in the Tree.
943+Indicates, without modifying the Exchange's Value or Key objects, whether there is a successor or predecessor key in the Tree.
944 </p>
945 </td>
946 </tr>
947@@ -162,7 +165,7 @@
948 map<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">put</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"Boston"</span><span style="color: #990000">,</span> <span style="color: #FF0000">"Hub"</span><span style="color: #990000">);</span></tt></pre></div></div>
949 <div class="paragraph"><p>places a key/value pair into the myTree with the concatenated key <tt>{"USA ","MA","Boston"}</tt> and a value of <tt>"Hub"</tt>.</p></div>
950 <div class="paragraph"><p>Because Persistit is designed for concurrent operation it is possible (and often intended) for the backing store of PersistitMap to be changed by other threads while a java.util.Iterator is in use. Generally the expected behavior for an Iterator on a Map collection view is to throw a ConcurrentModificationException if the underlying collection changes. This is known as fail-fast behavior. PersistitMap implements this behavior by throwing a ConcurrentModificationException in the event the Tree containing the map changes. An application can detect that the map may have changed due to a programming error in case the design contract calls for it to remain unchanged by catching this exception.</p></div>
951-<div class="paragraph"><p>However, sometimes it may be desirable to use PersistitMap and its collections view interfaces to iterate across changing data. Internally, Persistit uses the traverse method to retrieve the next highest key in the key sort order in order to implement the Iterator’s hasNext and next methods. The result will depend on the content of the database at the instant these operations are performed. PersistitMap provides the method setAllowConcurrentModification to enable this behavior. By default, concurrent modifications are not allowed.
952+<div class="paragraph"><p>However, sometimes it may be desirable to use PersistitMap and its collections view interfaces to iterate across changing data. Internally, Persistit uses the traverse method to retrieve the next highest key in the key sort order in order to implement the Iterator's hasNext and next methods. The result will depend on the content of the database at the instant these operations are performed. PersistitMap provides the method setAllowConcurrentModification to enable this behavior. By default, concurrent modifications are not allowed.
953 === KeyFilter</p></div>
954 <div class="paragraph"><p>A <tt>com.persistit.KeyFilter</tt> defines a subset of all possible key values. You can supply a KeyFilter to the traverse methods of an Exchange. You can also specify a KeyFilter for any Iterator returned by the collection views of a PersistitMap. In either case, the key/value pairs covered by traversing the database or iterating over the collection view are restricted to those selected by the KeyFilter.</p></div>
955 <div class="paragraph"><p>Use of a KeyFilter is illustrated by the following code fragment:</p></div>
956@@ -178,11 +181,11 @@
957 <span style="color: #FF0000">{</span>
958 System<span style="color: #990000">.</span>out<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">println</span></span><span style="color: #990000">(</span>ex<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">getKey</span></span><span style="color: #990000">().</span><span style="font-weight: bold"><span style="color: #000000">reset</span></span><span style="color: #990000">().</span><span style="font-weight: bold"><span style="color: #000000">decodeString</span></span><span style="color: #990000">());</span>
959 <span style="color: #FF0000">}</span></tt></pre></div></div>
960-<div class="paragraph"><p>This simple example emits the string-valued keys within myTree whose values fall alphabetically between “Bellini” and “Busoni”, inclusive.</p></div>
961+<div class="paragraph"><p>This simple example emits the string-valued keys within myTree whose values fall alphabetically between "Bellini" and "Busoni", inclusive.</p></div>
962 </div>
963 <h2 id="_transactions">Transactions</h2>
964 <div class="sectionbody">
965-<div class="paragraph"><p>Persistit supports transactions with full isolation and optimistic concurrency control. An application may begin, commit or roll back the current transaction scope explicitly, executing multiple database operations in an atomic, consistent, isolated and (optionally) durable (ACID) manner. If the application does not explicitly define the scope of a transaction, each database operation implicitly runs within the scope of a separate transaction. Each Persistit transaction may optionally be committed to either memory or disk. Transactions committed to memory are much faster, but are not immediately durable. (See Transactions.)</p></div>
966+<div class="paragraph"><p>Persistit supports transactions with Snapshot Isolation and optimistic concurrency control. An application may begin, commit or roll back the current transaction scope explicitly, executing multiple database operations in an atomic, consistent, isolated and (optionally) durable (ACID) manner. Each Persistit transaction may optionally be committed to either memory or disk. Transactions committed to memory are much faster, but are not immediately durable. (See Transactions.)</p></div>
967 </div>
968 <h2 id="_configuration">Configuration</h2>
969 <div class="sectionbody">
970@@ -190,7 +193,7 @@
971 </div>
972 <h2 id="_logging_api">Logging API</h2>
973 <div class="sectionbody">
974-<div class="paragraph"><p>Persistit is writes various diagnostic and informational messages to a log. By default, the log is written as text to the file <tt>persistit.log</tt> in the current working directory. However, a container application will usually have a logging architecture already in place, and Persistit provides a simple way to redirect its log output to the container application’s log. Adapters for Log4J and the Java Logging API are included; other logging systems are easy to adapt.</p></div>
975+<div class="paragraph"><p>Persistit is writes various diagnostic and informational messages to a log. By default, the log is written as text to the file <tt>persistit.log</tt> in the current working directory. However, a container application will usually have a logging architecture already in place, and Persistit provides a simple way to redirect its log output to the container application's log. Adapters for Log4J and the Java Logging API are included; other logging systems are easy to adapt.</p></div>
976 </div>
977 </div>
978 <div id="footnotes"><hr /></div>

Subscribers

People subscribed via source and target branches