foray-commit Mailing List for FOray
Modular XSL-FO Implementation for Java.
Status: Alpha
Brought to you by:
victormote
You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
(139) |
Apr
(98) |
May
(250) |
Jun
(394) |
Jul
(84) |
Aug
(13) |
Sep
(420) |
Oct
(186) |
Nov
(1) |
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(108) |
Feb
(202) |
Mar
(291) |
Apr
(247) |
May
(374) |
Jun
(227) |
Jul
(231) |
Aug
(60) |
Sep
(31) |
Oct
(45) |
Nov
(18) |
Dec
|
| 2008 |
Jan
(38) |
Feb
(71) |
Mar
(142) |
Apr
|
May
(59) |
Jun
(6) |
Jul
(10) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2009 |
Jan
(12) |
Feb
(4) |
Mar
(88) |
Apr
(121) |
May
(17) |
Jun
(30) |
Jul
|
Aug
(5) |
Sep
|
Oct
(1) |
Nov
|
Dec
|
| 2010 |
Jan
(11) |
Feb
(76) |
Mar
(11) |
Apr
|
May
(11) |
Jun
|
Jul
|
Aug
(44) |
Sep
(14) |
Oct
(7) |
Nov
|
Dec
|
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(9) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(10) |
Nov
|
Dec
|
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
(4) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(168) |
| 2017 |
Jan
(77) |
Feb
(11) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
(1) |
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2019 |
Jan
|
Feb
(88) |
Mar
(118) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(6) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(141) |
| 2021 |
Jan
(170) |
Feb
(20) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(62) |
Nov
(189) |
Dec
(162) |
| 2022 |
Jan
(201) |
Feb
(118) |
Mar
(8) |
Apr
|
May
(2) |
Jun
(47) |
Jul
(19) |
Aug
(14) |
Sep
(3) |
Oct
|
Nov
(28) |
Dec
(235) |
| 2023 |
Jan
(112) |
Feb
(23) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(1) |
Jul
|
Aug
(70) |
Sep
(92) |
Oct
(20) |
Nov
(1) |
Dec
(1) |
| 2024 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
(14) |
Jun
(11) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2025 |
Jan
(10) |
Feb
(29) |
Mar
|
Apr
(162) |
May
(245) |
Jun
(83) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(2) |
2
(2) |
|
3
(2) |
4
(2) |
5
(8) |
6
(5) |
7
(3) |
8
(5) |
9
(2) |
|
10
(6) |
11
(6) |
12
(3) |
13
(5) |
14
(6) |
15
(5) |
16
(5) |
|
17
(3) |
18
(6) |
19
(6) |
20
(6) |
21
(7) |
22
(2) |
23
(4) |
|
24
|
25
(2) |
26
(1) |
27
(1) |
28
(6) |
29
(3) |
30
(4) |
|
31
|
|
|
|
|
|
|
|
From: <vic...@us...> - 2019-03-30 21:08:22
|
Revision: 11560
http://sourceforge.net/p/foray/code/11560
Author: victormote
Date: 2019-03-30 21:08:13 +0000 (Sat, 30 Mar 2019)
Log Message:
-----------
1. Remove leftover casts that are truncating indexes. 2. Move clone logic from TernaryNodesChar to TernaryNodes. 3. Add methods allowing client code to get to the TernaryTree optimization.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/DictionaryParser.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -527,6 +527,27 @@
this.keyChar[index] = value;
}
+ /**
+ * Copies the data from this collection into a new instance of {@link TernaryNodesInt}.
+ * @return A copy of the data from this structure, packaged in a new instance of {@link TernaryNodesInt}.
+ */
+ public TernaryNodesInt cloneAsInt() {
+ if (this instanceof TernaryNodesInt) {
+ return (TernaryNodesInt) this;
+ }
+ final TernaryNodesInt newNodes = new TernaryNodesInt();
+ /* Presumably, this is done because we are out of room in the char version, so add some capacity. */
+ newNodes.resize(this.keyChar.length + DEFAULT_BLOCK_SIZE);
+ for (int index = 0; index < this.keyChar.length; index ++) {
+ newNodes.setLow(index, getLow(index));
+ newNodes.setEqual(index, getEqual(index));
+ newNodes.setHigh(index, getHigh(index));
+ newNodes.setKeyChar(index, getKeyChar(index));
+ }
+ ((TernaryNodes) newNodes).freenode = this.freenode;
+ return newNodes;
+ }
+
@Override
public TernaryNodes clone() {
final TernaryNodes clone = forceClone();
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -104,26 +104,6 @@
return clone;
}
- /**
- * Copies the data from this collection into a new instance of {@link TernaryNodesInt}.
- * @return A copy of the data from this structure, packaged in a new instance of {@link TernaryNodesInt}.
- */
- public TernaryNodesInt cloneAsInt() {
- final TernaryNodesInt newNodes = new TernaryNodesInt();
- /* Presumably, this is done because we are out of room in the char version, so add some capacity. */
- newNodes.resize(this.low.length + DEFAULT_BLOCK_SIZE);
- /* Start copy at 1 instead of 0. Node 0 is not really explicity created. */
- for (int index = 1; index < this.low.length; index ++) {
- /* Allocating the node explicitly should keep the node count correct. */
- newNodes.allocateNewNode();
- newNodes.setLow(index, getLow(index));
- newNodes.setEqual(index, getEqual(index));
- newNodes.setHigh(index, getHigh(index));
- newNodes.setKeyChar(index, getKeyChar(index));
- }
- return newNodes;
- }
-
@Override
public TernaryNodesChar createInstance() {
return new TernaryNodesChar();
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -56,32 +56,32 @@
@Override
public int getLow(final int index) {
- return this.low[(int) index];
+ return this.low[index];
}
@Override
public void setLow(final int index, final int value) {
- this.low[index] = (char) value;
+ this.low[index] = value;
}
@Override
public int getHigh(final int index) {
- return this.high[(int) index];
+ return this.high[index];
}
@Override
public void setHigh(final int index, final int value) {
- this.high[index] = (char) value;
+ this.high[index] = value;
}
@Override
public int getEqual(final int index) {
- return this.equal[(int) index];
+ return this.equal[index];
}
@Override
public void setEqual(final int index, final int value) {
- this.equal[index] = (char) value;
+ this.equal[index] = value;
}
@Override
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -48,8 +48,8 @@
import java.util.Stack;
/**
- * <p>A map whose key is always a {@link CharSequence} (usually a {@link String}), and whose value is a char, usually
- * used to store an index into some other data structure.
+ * <p>A map whose key is always a {@link CharSequence} (usually a {@link String}), and whose value is a char or other
+ * integral value, usually used to store an index into some other data structure.
* This class is intended to serve as a base class or helper class for natural-language dictionaries and similar data
* structures.</p>
*
@@ -83,10 +83,7 @@
* Compressed branches are decompressed as needed when another key with same prefix is inserted.
* This saves a lot of space, especially for long keys.</p>
*
- * <p>This class could be extended to or embedded in a general map that would allow arbitrary objects to be values in
- * the map.
- * One scheme for doing so would be to create an array of the value Objects, and use this class to store the indexes to
- * that array.</p>
+ * @see TernaryTreeMap for a wrapper that implements the {@link java.util.Map} interface.
*/
public class TernaryTree implements Cloneable, Serializable {
@@ -102,9 +99,7 @@
* 2. TODO: 0xFFFF currently has special meaning, marking the compressed branches.
* It would be good to eliminate this limitation, possibly by adding a boolean array to the data structures that
* marks whether the data in that node is compressed or not.
- * 3. TODO: The zero-termination in CharVector is probably not needed, as the ending index can probably be stored in
- * the hi branch of the compressed node, just as the starting index is stored in the lo branch.
- * 4. TODO: We miss an opportunity by using the branch compression.
+ * 3. TODO: We miss an opportunity by using the branch compression.
* The good news is that it saves nodes, but the bad news is that it saves nodes.
* It might be useful, in addition to returning mapped values, to return the node number that contains the
* mapped value.
@@ -244,12 +239,6 @@
}
put(this.nodes.getRootNodeIndex(), key, start, end, value);
-
- if (this.logger.isDebugEnabled()) {
- if (! this.nodes.isConsistent()) {
- throw new IllegalStateException("Tree is in an inconsistent state. See the log for details.");
- }
- }
}
/**
@@ -382,7 +371,7 @@
* from the compressed branch by incrementing that branch's starting point. */
this.nodes.setLow(newNodeIndex, this.nodes.getLow(newNodeIndex) + 1);
- /* If there is nothing left to compress, convert the compresses node to an uncompressed node. */
+ /* If there is nothing left to compress, convert the compressed node to an uncompressed node. */
if (suffix.length() <= this.nodes.getLow(newNodeIndex)) {
/* We are at the end of the compressed node. Mark the new node to indicate that it is NOT a
* compressed node. */
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -169,4 +169,12 @@
return Collections.emptySet();
}
+ /**
+ * After all items have been added to the tree, this method can be run to give the tree an opportunity to optimize
+ * itself.
+ */
+ public void optimize() {
+ this.keys.optimize();
+ }
+
}
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/DictionaryParser.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/DictionaryParser.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/DictionaryParser.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -135,6 +135,7 @@
for (Map.Entry<String, StringWord> entry : wordMap.entrySet()) {
dictionary.addWord(entry.getKey(), entry.getValue());
}
+ dictionary.optimize();
return dictionary;
}
@@ -153,4 +154,5 @@
}
return null;
}
+
}
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-30 19:44:50 UTC (rev 11559)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-30 21:08:13 UTC (rev 11560)
@@ -28,8 +28,9 @@
package org.foray.hyphen;
+import org.foray.common.data.TernaryTreeMap;
+
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -43,8 +44,11 @@
/** Constant needed for serialization. */
private static final long serialVersionUID = -8752423281137349847L;
- /** The data structure containing the dictionary words. */
- private Map<CharSequence, SegmentDictionaryWord> wordMap = new HashMap<CharSequence, SegmentDictionaryWord>();
+ /** The data structure containing the dictionary words.
+ * TODO: More work needs to be done to determine which Map implementation should be used here.
+ * The TernaryTreeMap currently uses approximately 50% more memory, but has not been optimized for memory use.
+ * The other tradeoff axis is speed, and we are not sure which implementation is faster. */
+ private Map<CharSequence, SegmentDictionaryWord> wordMap = new TernaryTreeMap<SegmentDictionaryWord>();
/** The array of word segments in this dictionary. */
private StringWordSegment[] wordSegments;
@@ -138,4 +142,13 @@
return this.wordSegments[index];
}
+ /**
+ * After all items have been added to the dictionary, this method can be run to give the dictionary an opportunity
+ * to optimize itself.
+ */
+ public void optimize() {
+ final TernaryTreeMap<SegmentDictionaryWord> ternaryTreeMap =
+ (TernaryTreeMap<SegmentDictionaryWord>) this.wordMap;
+ ternaryTreeMap.optimize();
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-30 19:45:00
|
Revision: 11559
http://sourceforge.net/p/foray/code/11559
Author: victormote
Date: 2019-03-30 19:44:50 +0000 (Sat, 30 Mar 2019)
Log Message:
-----------
Throw exception if values are not valid chars.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharacterUtils.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-30 19:42:27 UTC (rev 11558)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-30 19:44:50 UTC (rev 11559)
@@ -28,6 +28,8 @@
package org.foray.common.data;
+import org.foray.common.primitive.CharacterUtils;
+
import java.util.Arrays;
/**
@@ -61,6 +63,9 @@
@Override
public void setLow(final int index, final int value) {
+ if (! CharacterUtils.isInCharacterRange(value)) {
+ throw new IllegalArgumentException("Value is not valid char: " + value);
+ }
this.low[index] = (char) value;
}
@@ -71,6 +76,9 @@
@Override
public void setHigh(final int index, final int value) {
+ if (! CharacterUtils.isInCharacterRange(value)) {
+ throw new IllegalArgumentException("Value is not valid char: " + value);
+ }
this.high[index] = (char) value;
}
@@ -81,6 +89,9 @@
@Override
public void setEqual(final int index, final int value) {
+ if (! CharacterUtils.isInCharacterRange(value)) {
+ throw new IllegalArgumentException("Value is not valid char: " + value);
+ }
this.equal[index] = (char) value;
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharacterUtils.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharacterUtils.java 2019-03-30 19:42:27 UTC (rev 11558)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharacterUtils.java 2019-03-30 19:44:50 UTC (rev 11559)
@@ -49,6 +49,9 @@
/** The typographical double close quotation mark: \u201D. */
public static final char DOUBLE_CLOSE_QUOTATION_MARK = '\u201D';
+ /** The maximum printable ASCII character, a tilde ~, 0x7E, 126. */
+ public static final char MAX_PRINTABLE_ASCII_CHAR = '\u007E';
+
/** The punctuation characters which, when they immediately precede a word, should not be separated from that word
* during line-breaking. TODO: This list is not comprehensive and should be improved. */
private static final String ATTACHED_LEADING_PUNCTUATION = new String(new char[] {
@@ -149,4 +152,20 @@
return (char) (WellKnownConstants.MAX_8_BIT_UNSIGNED_INT & theByte);
}
+ /**
+ * Indicates whether an integral type can be safely converted to a char without loss of data.
+ * @param theIntegral The integral being tested.
+ * @return True if and only if {@code theIntegral} is between {@link Character#MIN_VALUE} inclusive and
+ * {@link Character#MAX_VALUE} inclusive.
+ */
+ public static boolean isInCharacterRange(final long theIntegral) {
+ if (theIntegral < Character.MIN_VALUE) {
+ return false;
+ }
+ if (theIntegral > Character.MAX_VALUE) {
+ return false;
+ }
+ return true;
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-30 19:42:38
|
Revision: 11558
http://sourceforge.net/p/foray/code/11558
Author: victormote
Date: 2019-03-30 19:42:27 +0000 (Sat, 30 Mar 2019)
Log Message:
-----------
Log, but don't throw exception for inconsistencies.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-30 16:47:10 UTC (rev 11557)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-30 19:42:27 UTC (rev 11558)
@@ -28,6 +28,8 @@
package org.foray.common.data;
+import org.foray.common.primitive.CharacterUtils;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -196,7 +198,7 @@
public String toString() {
char printableChar = this.keyChar;
if (printableChar < ' '
- || printableChar == Character.MAX_VALUE) {
+ || printableChar > CharacterUtils.MAX_PRINTABLE_ASCII_CHAR) {
printableChar = ' ';
}
return String.format(TO_STRING_FORMAT,
@@ -330,10 +332,10 @@
/**
* Constructor.
* Finds the parent for each node.
- * @throws InconsistentTreeException If problems in the current state of the tree are found.
*/
- public WithParents() throws InconsistentTreeException {
+ public WithParents() {
final String multipleParentFormat = "Index %d, referenced from Index %d, already has parent Index %d";
+
/* Start at index 1. Index 0 doesn't point anywhere. */
for (int index = 1; index < this.parents.length; index++) {
final int lowPointer = TernaryNodes.this.getLowPointer(index);
@@ -341,7 +343,7 @@
if (this.parents[lowPointer] == 0) {
this.parents[lowPointer] = index;
} else {
- throw new InconsistentTreeException(
+ TernaryNodes.this.logger.error(
String.format(multipleParentFormat, lowPointer, index, this.parents[lowPointer]));
}
}
@@ -350,7 +352,7 @@
if (this.parents[equalPointer] == 0) {
this.parents[equalPointer] = index;
} else {
- throw new InconsistentTreeException(
+ TernaryNodes.this.logger.error(
String.format(multipleParentFormat, equalPointer, index, this.parents[equalPointer]));
}
}
@@ -359,7 +361,7 @@
if (this.parents[highPointer] == 0) {
this.parents[highPointer] = index;
} else {
- throw new InconsistentTreeException(
+ TernaryNodes.this.logger.error(
String.format(multipleParentFormat, highPointer, index, this.parents[highPointer]));
}
}
@@ -367,10 +369,10 @@
/* Nodes 0 and 1 should not have parents... */
if (parents[0] != 0) {
- throw new InconsistentTreeException("Index 0 should have no parent.");
+ TernaryNodes.this.logger.error("Index 0 should have no parent.");
}
if (parents[1] != 0) {
- throw new InconsistentTreeException("Index 1 should have no parent.");
+ TernaryNodes.this.logger.error("Index 1 should have no parent.");
}
/* ... but everybody else should, unless they are orphaned. */
@@ -384,22 +386,22 @@
} else if (index == end + 1) {
end = index;
} else if (start == end) {
- throw new InconsistentTreeException("Index " + start + " has no parent.");
-// start = index;
-// end = index;
+ TernaryNodes.this.logger.error("Index " + start + " has no parent.");
+ start = index;
+ end = index;
} else {
- throw new InconsistentTreeException(
+ TernaryNodes.this.logger.error(
"Indexes " + start + " through " + end + " have no parent.");
-// start = index;
-// end = index;
+ start = index;
+ end = index;
}
}
}
if (start > -1) {
if (start == end) {
- throw new InconsistentTreeException("Index " + start + " has no parent.");
+ TernaryNodes.this.logger.error("Index " + start + " has no parent.");
} else {
- throw new InconsistentTreeException("Indexes " + start + " through " + end + " have no parent.");
+ TernaryNodes.this.logger.error("Indexes " + start + " through " + end + " have no parent.");
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-30 16:47:15
|
Revision: 11557
http://sourceforge.net/p/foray/code/11557
Author: victormote
Date: 2019-03-30 16:47:10 +0000 (Sat, 30 Mar 2019)
Log Message:
-----------
Remove unnecessary cast.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-29 22:53:00 UTC (rev 11556)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-30 16:47:10 UTC (rev 11557)
@@ -56,7 +56,7 @@
@Override
public int getLow(final int index) {
- return this.low[(int) index];
+ return this.low[index];
}
@Override
@@ -66,7 +66,7 @@
@Override
public int getHigh(final int index) {
- return this.high[(int) index];
+ return this.high[index];
}
@Override
@@ -76,7 +76,7 @@
@Override
public int getEqual(final int index) {
- return this.equal[(int) index];
+ return this.equal[index];
}
@Override
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-29 22:53:06
|
Revision: 11556
http://sourceforge.net/p/foray/code/11556
Author: victormote
Date: 2019-03-29 22:53:00 +0000 (Fri, 29 Mar 2019)
Log Message:
-----------
Convert compressed node logic to use a list of Strings instead of StringBuilder, because of limitation of 16-bits for the index space.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharSequenceUtils.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-29 22:49:27 UTC (rev 11555)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-29 22:53:00 UTC (rev 11556)
@@ -40,7 +40,11 @@
import org.slf4j.LoggerFactory;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
+import java.util.List;
import java.util.Stack;
/**
@@ -123,7 +127,7 @@
* It is simply a series of word fragments, each followed by a {@link StringUtils#NULL_TERMINATOR}.
* The index to the start of the compressed portion of the key for a given node in the tree is found in the
* {@link TernaryNodes#getLow(int)} value for the node. */
- private StringBuilder compressedKeys;
+ private List<String> suffixes;
/** The number of key-value pairs mapped in the tree.
* This is not necessarily the same as the number of nodes in the tree, because of branch compression, and because
@@ -152,7 +156,7 @@
*/
private void init() {
this.length = 0;
- this.compressedKeys = new StringBuilder();
+ this.suffixes = new ArrayList<String>();
this.nodes.init();
}
@@ -333,12 +337,12 @@
/* Mark the branch as compressed */
this.nodes.setKeyChar(currentNodeIndex, Character.MAX_VALUE);
/* Store the compressed data in the vector for that purpose. */
- final int startOfCompressedData = this.compressedKeys.length();
- this.compressedKeys.append(key, start, start + len);
- /* Store the index to the compressed data in the "lo" value. */
- this.nodes.setLow(currentNodeIndex, startOfCompressedData);
- /* Zero-terminate the compressed data. */
- this.compressedKeys.append(StringUtils.NULL_TERMINATOR);
+ final int indexToNewSuffix = this.suffixes.size();
+ this.suffixes.add(key.subSequence(start, start + len).toString());
+ /* Store the index to the suffix in the "high" value. */
+ this.nodes.setHigh(currentNodeIndex, indexToNewSuffix);
+ /* Store the index within the suffix "low" value. This will always start at zero. */
+ this.nodes.setLow(currentNodeIndex, 0);
} else {
this.nodes.setKeyChar(currentNodeIndex, Character.MIN_VALUE);
this.nodes.setLow(currentNodeIndex, 0);
@@ -357,7 +361,8 @@
}
/* Set the key character for the current node to be the first character in the previously-compressed data. */
- this.nodes.setKeyChar(nodeIndex, this.compressedKeys.charAt(this.nodes.getLow(nodeIndex)));
+ final String suffix = this.suffixes.get(this.nodes.getHigh(nodeIndex));
+ this.nodes.setKeyChar(nodeIndex, suffix.charAt(this.nodes.getLow(nodeIndex)));
/* Create and initialize the new node. */
final int newNodeIndex = createNode();
@@ -376,7 +381,9 @@
/* We just moved the first character in the compressed branch to this node. We now need to remove it
* from the compressed branch by incrementing that branch's starting point. */
this.nodes.setLow(newNodeIndex, this.nodes.getLow(newNodeIndex) + 1);
- if (this.compressedKeys.charAt(this.nodes.getLow(newNodeIndex)) == 0) {
+
+ /* If there is nothing left to compress, convert the compresses node to an uncompressed node. */
+ if (suffix.length() <= this.nodes.getLow(newNodeIndex)) {
/* We are at the end of the compressed node. Mark the new node to indicate that it is NOT a
* compressed node. */
this.nodes.setLow(newNodeIndex, 0);
@@ -474,8 +481,10 @@
}
if (this.nodes.isCompressedValueNode(charNodeIndex)) {
- if (CharSequenceUtils.compareNullTerminated(
- this.compressedKeys, this.nodes.getLow(charNodeIndex), key, i, end) == 0) {
+ final String suffix = this.suffixes.get(this.nodes.getHigh(charNodeIndex));
+ final int suffixStart = this.nodes.getLow(charNodeIndex);
+ if (CharSequenceUtils.areEquivalent(suffix, suffixStart, suffix.length() - suffixStart,
+ key, i, end - i)) {
return charNodeIndex;
}
return -1;
@@ -510,7 +519,8 @@
public TernaryTree clone() {
final TernaryNodes newNodes = this.nodes.clone();
final TernaryTree t = new TernaryTree(newNodes);
- t.compressedKeys = new StringBuilder(this.compressedKeys);
+ t.suffixes = new ArrayList<String>(this.suffixes.size());
+ Collections.copy(t.suffixes, this.suffixes);
t.length = this.length;
return t;
@@ -583,12 +593,12 @@
this.nodes.pack();
/* Compact the compressedKeys. */
- final StringBuilder kx = new StringBuilder();
+ final ArrayList<String> kx = new ArrayList<String>();
final TernaryNodes nodes = this.nodes.createInstance();
final TernaryTree map = new TernaryTree(nodes);
compact(kx, map, this.nodes.getRootNodeIndex());
- this.compressedKeys = kx;
- this.compressedKeys.trimToSize();
+ kx.trimToSize();
+ this.suffixes = kx;
}
/**
@@ -597,32 +607,83 @@
* @param map The map being used to look for duplicates.
* @param p The index to the node being tested.
*/
- private void compact(final StringBuilder kx, final TernaryTree map, final int p) {
- int k;
- if (p == 0) {
- return;
+ private void compact(final List<String> kx, final TernaryTree map, final int p) {
+
+ /* Create a cross-references list of suffixes and the nodes that use them, truncating the leading edge of each
+ * suffix where possible. */
+ final List<SuffixXref> xrefs = new ArrayList<SuffixXref>();
+ for (int index = 0; index < this.nodes.size(); index ++) {
+ if (this.nodes.isCompressedValueNode(index)) {
+ final SuffixXref xref = new SuffixXref();
+ final String suffix = this.suffixes.get(this.nodes.getHigh(index));
+ xref.suffix = suffix.substring(this.nodes.getLow(index));
+ xref.nodeIndex = index;
+ xrefs.add(xref);
+ }
}
- if (this.nodes.getKeyChar(p) == Character.MAX_VALUE) {
- k = map.get(this.compressedKeys, this.nodes.getLow(p));
- if (k < 0) {
- k = kx.length();
- final int start = this.nodes.getLow(p);
- final int size = StringUtils.nullTerminatedLength(this.compressedKeys, start);
- kx.append(this.compressedKeys, start, start + size);
- kx.append(StringUtils.NULL_TERMINATOR);
- map.put(kx, k, k);
+
+ /* Sort the cross-reference list by the suffix value so that we can easily find duplicates. */
+ Collections.sort(xrefs, new Comparator<SuffixXref>() {
+ @Override
+ public int compare(final SuffixXref o1, final SuffixXref o2) {
+ return o1.suffix.compareTo(o2.suffix);
}
- this.nodes.setLow(p, k);
- } else {
- compact(kx, map, this.nodes.getLow(p));
- if (this.nodes.getKeyChar(p) != 0) {
- compact(kx, map, this.nodes.getEqual(p));
+ });
+
+ /*
+ * Iterate the cross-reference list, creating the new suffix list while updating the references to it in the
+ * nodes.
+ */
+ String currentSuffix = null;
+ int newSuffixIndex = -1;
+ for (int index = 0; index < xrefs.size(); index++) {
+ final SuffixXref xref = xrefs.get(index);
+ if (! xref.suffix.equals(currentSuffix)) {
+ /* A new suffix. */
+ currentSuffix = xref.suffix;
+ newSuffixIndex = kx.size();
+ kx.add(xref.suffix);
}
- compact(kx, map, this.nodes.getHigh(p));
+ this.nodes.setHigh(xref.nodeIndex, newSuffixIndex);
+ this.nodes.setLow(xref.nodeIndex, 0);
}
+
+// int k;
+// if (p == 0) {
+// return;
+// }
+// if (this.nodes.isCompressedValueNode(p)) {
+// k = map.get(this.compressedKeys, this.nodes.getLow(p));
+// if (k < 0) {
+// k = kx.length();
+// final int start = this.nodes.getLow(p);
+// final int size = StringUtils.nullTerminatedLength(this.compressedKeys, start);
+// kx.append(this.compressedKeys, start, start + size);
+// kx.append(StringUtils.NULL_TERMINATOR);
+// map.put(kx, k, k);
+// }
+// this.nodes.setLow(p, k);
+// } else {
+// compact(kx, map, this.nodes.getLow(p));
+// if (this.nodes.getKeyChar(p) != 0) {
+// compact(kx, map, this.nodes.getEqual(p));
+// }
+// compact(kx, map, this.nodes.getHigh(p));
+// }
}
/**
+ * Private inner class used for optimizing suffixes.
+ */
+ private class SuffixXref {
+ /** The suffix being referenced from {@link #nodeIndex}. */
+ private String suffix;
+
+ /** The node referencing {@link #suffix}. */
+ private int nodeIndex;
+ }
+
+ /**
* Returns the nodes for this instance.
* This is useful mostly for testing and creating new, empty instances.
* @return The nodes.
@@ -847,10 +908,9 @@
// the key should be in the key stack (at least partially)
final StringBuilder buf = new StringBuilder(this.ks.toString());
if (TernaryTree.this.nodes.getKeyChar(this.cur) == Character.MAX_VALUE) {
- int p = TernaryTree.this.nodes.getLow(this.cur);
- while (TernaryTree.this.compressedKeys.charAt(p) != 0) {
- buf.append(TernaryTree.this.compressedKeys.charAt(p++));
- }
+ final String suffix = TernaryTree.this.suffixes.get(TernaryTree.this.nodes.getHigh(this.cur));
+ final int p = TernaryTree.this.nodes.getLow(this.cur);
+ buf.append(suffix.substring(p));
}
this.curkey = buf.toString();
return 0;
@@ -881,12 +941,21 @@
}
/**
- * Returns the compressed keys.
+ * Returns the number of suffixes stored in this tree.
+ * @return The number of suffixes stored in this tree.
+ */
+ int getQtySuffixes() {
+ return this.suffixes.size();
+ }
+
+ /**
+ * Returns a suffix entry.
* This is useful mostly for testing.
- * @return The compressed keys.
+ * @param index The index to the suffix that should be returned.
+ * @return The suffix at {@code index}.
*/
- String getCompressedKeys() {
- return this.compressedKeys.toString();
+ String getSuffix(final int index) {
+ return this.suffixes.get(index);
}
/**
@@ -902,9 +971,9 @@
int currentIndex = index;
while (currentIndex > 0) {
if (nodes.isCompressedValueNode(currentIndex)) {
+ final String suffix = this.suffixes.get(nodes.getHigh(currentIndex));
final int start = nodes.getLow(currentIndex);
- final int length = StringUtils.nullTerminatedLength(this.compressedKeys, start);
- builder.insert(0, this.compressedKeys.substring(start, start + length));
+ builder.insert(0, suffix.substring(start));
} else if (nodes.isCharNode(currentIndex)) {
builder.insert(0, nodes.getKeyChar(currentIndex));
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharSequenceUtils.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharSequenceUtils.java 2019-03-29 22:49:27 UTC (rev 11555)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/primitive/CharSequenceUtils.java 2019-03-29 22:53:00 UTC (rev 11556)
@@ -171,8 +171,8 @@
return false;
}
- for (int index1 = 0; index1 < length1; index1 ++) {
- final int index2 = start2 + index1;
+ for (int index1 = start1; index1 < (start1 + length1); index1 ++) {
+ final int index2 = index1 + start2 - start1;
if (sequence1.charAt(index1) != sequence2.charAt(index2)) {
return false;
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-29 22:49:27 UTC (rev 11555)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-29 22:53:00 UTC (rev 11556)
@@ -296,7 +296,8 @@
Assert.assertEquals(2, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2019, 0, Character.MAX_VALUE);
- Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("superset", map.getSuffix(0));
Assert.assertEquals(1, map.getNodeIndex("superset", 0, "superset".length()));
Assert.assertEquals(-1, map.getNodeIndex("super", 0, "super".length()));
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
@@ -312,7 +313,8 @@
testNode(map, 6, 0, 7, 0, 's');
testNode(map, 7, 6, 2019, 0, Character.MAX_VALUE);
testNode(map, 8, 0, 2007, 6, Character.MIN_VALUE);
- Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("superset", map.getSuffix(0));
Assert.assertEquals(7, map.getNodeIndex("superset", 0, "superset".length()));
Assert.assertEquals(8, map.getNodeIndex("super", 0, "super".length()));
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
@@ -329,7 +331,8 @@
testNode(map, 7, 6, 2019, 0, Character.MAX_VALUE);
testNode(map, 8, 0, 2007, 6, Character.MIN_VALUE);
testNode(map, 9, 0, 1941, 4, Character.MIN_VALUE);
- Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("superset", map.getSuffix(0));
Assert.assertEquals(7, map.getNodeIndex("superset", 0, "superset".length()));
Assert.assertEquals(8, map.getNodeIndex("super", 0, "super".length()));
Assert.assertEquals(9, map.getNodeIndex("sup", 0, "sup".length()));
@@ -359,11 +362,16 @@
testNode(map, 6, 0, 7, 0, 'v');
testNode(map, 7, 0, 8, 9, 'e');
testNode(map, 8, 0, 1002, 10, Character.MIN_VALUE);
- testNode(map, 9, 10, 1003, 0, Character.MAX_VALUE);
+ testNode(map, 9, 0, 1003, 2, Character.MAX_VALUE);
testNode(map, 10, 0, 11, 0, 'r');
testNode(map, 11, 0, 1004, 12, Character.MIN_VALUE);
- testNode(map, 12, 14, 1005, 0, Character.MAX_VALUE);
- Assert.assertEquals("bread\u0000ave\u0000o\u0000r\u0000y\u0000", map.getCompressedKeys());
+ testNode(map, 12, 0, 1005, 4, Character.MAX_VALUE);
+ Assert.assertEquals(5, map.getQtySuffixes());
+ Assert.assertEquals("bread", map.getSuffix(0));
+ Assert.assertEquals("ave", map.getSuffix(1));
+ Assert.assertEquals("o", map.getSuffix(2));
+ Assert.assertEquals("r", map.getSuffix(3));
+ Assert.assertEquals("y", map.getSuffix(4));
Assert.assertEquals(1, map.getNodes().findCharNode(1, 'b'));
Assert.assertEquals(-1, map.getNodes().findCharNode(1, 'q'));
@@ -451,7 +459,8 @@
Assert.assertEquals(2, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 10001, 0, Character.MAX_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
map.uncompressNode(1);
Assert.assertEquals(3, map.getNodes().size());
@@ -458,7 +467,8 @@
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 'b');
testNode(map, 2, 1, 10001, 0, Character.MAX_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
map.uncompressNode(2); // 'r'
map.uncompressNode(3); // 'a'
@@ -474,7 +484,8 @@
testNode(map, 5, 0, 6, 0, 'e');
testNode(map, 6, 0, 7, 0, 'r');
testNode(map, 7, 6, 10001, 0, Character.MAX_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
map.uncompressNode(7); // 'y'
Assert.assertEquals(9, map.getNodes().size());
@@ -487,7 +498,8 @@
testNode(map, 6, 0, 7, 0, 'r');
testNode(map, 7, 0, 8, 0, 'y');
testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
@@ -499,7 +511,8 @@
Assert.assertEquals(2, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 10001, 0, Character.MAX_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
/* Add shorter word. */
map.put("braver", 10002);
@@ -514,7 +527,8 @@
testNode(map, 7, 0, 8, 0, 'y');
testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
testNode(map, 9, 0, 10002, 7, Character.MIN_VALUE);
- Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
/* This isn't a word, but we need the test. */
map = new TernaryTree();
@@ -530,8 +544,10 @@
testNode(map, 6, 0, 7, 0, 'r');
testNode(map, 7, 9, 8, 0, 'y');
testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
- testNode(map, 9, 8, 10003, 0, Character.MAX_VALUE);
- Assert.assertEquals("bravery\u0000a\u0000", map.getCompressedKeys());
+ testNode(map, 9, 0, 10003, 1, Character.MAX_VALUE);
+ Assert.assertEquals(2, map.getQtySuffixes());
+ Assert.assertEquals("bravery", map.getSuffix(0));
+ Assert.assertEquals("a", map.getSuffix(1));
}
/**
@@ -547,7 +563,7 @@
testNode(charNodes, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(charNodes, 1, 0, 2, 3, 'O');
testNode(charNodes, 2, 1, 1, 0, Character.MAX_VALUE);
- testNode(charNodes, 3, 4, 2, 0, Character.MAX_VALUE);
+ testNode(charNodes, 3, 0, 2, 1, Character.MAX_VALUE);
final TernaryNodesInt intNodes = charNodes.cloneAsInt();
Assert.assertEquals(4, charNodes.size());
@@ -554,7 +570,7 @@
testNode(intNodes, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(intNodes, 1, 0, 2, 3, 'O');
testNode(intNodes, 2, 1, 1, 0, Character.MAX_VALUE);
- testNode(intNodes, 3, 4, 2, 0, Character.MAX_VALUE);
+ testNode(intNodes, 3, 0, 2, 1, Character.MAX_VALUE);
}
}
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-29 22:49:31
|
Revision: 11555
http://sourceforge.net/p/foray/code/11555
Author: victormote
Date: 2019-03-29 22:49:27 +0000 (Fri, 29 Mar 2019)
Log Message:
-----------
Add exported Eclipse-specific resources.
Modified Paths:
--------------
trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml
Added Paths:
-----------
trunk/foray/master/ide/eclipse/code-templates/
trunk/foray/master/ide/eclipse/code-templates/FOray-codetemplates.xml
trunk/foray/master/ide/eclipse/launch-configurations/PatternSerializer.launch
Added: trunk/foray/master/ide/eclipse/code-templates/FOray-codetemplates.xml
===================================================================
--- trunk/foray/master/ide/eclipse/code-templates/FOray-codetemplates.xml (rev 0)
+++ trunk/foray/master/ide/eclipse/code-templates/FOray-codetemplates.xml 2019-03-29 22:49:27 UTC (rev 11555)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><templates><template autoinsert="true" context="gettercomment_context" deleted="false" description="Comment for getter method" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name="gettercomment">/**
+ * @return the ${bare_field_name}
+ */</template><template autoinsert="true" context="settercomment_context" deleted="false" description="Comment for setter method" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.settercomment" name="settercomment">/**
+ * @param ${param} the ${bare_field_name} to set
+ */</template><template autoinsert="true" context="constructorcomment_context" deleted="false" description="Comment for created constructors" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name="constructorcomment">/**
+ * ${tags}
+ */</template><template autoinsert="true" context="filecomment_context" deleted="false" description="Comment for created Java files" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.filecomment" name="filecomment">/**
+ *
+ */</template><template autoinsert="false" context="typecomment_context" deleted="false" description="Comment for created types" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.typecomment" name="typecomment">/**
+ * ${tags}
+ */</template><template autoinsert="true" context="fieldcomment_context" deleted="false" description="Comment for fields" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name="fieldcomment">/**
+ *
+ */</template><template autoinsert="true" context="methodcomment_context" deleted="false" description="Comment for non-overriding methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name="methodcomment">/**
+ * ${tags}
+ */</template><template autoinsert="true" context="overridecomment_context" deleted="false" description="Comment for overriding methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name="overridecomment">/* (non-Javadoc)
+ * ${see_to_overridden}
+ */</template><template autoinsert="true" context="delegatecomment_context" deleted="false" description="Comment for delegate methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name="delegatecomment">/**
+ * ${tags}
+ * ${see_to_target}
+ */</template><template autoinsert="true" context="newtype_context" deleted="false" description="Newly created files" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.newtype" name="newtype">${filecomment}
+${package_declaration}
+
+${typecomment}
+${type_declaration}</template><template autoinsert="true" context="classbody_context" deleted="false" description="Code in new class type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.classbody" name="classbody">
+</template><template autoinsert="true" context="interfacebody_context" deleted="false" description="Code in new interface type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name="interfacebody">
+</template><template autoinsert="true" context="enumbody_context" deleted="false" description="Code in new enum type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.enumbody" name="enumbody">
+</template><template autoinsert="true" context="annotationbody_context" deleted="false" description="Code in new annotation type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name="annotationbody">
+</template><template autoinsert="true" context="catchblock_context" deleted="false" description="Code in new catch blocks" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.catchblock" name="catchblock">// ${todo} Auto-generated catch block
+${exception_var}.printStackTrace();</template><template autoinsert="true" context="methodbody_context" deleted="false" description="Code in created method stubs" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.methodbody" name="methodbody">// ${todo} Auto-generated method stub
+${body_statement}</template><template autoinsert="true" context="constructorbody_context" deleted="false" description="Code in created constructor stubs" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name="constructorbody">${body_statement}
+// ${todo} Auto-generated constructor stub</template><template autoinsert="true" context="getterbody_context" deleted="false" description="Code in created getters" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.getterbody" name="getterbody">return ${field};</template><template autoinsert="true" context="setterbody_context" deleted="false" description="Code in created setters" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.setterbody" name="setterbody">${field} = ${param};</template></templates>
\ No newline at end of file
Modified: trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml
===================================================================
--- trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml 2019-03-29 14:41:48 UTC (rev 11554)
+++ trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml 2019-03-29 22:49:27 UTC (rev 11555)
@@ -14,11 +14,11 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
@@ -41,7 +41,7 @@
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
@@ -71,7 +71,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
@@ -176,7 +176,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
Added: trunk/foray/master/ide/eclipse/launch-configurations/PatternSerializer.launch
===================================================================
--- trunk/foray/master/ide/eclipse/launch-configurations/PatternSerializer.launch (rev 0)
+++ trunk/foray/master/ide/eclipse/launch-configurations/PatternSerializer.launch 2019-03-29 22:49:27 UTC (rev 11555)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/foray-hyphen/src/main/java/org/foray/hyphen/PatternSerializer.java"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.buildship.core.classpathprovider"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.foray.hyphen.PatternSerializer"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--input ${project_loc}/../foray-hyphen/src/main/data/hyph-patterns --output ${project_loc}/../foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns --pattern ".*\.xml""/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="foray-hyphen"/>
+</launchConfiguration>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-29 14:42:03
|
Revision: 11554
http://sourceforge.net/p/foray/code/11554
Author: victormote
Date: 2019-03-29 14:41:48 +0000 (Fri, 29 Mar 2019)
Log Message:
-----------
Add parent information to Node, if provided.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-28 23:54:18 UTC (rev 11553)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-29 14:41:48 UTC (rev 11554)
@@ -106,6 +106,10 @@
*/
public class Node {
+ /** Format string for {@link #toString()}. */
+ private static final String TO_STRING_FORMAT =
+ "index: %5d, low: %5d, equal: %5d, high: %5d, key: %4x %s, parent: %5d";
+
/** The index for this node. */
private int index;
@@ -121,16 +125,23 @@
/** The keyChar for this node. */
private char keyChar;
+ /** The index to the parent of this node. */
+ private int parent = -1;
+
/**
* Constructor.
* @param index The index for which a notional nodes is wanted.
+ * @param withParents The {@link TernaryNodes.WithParents} instance. This can be null.
*/
- public Node(final int index) {
+ public Node(final int index, final WithParents withParents) {
this.index = index;
this.low = TernaryNodes.this.getLow(index);
this.equal = TernaryNodes.this.getEqual(index);
this.high = TernaryNodes.this.getHigh(index);
this.keyChar = TernaryNodes.this.getKeyChar(index);
+ if (withParents != null) {
+ this.parent = withParents.getParent(index);
+ }
}
/**
@@ -173,6 +184,14 @@
return this.keyChar;
}
+ /**
+ * Returns the index to the parent node, if known.
+ * @return The high.
+ */
+ public int getParent() {
+ return this.parent;
+ }
+
@Override
public String toString() {
char printableChar = this.keyChar;
@@ -180,8 +199,8 @@
|| printableChar == Character.MAX_VALUE) {
printableChar = ' ';
}
- return String.format("index: %5d, low: %5d, equal: %5d, high: %5d, key: %4x %s",
- this.index, this.low, this.equal, this.high, (int) this.keyChar, printableChar);
+ return String.format(TO_STRING_FORMAT,
+ this.index, this.low, this.equal, this.high, (int) this.keyChar, printableChar, this.parent);
}
@Override
@@ -288,7 +307,7 @@
this.currentBranchStack.pop();
}
- return new Node(returnValue);
+ return new Node(returnValue, null);
}
@Override
@@ -567,10 +586,11 @@
* Use the getters and setters for ordinary processing.
* It is expected that this method should be used ONLY for testing and iteration.
* @param index The index to the node.
+ * @param withParents An optional {@link TernaryNodes.WithParents}. This can be null.
* @return A new Node instance containing the data for the reqested node.
*/
- Node createNotionalNode(final int index) {
- return new Node(index);
+ Node createNotionalNode(final int index, final WithParents withParents) {
+ return new Node(index, withParents);
}
/**
@@ -694,8 +714,14 @@
* Useful for tests.
*/
public void dumpTree() {
+ WithParents withParents = null;
+ try {
+ withParents = withParents();
+ } catch (final InconsistentTreeException e) {
+ this.logger.error("Inconsistent Tree", e);
+ }
for (int index = 0; index < size(); index ++) {
- final Node node = createNotionalNode(index);
+ final Node node = createNotionalNode(index, withParents);
this.logger.info(node.toString());
}
this.logger.info("-----------------------------------------------------------------------------------------");
@@ -805,19 +831,32 @@
/**
* Indicates whether the state of the nodes is consistent.
* This is useful mostly for testing.
- * @return True if and only if there are no known inconsistencies in the node.s
+ * @return True if and only if there are no known inconsistencies in the nodes.
*/
public boolean isConsistent() {
+ for (int index = 0; index < size(); index ++) {
+ if (getLowPointer(index) < 0) {
+ this.logger.error("Low Pointer out of range: {}", getLowPointer(0));
+ return false;
+ }
+ if (getEqualPointer(index) < 0) {
+ this.logger.error("Equal Pointer out of range: {}", getEqualPointer(0));
+ return false;
+ }
+ if (getHighPointer(index) < 0) {
+ this.logger.error("High Pointer out of range: {}", getHighPointer(0));
+ return false;
+ }
+ }
/* For now, most of the testing is done with the WithParents class. Just create an instance of it and catch
* Exceptions thrown by it. */
- boolean isConsistent = true;
try {
this.withParents();
} catch (final InconsistentTreeException e) {
this.logger.error("", e);
- isConsistent = false;
+ return false;
}
- return isConsistent;
+ return true;
}
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-28 23:54:18 UTC (rev 11553)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-29 14:41:48 UTC (rev 11554)
@@ -258,7 +258,7 @@
*/
private void testNode(final TernaryTree map, final int index, final int expectedLow, final int expectedEqual,
final int expectedHigh, final char expectedKeyChar) {
- final TernaryNodes.Node node = map.getNodes().createNotionalNode(index);
+ final TernaryNodes.Node node = map.getNodes().createNotionalNode(index, null);
Assert.assertEquals(index, node.getIndex());
Assert.assertEquals(expectedLow, node.getLow());
Assert.assertEquals(expectedEqual, node.getEqual());
@@ -277,7 +277,7 @@
*/
private void testNode(final TernaryNodes nodes, final int index, final int expectedLow, final int expectedEqual,
final int expectedHigh, final char expectedKeyChar) {
- final TernaryNodes.Node node = nodes.createNotionalNode(index);
+ final TernaryNodes.Node node = nodes.createNotionalNode(index, null);
Assert.assertEquals(index, node.getIndex());
Assert.assertEquals(expectedLow, node.getLow());
Assert.assertEquals(expectedEqual, node.getEqual());
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 23:54:21
|
Revision: 11553
http://sourceforge.net/p/foray/code/11553
Author: victormote
Date: 2019-03-28 23:54:18 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Add logger. Throw a checked exception if the tree is in an inconsistent state.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Added Paths:
-----------
trunk/foray/master/ide/eclipse/launch-configurations/DictionarySerializer.launch
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-28 22:38:26 UTC (rev 11552)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-28 23:54:18 UTC (rev 11553)
@@ -39,7 +39,7 @@
* <p>Interface for data structures that hold the tree data for a {@link TernaryTree}.</p>
*
* <p>We use four arrays of equal size to represent the nodes in this tree.
- * A given node /n/ is represented by the values in the arrays lo, hi, eq, and keyChar.
+ * A given node /n/ is represented by the values in the arrays low, high, equal, and keyChar.
* It is tempting to group these four arrays into a private inner class, and the original author of this class left
* documentation kind of apologizing for not doing so.
* However, experimentation shows that the extra object references created when doing so more than double the size
@@ -58,6 +58,9 @@
/** Constant needed for serialization. */
private static final long serialVersionUID = 2866689417641820196L;
+ /** The logger. */
+ private transient Logger logger = LoggerFactory.getLogger(this.getClass());
+
/**
* Enumeration of the valid node types.
*/
@@ -74,6 +77,30 @@
}
/**
+ * Exception class that can be used to report a consistency problem in the tree.
+ */
+ public class InconsistentTreeException extends Exception {
+
+ /** Constant needed for serialization. */
+ private static final long serialVersionUID = -7811983575599941811L;
+
+ /**
+ * See superclass doc.
+ */
+ public InconsistentTreeException() {
+ super();
+ }
+
+ /**
+ * See superclass doc.
+ * @param message The message for the exception.
+ */
+ public InconsistentTreeException(final String message) {
+ super(message);
+ }
+ }
+
+ /**
* A notional Node for {@link TernaryNodes}, useful mostly for iterators and debugging.
* Instances of this class are expected to be short-lived and used only for those purposes.
*/
@@ -284,9 +311,10 @@
/**
* Constructor.
* Finds the parent for each node.
+ * @throws InconsistentTreeException If problems in the current state of the tree are found.
*/
- public WithParents() {
- final String format = "Index %d, referenced from Index %d, already has parent Index %d";
+ public WithParents() throws InconsistentTreeException {
+ final String multipleParentFormat = "Index %d, referenced from Index %d, already has parent Index %d";
/* Start at index 1. Index 0 doesn't point anywhere. */
for (int index = 1; index < this.parents.length; index++) {
final int lowPointer = TernaryNodes.this.getLowPointer(index);
@@ -294,8 +322,8 @@
if (this.parents[lowPointer] == 0) {
this.parents[lowPointer] = index;
} else {
- throw new IllegalStateException(
- String.format(format, lowPointer, index, this.parents[lowPointer]));
+ throw new InconsistentTreeException(
+ String.format(multipleParentFormat, lowPointer, index, this.parents[lowPointer]));
}
}
final int equalPointer = TernaryNodes.this.getEqualPointer(index);
@@ -303,8 +331,8 @@
if (this.parents[equalPointer] == 0) {
this.parents[equalPointer] = index;
} else {
- throw new IllegalStateException(
- String.format(format, equalPointer, index, this.parents[equalPointer]));
+ throw new InconsistentTreeException(
+ String.format(multipleParentFormat, equalPointer, index, this.parents[equalPointer]));
}
}
final int highPointer = TernaryNodes.this.getHighPointer(index);
@@ -312,8 +340,8 @@
if (this.parents[highPointer] == 0) {
this.parents[highPointer] = index;
} else {
- throw new IllegalStateException(
- String.format(format, highPointer, index, this.parents[highPointer]));
+ throw new InconsistentTreeException(
+ String.format(multipleParentFormat, highPointer, index, this.parents[highPointer]));
}
}
}
@@ -320,21 +348,17 @@
/* Nodes 0 and 1 should not have parents... */
if (parents[0] != 0) {
- throw new IllegalStateException("Index 0 should have no parent.");
+ throw new InconsistentTreeException("Index 0 should have no parent.");
}
if (parents[1] != 0) {
- throw new IllegalStateException("Index 1 should have no parent.");
+ throw new InconsistentTreeException("Index 1 should have no parent.");
}
/* ... but everybody else should, unless they are orphaned. */
- Logger logger = null;
int start = -1;
int end = -1;
for (int index = 2; index < this.parents.length; index ++) {
if (parents[index] == 0) {
- if (logger == null) {
- logger = LoggerFactory.getLogger(this.getClass());
- }
if (start < 0) {
start = index;
end = index;
@@ -341,21 +365,22 @@
} else if (index == end + 1) {
end = index;
} else if (start == end) {
- logger.info("Index " + start + " has no parent.");
- start = index;
- end = index;
+ throw new InconsistentTreeException("Index " + start + " has no parent.");
+// start = index;
+// end = index;
} else {
- logger.info("Indexes " + start + " through " + end + " have no parent.");
- start = index;
- end = index;
+ throw new InconsistentTreeException(
+ "Indexes " + start + " through " + end + " have no parent.");
+// start = index;
+// end = index;
}
}
}
if (start > -1) {
if (start == end) {
- logger.info("Index " + start + " has no parent.");
+ throw new InconsistentTreeException("Index " + start + " has no parent.");
} else {
- logger.info("Indexes " + start + " through " + end + " have no parent.");
+ throw new InconsistentTreeException("Indexes " + start + " through " + end + " have no parent.");
}
}
@@ -669,12 +694,11 @@
* Useful for tests.
*/
public void dumpTree() {
- final Logger logger = LoggerFactory.getLogger(this.getClass());
for (int index = 0; index < size(); index ++) {
final Node node = createNotionalNode(index);
- logger.info(node.toString());
+ this.logger.info(node.toString());
}
- logger.info("-----------------------------------------------------------------------------------------");
+ this.logger.info("-----------------------------------------------------------------------------------------");
}
/**
@@ -726,8 +750,9 @@
/**
* Returns an object containing the parents for each node in this instance.
* @return The parents.
+ * @throws InconsistentTreeException If exceptions are found while walking the tree.
*/
- public WithParents withParents() {
+ public WithParents withParents() throws InconsistentTreeException {
return new WithParents();
}
@@ -777,4 +802,22 @@
}
}
+ /**
+ * Indicates whether the state of the nodes is consistent.
+ * This is useful mostly for testing.
+ * @return True if and only if there are no known inconsistencies in the node.s
+ */
+ public boolean isConsistent() {
+ /* For now, most of the testing is done with the WithParents class. Just create an instance of it and catch
+ * Exceptions thrown by it. */
+ boolean isConsistent = true;
+ try {
+ this.withParents();
+ } catch (final InconsistentTreeException e) {
+ this.logger.error("", e);
+ isConsistent = false;
+ }
+ return isConsistent;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-28 22:38:26 UTC (rev 11552)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-28 23:54:18 UTC (rev 11553)
@@ -234,11 +234,18 @@
public void put(final CharSequence key, final int start, final int end, final int value) {
final int newCapacity = this.nodes.size() + end - start + 1;
this.nodes.ensureCapacity(newCapacity);
+
if (start == 0) {
this.logger.debug(key.toString());
}
put(this.nodes.getRootNodeIndex(), key, start, end, value);
+
+ if (this.logger.isDebugEnabled()) {
+ if (! this.nodes.isConsistent()) {
+ throw new IllegalStateException("Tree is in an inconsistent state. See the log for details.");
+ }
+ }
}
/**
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-28 22:38:26 UTC (rev 11552)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-28 23:54:18 UTC (rev 11553)
@@ -28,6 +28,8 @@
package org.foray.common.data;
+import org.foray.common.data.TernaryNodes.InconsistentTreeException;
+
import org.junit.Assert;
import org.junit.Test;
@@ -335,10 +337,11 @@
/**
* Test of {@link TernaryNodes#findCharNode(int, char)}.
+ * @throws InconsistentTreeException Not expected here.
*/
@SuppressWarnings("javadoc")
@Test
- public void testFindCharNode() {
+ public void testFindCharNode() throws InconsistentTreeException {
final TernaryTree map = new TernaryTree();
map.put("bread", 1001);
map.put("brave", 1002);
Added: trunk/foray/master/ide/eclipse/launch-configurations/DictionarySerializer.launch
===================================================================
--- trunk/foray/master/ide/eclipse/launch-configurations/DictionarySerializer.launch (rev 0)
+++ trunk/foray/master/ide/eclipse/launch-configurations/DictionarySerializer.launch 2019-03-28 23:54:18 UTC (rev 11553)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/foray-hyphen/src/main/java/org/foray/hyphen/DictionarySerializer.java"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
+<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6/" javaProject="foray-hyphen" path="1" type="4"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="foray-hyphen"/> </runtimeClasspathEntry> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.USER_LIBRARY/logback" path="3" type="4"/> "/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.buildship.core.classpathprovider"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.foray.hyphen.DictionarySerializer"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--input ${project_loc}/src/main/data/word-lists --output ${project_loc}/src/main/resources/resources/org/foray/dictionaries --pattern "eng-word-list-moby.txt""/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="foray-hyphen"/>
+</launchConfiguration>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 22:38:29
|
Revision: 11552
http://sourceforge.net/p/foray/code/11552
Author: victormote
Date: 2019-03-28 22:38:26 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Fix some checkstyle complaints.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/para/DiscretionaryHyphen4a.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/Interword4a.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/para/DiscretionaryHyphen4a.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/para/DiscretionaryHyphen4a.java 2019-03-28 22:36:22 UTC (rev 11551)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/para/DiscretionaryHyphen4a.java 2019-03-28 22:38:26 UTC (rev 11552)
@@ -59,7 +59,7 @@
/**
* Protected constructor. There are only 3 possible normal values, so these are pre-constructed.
- * Use {@link #fromQuality(org.axsl.hyphen.HyphenationPoint.Quality)} to obtain an instance of this class.
+ * Use {@link #fromQuality(org.axsl.common.para.DiscretionaryHyphen.Quality)} to obtain an instance of this class.
* @param quality The quality for this instance.
*/
protected DiscretionaryHyphen4a(final DiscretionaryHyphen.Quality quality) {
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/Interword4a.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/Interword4a.java 2019-03-28 22:36:22 UTC (rev 11551)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/Interword4a.java 2019-03-28 22:38:26 UTC (rev 11552)
@@ -31,6 +31,8 @@
import org.foray.common.para.ParaBoxChars;
import org.foray.common.para.ParaGlueChars;
import org.foray.common.primitive.CharSequenceUtils;
+import org.foray.common.primitive.CharacterUtils;
+import org.foray.common.primitive.StringUtils;
import org.axsl.common.para.ParaBranch;
import org.axsl.common.para.ParaConfig;
@@ -82,7 +84,7 @@
/** Common interword item. TODO: This needs to be treated differently. */
private static final Interword4a APOSTROPHE = new Interword4a(new ParaLeaf[] {
- new ParaBoxChars("\x92")
+ new ParaBoxChars(StringUtils.EMPTY_STRING + CharacterUtils.SINGLE_CLOSE_QUOTATION_MARK)
});
/** Common interword item. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 22:36:25
|
Revision: 11551
http://sourceforge.net/p/foray/code/11551
Author: victormote
Date: 2019-03-28 22:36:22 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Upgrade checkstyle version to match version used by Eclipse.
Modified Paths:
--------------
trunk/foray/master/build.gradle
Modified: trunk/foray/master/build.gradle
===================================================================
--- trunk/foray/master/build.gradle 2019-03-28 21:36:17 UTC (rev 11550)
+++ trunk/foray/master/build.gradle 2019-03-28 22:36:22 UTC (rev 11551)
@@ -43,6 +43,7 @@
ext.junitVersion = '4.12'
ext.mockitoVersion = '2.25.1'
ext.logbackClassicVersion = '1.0.13'
+ ext.checkstyleVersion = '8.18'
}
subprojects {
@@ -57,7 +58,7 @@
checkstyle {
configFile = new File(rootProject.projectDir.absolutePath + '/config/checkstyle/checkstyle-config.xml')
configProperties.put('foray.root', rootProject.projectDir)
- toolVersion = "8.17"
+ toolVersion = checkstyleVersion
}
tasks.withType(JavaCompile) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 21:36:20
|
Revision: 11550
http://sourceforge.net/p/foray/code/11550
Author: victormote
Date: 2019-03-28 21:36:17 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Add eclipse-specific formatting helps.
Added Paths:
-----------
trunk/foray/master/ide/eclipse/formatters/
trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml
trunk/foray/master/ide/eclipse/import-organizers/
trunk/foray/master/ide/eclipse/import-organizers/FOray.importorder
Added: trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml
===================================================================
--- trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml (rev 0)
+++ trunk/foray/master/ide/eclipse/formatters/FOray-formatter.xml 2019-03-28 21:36:17 UTC (rev 11550)
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="15">
+<profile kind="CodeFormatterProfile" name="FOray" version="15">
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+</profile>
+</profiles>
Added: trunk/foray/master/ide/eclipse/import-organizers/FOray.importorder
===================================================================
--- trunk/foray/master/ide/eclipse/import-organizers/FOray.importorder (rev 0)
+++ trunk/foray/master/ide/eclipse/import-organizers/FOray.importorder 2019-03-28 21:36:17 UTC (rev 11550)
@@ -0,0 +1,8 @@
+#Organize Import Order
+#Thu Mar 28 15:10:21 MDT 2019
+5=javax
+4=java
+3=com
+2=org
+1=org.axsl
+0=org.foray
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 21:34:42
|
Revision: 11549
http://sourceforge.net/p/foray/code/11549
Author: victormote
Date: 2019-03-28 21:34:37 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Use the gradle wrapper instead of gradle directly.
Added Paths:
-----------
trunk/foray/master/gradle/
trunk/foray/master/gradle/wrapper/
trunk/foray/master/gradle/wrapper/gradle-wrapper.jar
trunk/foray/master/gradle/wrapper/gradle-wrapper.properties
trunk/foray/master/gradlew
trunk/foray/master/gradlew.bat
Added: trunk/foray/master/gradle/wrapper/gradle-wrapper.jar
===================================================================
(Binary files differ)
Index: trunk/foray/master/gradle/wrapper/gradle-wrapper.jar
===================================================================
--- trunk/foray/master/gradle/wrapper/gradle-wrapper.jar 2019-03-28 21:13:28 UTC (rev 11548)
+++ trunk/foray/master/gradle/wrapper/gradle-wrapper.jar 2019-03-28 21:34:37 UTC (rev 11549)
Property changes on: trunk/foray/master/gradle/wrapper/gradle-wrapper.jar
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/foray/master/gradle/wrapper/gradle-wrapper.properties
===================================================================
--- trunk/foray/master/gradle/wrapper/gradle-wrapper.properties (rev 0)
+++ trunk/foray/master/gradle/wrapper/gradle-wrapper.properties 2019-03-28 21:34:37 UTC (rev 11549)
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
Added: trunk/foray/master/gradlew
===================================================================
--- trunk/foray/master/gradlew (rev 0)
+++ trunk/foray/master/gradlew 2019-03-28 21:34:37 UTC (rev 11549)
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
Added: trunk/foray/master/gradlew.bat
===================================================================
--- trunk/foray/master/gradlew.bat (rev 0)
+++ trunk/foray/master/gradlew.bat 2019-03-28 21:34:37 UTC (rev 11549)
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-28 21:20:21
|
Revision: 11548
http://sourceforge.net/p/foray/code/11548
Author: victormote
Date: 2019-03-28 21:13:28 +0000 (Thu, 28 Mar 2019)
Log Message:
-----------
Upgrade checkstyle DTD.
Modified Paths:
--------------
trunk/foray/master/config/checkstyle/checkstyle-config.xml
Modified: trunk/foray/master/config/checkstyle/checkstyle-config.xml
===================================================================
--- trunk/foray/master/config/checkstyle/checkstyle-config.xml 2019-03-27 17:38:27 UTC (rev 11547)
+++ trunk/foray/master/config/checkstyle/checkstyle-config.xml 2019-03-28 21:13:28 UTC (rev 11548)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module
- PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
- "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+ PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+ "https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
This is the checkstyle configuration for FOray.
@@ -231,7 +231,7 @@
<module name="IllegalType">
<!-- Turn off the restriction on Abstract classes. -->
- <property name="format" value="^ZZZZZZ$"/>
+ <property name="illegalAbstractClassNameFormat" value="^ZZZZZZ$"/>
</module>
<!-- Checks for complexity. -->
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-27 17:38:42
|
Revision: 11547
http://sourceforge.net/p/foray/code/11547
Author: victormote
Date: 2019-03-27 17:38:27 +0000 (Wed, 27 Mar 2019)
Log Message:
-----------
Add some code to help with testing.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-26 16:11:02 UTC (rev 11546)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-27 17:38:27 UTC (rev 11547)
@@ -286,20 +286,35 @@
* Finds the parent for each node.
*/
public WithParents() {
- final Iterator<TernaryNodes.Node> iterator = TernaryNodes.this.nodeIterator();
- while (iterator.hasNext()) {
- final TernaryNodes.Node node = iterator.next();
- final int lowPointer = TernaryNodes.this.getLowPointer(node.index);
+ final String format = "Index %d, referenced from Index %d, already has parent Index %d";
+ /* Start at index 1. Index 0 doesn't point anywhere. */
+ for (int index = 1; index < this.parents.length; index++) {
+ final int lowPointer = TernaryNodes.this.getLowPointer(index);
if (lowPointer != 0) {
- this.parents[lowPointer] = node.index;
+ if (this.parents[lowPointer] == 0) {
+ this.parents[lowPointer] = index;
+ } else {
+ throw new IllegalStateException(
+ String.format(format, lowPointer, index, this.parents[lowPointer]));
+ }
}
- final int equalPointer = TernaryNodes.this.getEqualPointer(node.index);
+ final int equalPointer = TernaryNodes.this.getEqualPointer(index);
if (equalPointer != 0) {
- this.parents[equalPointer] = node.index;
+ if (this.parents[equalPointer] == 0) {
+ this.parents[equalPointer] = index;
+ } else {
+ throw new IllegalStateException(
+ String.format(format, equalPointer, index, this.parents[equalPointer]));
+ }
}
- final int highPointer = TernaryNodes.this.getHighPointer(node.index);
+ final int highPointer = TernaryNodes.this.getHighPointer(index);
if (highPointer != 0) {
- this.parents[highPointer] = node.index;
+ if (this.parents[highPointer] == 0) {
+ this.parents[highPointer] = index;
+ } else {
+ throw new IllegalStateException(
+ String.format(format, highPointer, index, this.parents[highPointer]));
+ }
}
}
@@ -311,12 +326,39 @@
throw new IllegalStateException("Index 1 should have no parent.");
}
- /* ... but everybody else must. */
+ /* ... but everybody else should, unless they are orphaned. */
+ Logger logger = null;
+ int start = -1;
+ int end = -1;
for (int index = 2; index < this.parents.length; index ++) {
if (parents[index] == 0) {
- throw new IllegalStateException("Index " + index + " must have a parent.");
+ if (logger == null) {
+ logger = LoggerFactory.getLogger(this.getClass());
+ }
+ if (start < 0) {
+ start = index;
+ end = index;
+ } else if (index == end + 1) {
+ end = index;
+ } else if (start == end) {
+ logger.info("Index " + start + " has no parent.");
+ start = index;
+ end = index;
+ } else {
+ logger.info("Indexes " + start + " through " + end + " have no parent.");
+ start = index;
+ end = index;
+ }
}
}
+ if (start > -1) {
+ if (start == end) {
+ logger.info("Index " + start + " has no parent.");
+ } else {
+ logger.info("Indexes " + start + " through " + end + " have no parent.");
+ }
+
+ }
}
/**
@@ -484,7 +526,7 @@
* Packs the arrays to their current size, i.e. removes any unused array elements..
*/
public void pack() {
- resizeIndexes(this.freenode);
+ resize(this.freenode);
}
/**
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-26 16:11:02 UTC (rev 11546)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-27 17:38:27 UTC (rev 11547)
@@ -36,6 +36,7 @@
import org.foray.common.primitive.CharSequenceUtils;
import org.foray.common.primitive.StringUtils;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
@@ -112,6 +113,9 @@
/** Constant used for serialization. */
private static final long serialVersionUID = 240904407206584695L;
+ /** The logger. */
+ private transient Logger logger = LoggerFactory.getLogger(this.getClass());
+
/** The data structure containing the branch indexes. */
private TernaryNodes nodes;
@@ -161,7 +165,7 @@
if (this.nodes instanceof TernaryNodesChar) {
final TernaryNodesChar oldNodes = (TernaryNodesChar) this.nodes;
this.nodes = oldNodes.cloneAsInt();
- LoggerFactory.getLogger(this.getClass()).info("Switched to TernaryNodesInt for greater capacity.");
+ this.logger.info("Switched to TernaryNodesInt for greater capacity.");
} else {
throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
+ this.nodes.getMaximumCapacity());
@@ -230,6 +234,10 @@
public void put(final CharSequence key, final int start, final int end, final int value) {
final int newCapacity = this.nodes.size() + end - start + 1;
this.nodes.ensureCapacity(newCapacity);
+ if (start == 0) {
+ this.logger.debug(key.toString());
+ }
+
put(this.nodes.getRootNodeIndex(), key, start, end, value);
}
@@ -904,4 +912,20 @@
return builder.toString();
}
+ /**
+ * For a given index, recovers its key, then iteratively recovers its parent keys until it reaches the root.
+ * @param withParents The nodes, along with their parents, needed to recover the keys.
+ * @param index The starting index.
+ */
+ public void dumpKeyPath(final TernaryNodes.WithParents withParents, final int index) {
+ final String format = "Index: %6d, Key: %s";
+ int nextIndex = index;
+ while (nextIndex > 0) {
+ final String key = this.recoverKey(withParents, nextIndex);
+ final String message = String.format(format, nextIndex, key);
+ logger.info(message);
+ nextIndex = withParents.getParent(nextIndex);
+ }
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-26 16:11:07
|
Revision: 11546
http://sourceforge.net/p/foray/code/11546
Author: victormote
Date: 2019-03-26 16:11:02 +0000 (Tue, 26 Mar 2019)
Log Message:
-----------
Make TernaryTreeMap serializable.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-25 20:05:05 UTC (rev 11545)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-26 16:11:02 UTC (rev 11546)
@@ -28,6 +28,7 @@
package org.foray.common.data;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -41,8 +42,11 @@
* <p>This map implementation does not support either null keys or null values.</p>
* @param <V> The type of the values stored in this map.
*/
-public class TernaryTreeMap<V> implements Map<CharSequence, V> {
+public class TernaryTreeMap<V> implements Map<CharSequence, V>, Serializable {
+ /** Constant needed for serialization. */
+ private static final long serialVersionUID = -8265259201598682447L;
+
/** Ternary tree containing the keys, i.e. the indexes into {@link #values}. */
private TernaryTree keys;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-25 20:05:18
|
Revision: 11545
http://sourceforge.net/p/foray/code/11545
Author: victormote
Date: 2019-03-25 20:05:05 +0000 (Mon, 25 Mar 2019)
Log Message:
-----------
Add inner class that provides parent node information. Add method to TernaryTree that uses the parent information to reconstruct the key.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-25 16:41:50 UTC (rev 11544)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-25 20:05:05 UTC (rev 11545)
@@ -228,31 +228,15 @@
int branchIndex = -1;
switch (this.currentBranchStack.peek()) {
case -1: {
- if (TernaryNodes.this.isCompressedValueNode(currentIndex)) {
- /* The low branch stores a value, not a node pointer. */
- branchIndex = 0;
- } else {
- branchIndex = TernaryNodes.this.getLow(currentIndex);
- }
+ branchIndex = TernaryNodes.this.getLowPointer(currentIndex);
break;
}
case 0: {
- if (TernaryNodes.this.isUncompressedValueNode(currentIndex)
- || TernaryNodes.this.isCompressedValueNode(currentIndex)) {
- /* The equal branch stores a value, not a node pointer. */
- branchIndex = 0;
- } else {
- branchIndex = TernaryNodes.this.getEqual(currentIndex);
- }
+ branchIndex = TernaryNodes.this.getEqualPointer(currentIndex);
break;
}
case 1: {
- if (TernaryNodes.this.isCompressedValueNode(currentIndex)) {
- /* The high branch does not store a value. */
- branchIndex = 0;
- } else {
- branchIndex = TernaryNodes.this.getHigh(currentIndex);
- }
+ branchIndex = TernaryNodes.this.getHighPointer(currentIndex);
break;
}
default: {
@@ -287,6 +271,65 @@
}
+ /**
+ * Sister class for {@link TernaryNodes} that provides the parent for each node in that tree.
+ * This is probably only useful for debugging, as we would ordinarily not want to spend the memory to keep track of
+ * the parent node.
+ */
+ public class WithParents {
+
+ /** The array of parent values. */
+ private int[] parents = new int[TernaryNodes.this.size()];
+
+ /**
+ * Constructor.
+ * Finds the parent for each node.
+ */
+ public WithParents() {
+ final Iterator<TernaryNodes.Node> iterator = TernaryNodes.this.nodeIterator();
+ while (iterator.hasNext()) {
+ final TernaryNodes.Node node = iterator.next();
+ final int lowPointer = TernaryNodes.this.getLowPointer(node.index);
+ if (lowPointer != 0) {
+ this.parents[lowPointer] = node.index;
+ }
+ final int equalPointer = TernaryNodes.this.getEqualPointer(node.index);
+ if (equalPointer != 0) {
+ this.parents[equalPointer] = node.index;
+ }
+ final int highPointer = TernaryNodes.this.getHighPointer(node.index);
+ if (highPointer != 0) {
+ this.parents[highPointer] = node.index;
+ }
+ }
+
+ /* Nodes 0 and 1 should not have parents... */
+ if (parents[0] != 0) {
+ throw new IllegalStateException("Index 0 should have no parent.");
+ }
+ if (parents[1] != 0) {
+ throw new IllegalStateException("Index 1 should have no parent.");
+ }
+
+ /* ... but everybody else must. */
+ for (int index = 2; index < this.parents.length; index ++) {
+ if (parents[index] == 0) {
+ throw new IllegalStateException("Index " + index + " must have a parent.");
+ }
+ }
+ }
+
+ /**
+ * Returns the parent index for a given index.
+ * @param index The index of the child whose parent should be returned.
+ * @return The index to the parent of the child at {@code index}.
+ */
+ public int getParent(final int index) {
+ return this.parents[index];
+ }
+
+ }
+
/** The index to the next available node. */
private int freenode;
@@ -502,6 +545,15 @@
}
/**
+ * Indicates whether a given node is a char node, i.e. a node whose char key value is a character.
+ * @param index The index of the node to be tested.
+ * @return True if and only if the node is an uncompressed node matching the {@code theChar}.
+ */
+ boolean isCharNode(final int index) {
+ return getNodeType(index) == NodeType.CHARACTER;
+ }
+
+ /**
* Indicates whether a given node has a key value equal to a specified char.
* @param index The index of the node to be tested.
* @param theChar The character being sought in the tree.
@@ -629,4 +681,58 @@
return new DepthFirstIterator();
}
+ /**
+ * Returns an object containing the parents for each node in this instance.
+ * @return The parents.
+ */
+ public WithParents withParents() {
+ return new WithParents();
+ }
+
+ /**
+ * Returns the index to the low branch, if any.
+ * @param index The index to the node whose low pointer is wanted.
+ * @return If the low value in {@code index} is an index pointing to another node, return that index.
+ * Otherwise, return 0.
+ */
+ public int getLowPointer(final int index) {
+ if (isCompressedValueNode(index)) {
+ /* The low branch stores a value, not a node pointer. */
+ return 0;
+ } else {
+ return getLow(index);
+ }
+ }
+
+ /**
+ * Returns the index to the equal branch, if any.
+ * @param index The index to the node whose equal pointer is wanted.
+ * @return If the equal value in {@code index} is an index pointing to another node, return that index.
+ * Otherwise, return 0.
+ */
+ public int getEqualPointer(final int index) {
+ if (isUncompressedValueNode(index)
+ || isCompressedValueNode(index)) {
+ /* The equal branch stores a value, not a node pointer. */
+ return 0;
+ } else {
+ return getEqual(index);
+ }
+ }
+
+ /**
+ * Returns the index to the high branch, if any.
+ * @param index The index to the node whose high pointer is wanted.
+ * @return If the high value in {@code index} is an index pointing to another node, return that index.
+ * Otherwise, return 0.
+ */
+ public int getHighPointer(final int index) {
+ if (isCompressedValueNode(index)) {
+ /* The high branch does not store a value. */
+ return 0;
+ } else {
+ return getHigh(index);
+ }
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-25 16:41:50 UTC (rev 11544)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-25 20:05:05 UTC (rev 11545)
@@ -874,4 +874,34 @@
return this.compressedKeys.toString();
}
+ /**
+ * Recovers the key to a given node by first finding the parents for each node, then going back up the tree to
+ * reconstruct the String.
+ * @param withParents The nodes, along with their parents, needed to recover the key.
+ * @param index The index whose key is wanted.
+ * @return The String that is the key to {@code index}.
+ */
+ public String recoverKey(final TernaryNodes.WithParents withParents, final int index) {
+ final StringBuilder builder = new StringBuilder();
+ final TernaryNodes nodes = this.getNodes();
+ int currentIndex = index;
+ while (currentIndex > 0) {
+ if (nodes.isCompressedValueNode(currentIndex)) {
+ final int start = nodes.getLow(currentIndex);
+ final int length = StringUtils.nullTerminatedLength(this.compressedKeys, start);
+ builder.insert(0, this.compressedKeys.substring(start, start + length));
+ } else if (nodes.isCharNode(currentIndex)) {
+ builder.insert(0, nodes.getKeyChar(currentIndex));
+ }
+
+ int parentIndex = withParents.getParent(currentIndex);
+ while (currentIndex != nodes.getEqual(parentIndex)) {
+ currentIndex = parentIndex;
+ parentIndex = withParents.getParent(currentIndex);
+ }
+ currentIndex = parentIndex;
+ }
+ return builder.toString();
+ }
+
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-25 16:41:50 UTC (rev 11544)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-25 20:05:05 UTC (rev 11545)
@@ -402,6 +402,36 @@
Assert.assertEquals(12, actual.get(9).getIndex());
Assert.assertEquals(9, actual.get(10).getIndex());
Assert.assertEquals(4, actual.get(11).getIndex());
+
+ /* Test the WithParent. */
+ final TernaryNodes.WithParents withParents = map.getNodes().withParents();
+ Assert.assertEquals(0, withParents.getParent(0));
+ Assert.assertEquals(0, withParents.getParent(1));
+ Assert.assertEquals(1, withParents.getParent(2));
+ Assert.assertEquals(2, withParents.getParent(3));
+ Assert.assertEquals(3, withParents.getParent(4));
+ Assert.assertEquals(3, withParents.getParent(5));
+ Assert.assertEquals(5, withParents.getParent(6));
+ Assert.assertEquals(6, withParents.getParent(7));
+ Assert.assertEquals(7, withParents.getParent(8));
+ Assert.assertEquals(7, withParents.getParent(9));
+ Assert.assertEquals(8, withParents.getParent(10));
+ Assert.assertEquals(10, withParents.getParent(11));
+ Assert.assertEquals(11, withParents.getParent(12));
+
+ Assert.assertEquals("", map.recoverKey(withParents, 0));
+ Assert.assertEquals("b", map.recoverKey(withParents, 1));
+ Assert.assertEquals("br", map.recoverKey(withParents, 2));
+ Assert.assertEquals("bre", map.recoverKey(withParents, 3));
+ Assert.assertEquals("bread", map.recoverKey(withParents, 4));
+ Assert.assertEquals("bra", map.recoverKey(withParents, 5));
+ Assert.assertEquals("brav", map.recoverKey(withParents, 6));
+ Assert.assertEquals("brave", map.recoverKey(withParents, 7));
+ Assert.assertEquals("brave", map.recoverKey(withParents, 8));
+ Assert.assertEquals("bravo", map.recoverKey(withParents, 9));
+ Assert.assertEquals("braver", map.recoverKey(withParents, 10));
+ Assert.assertEquals("braver", map.recoverKey(withParents, 11));
+ Assert.assertEquals("bravery", map.recoverKey(withParents, 12));
}
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-25 16:42:00
|
Revision: 11544
http://sourceforge.net/p/foray/code/11544
Author: victormote
Date: 2019-03-25 16:41:50 +0000 (Mon, 25 Mar 2019)
Log Message:
-----------
Add raw depth-first node iterator.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 21:28:11 UTC (rev 11543)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-25 16:41:50 UTC (rev 11544)
@@ -33,6 +33,7 @@
import java.io.Serializable;
import java.util.Arrays;
+import java.util.Iterator;
/**
* <p>Interface for data structures that hold the tree data for a {@link TernaryTree}.</p>
@@ -94,6 +95,18 @@
private char keyChar;
/**
+ * Constructor.
+ * @param index The index for which a notional nodes is wanted.
+ */
+ public Node(final int index) {
+ this.index = index;
+ this.low = TernaryNodes.this.getLow(index);
+ this.equal = TernaryNodes.this.getEqual(index);
+ this.high = TernaryNodes.this.getHigh(index);
+ this.keyChar = TernaryNodes.this.getKeyChar(index);
+ }
+
+ /**
* Returns the index.
* @return The index.
*/
@@ -164,6 +177,116 @@
}
}
+ /**
+ * Iterates over the nodes in depth-first order, going now first the left branch, then the equal branch, then the
+ * high branch.
+ */
+ public class DepthFirstIterator implements Iterator<TernaryNodes.Node> {
+
+ /** The stack of indexes. Index 1 should be at the bottom of the stack until finished. The current index is at
+ * the top. */
+ private IntArrayBuilder currentIndexStack = new IntArrayBuilder();
+
+ /** Parallel stack to indexStack -- this should always have the same number of element in it as indexStack.
+ * This keeps track of which branch of the related index is being processed.
+ * Low is -1, equal is 0, and high is +1. */
+ private IntArrayBuilder currentBranchStack = new IntArrayBuilder();
+
+ /** The next index to return. */
+ private int nextIndex = Integer.MIN_VALUE;
+
+ /**
+ * Constructor.
+ */
+ public DepthFirstIterator() {
+ if (TernaryNodes.this.size() > 1) {
+ this.currentIndexStack.push(1);
+ this.nextIndex = 1;
+ this.currentBranchStack.push(-1 - 1);
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.nextIndex > -1;
+ }
+
+ @Override
+ public Node next() {
+ final int returnValue = this.nextIndex;
+ this.nextIndex = -1;
+
+ indexLoop:
+ while (this.currentIndexStack.length() > 0
+ && this.nextIndex < 0) {
+ final int currentIndex = this.currentIndexStack.peek();
+ int currentBranch = this.currentBranchStack.pop();
+ currentBranch ++;
+ this.currentBranchStack.push(currentBranch);
+
+ while (currentBranch < 2) {
+ int branchIndex = -1;
+ switch (this.currentBranchStack.peek()) {
+ case -1: {
+ if (TernaryNodes.this.isCompressedValueNode(currentIndex)) {
+ /* The low branch stores a value, not a node pointer. */
+ branchIndex = 0;
+ } else {
+ branchIndex = TernaryNodes.this.getLow(currentIndex);
+ }
+ break;
+ }
+ case 0: {
+ if (TernaryNodes.this.isUncompressedValueNode(currentIndex)
+ || TernaryNodes.this.isCompressedValueNode(currentIndex)) {
+ /* The equal branch stores a value, not a node pointer. */
+ branchIndex = 0;
+ } else {
+ branchIndex = TernaryNodes.this.getEqual(currentIndex);
+ }
+ break;
+ }
+ case 1: {
+ if (TernaryNodes.this.isCompressedValueNode(currentIndex)) {
+ /* The high branch does not store a value. */
+ branchIndex = 0;
+ } else {
+ branchIndex = TernaryNodes.this.getHigh(currentIndex);
+ }
+ break;
+ }
+ default: {
+ throw new IllegalStateException("Unexpected branch value: " + this.currentBranchStack.peek());
+ }
+ }
+ if (branchIndex > 0) {
+ /* Push the found index onto the stack. */
+ this.currentIndexStack.push(branchIndex);
+ this.currentBranchStack.push(-1 - 1);
+ /* The new index is the next item to be processed. */
+ this.nextIndex = branchIndex;
+ break indexLoop;
+ } else {
+ /* Increment the current branch. */
+ currentBranch = this.currentBranchStack.pop() + 1;
+ this.currentBranchStack.push(currentBranch);
+ }
+ }
+ /* We have processed all of the branches on the current index. Pop both stacks. */
+ this.currentIndexStack.pop();
+ this.currentBranchStack.pop();
+ }
+
+ return new Node(returnValue);
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
/** The index to the next available node. */
private int freenode;
@@ -337,13 +460,7 @@
* @return A new Node instance containing the data for the reqested node.
*/
Node createNotionalNode(final int index) {
- final Node node = new Node();
- node.index = index;
- node.low = getLow(index);
- node.equal = getEqual(index);
- node.high = getHigh(index);
- node.keyChar = getKeyChar(index);
- return node;
+ return new Node(index);
}
/**
@@ -504,4 +621,12 @@
}
}
+ /**
+ * Returns a depth-first iterator over all nodes in the tree.
+ * @return A new iterator.
+ */
+ public Iterator<TernaryNodes.Node> nodeIterator() {
+ return new DepthFirstIterator();
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 21:28:11 UTC (rev 11543)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-25 16:41:50 UTC (rev 11544)
@@ -336,7 +336,7 @@
* keeping the existing node pointing to the first character in the previously-compressed node.
* @param nodeIndex The index to the node that should be uncompressed.
*/
- private void uncompressNode(final int nodeIndex) {
+ void uncompressNode(final int nodeIndex) {
if (this.nodes.getKeyChar(nodeIndex) != Character.MAX_VALUE) {
throw new IllegalStateException("Trying to uncompress a node that is not compressed.");
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 21:28:11 UTC (rev 11543)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-25 16:41:50 UTC (rev 11544)
@@ -340,26 +340,26 @@
@Test
public void testFindCharNode() {
final TernaryTree map = new TernaryTree();
- map.put("bread", 1);
- map.put("brave", 2);
- map.put("bravo", 3);
- map.put("braver", 4);
- map.put("bravery", 5);
+ map.put("bread", 1001);
+ map.put("brave", 1002);
+ map.put("bravo", 1003);
+ map.put("braver", 1004);
+ map.put("bravery", 1005);
Assert.assertEquals(13, map.getNodes().size());
- testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
- testNode(map, 1, 0, 2, 0, 'b');
- testNode(map, 2, 0, 3, 0, 'r');
- testNode(map, 3, 5, 4, 0, 'e');
- testNode(map, 4, 3, 1, 0, Character.MAX_VALUE);
- testNode(map, 5, 0, 6, 0, 'a');
- testNode(map, 6, 0, 7, 0, 'v');
- testNode(map, 7, 0, 8, 9, 'e');
- testNode(map, 8, 0, 2, 10, Character.MIN_VALUE);
- testNode(map, 9, 10, 3, 0, Character.MAX_VALUE);
- testNode(map, 10, 0, 11, 0, 'r');
- testNode(map, 11, 0, 4, 12, Character.MIN_VALUE);
- testNode(map, 12, 14, 5, 0, Character.MAX_VALUE);
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 5, 4, 0, 'e');
+ testNode(map, 4, 3, 1001, 0, Character.MAX_VALUE);
+ testNode(map, 5, 0, 6, 0, 'a');
+ testNode(map, 6, 0, 7, 0, 'v');
+ testNode(map, 7, 0, 8, 9, 'e');
+ testNode(map, 8, 0, 1002, 10, Character.MIN_VALUE);
+ testNode(map, 9, 10, 1003, 0, Character.MAX_VALUE);
+ testNode(map, 10, 0, 11, 0, 'r');
+ testNode(map, 11, 0, 1004, 12, Character.MIN_VALUE);
+ testNode(map, 12, 14, 1005, 0, Character.MAX_VALUE);
Assert.assertEquals("bread\u0000ave\u0000o\u0000r\u0000y\u0000", map.getCompressedKeys());
Assert.assertEquals(1, map.getNodes().findCharNode(1, 'b'));
@@ -381,9 +381,127 @@
/* Find the second 'r' in "braver" and "bravery". We have already found "brave", and therefore start at the
* equal branch of "e". */
Assert.assertEquals(10, map.getNodes().findCharNode(8, 'r'));
+
+ /* Test the iterator. */
+ final Iterator<TernaryNodes.Node> nodeIterator = map.getNodes().nodeIterator();
+ final List<TernaryNodes.Node> actual = new ArrayList<TernaryNodes.Node>();
+ while (nodeIterator.hasNext()) {
+ actual.add(nodeIterator.next());
+ }
+ /* The zero nodes does not get returned by the iterator, so we should have n - 1. */
+ Assert.assertEquals(12, actual.size());
+ Assert.assertEquals(1, actual.get(0).getIndex());
+ Assert.assertEquals(2, actual.get(1).getIndex());
+ Assert.assertEquals(3, actual.get(2).getIndex());
+ Assert.assertEquals(5, actual.get(3).getIndex());
+ Assert.assertEquals(6, actual.get(4).getIndex());
+ Assert.assertEquals(7, actual.get(5).getIndex());
+ Assert.assertEquals(8, actual.get(6).getIndex());
+ Assert.assertEquals(10, actual.get(7).getIndex());
+ Assert.assertEquals(11, actual.get(8).getIndex());
+ Assert.assertEquals(12, actual.get(9).getIndex());
+ Assert.assertEquals(9, actual.get(10).getIndex());
+ Assert.assertEquals(4, actual.get(11).getIndex());
}
/**
+ * Test of {@link TernaryNodes#uncompressNode(int)}.
+ */
+ @SuppressWarnings("javadoc")
+ @Test
+ public void testUncompressNode() {
+
+ /* First some tests with uncompressNode in isolation. */
+ TernaryTree map = new TernaryTree();
+
+ map.put("bravery", 10001);
+ Assert.assertEquals(2, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 10001, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+ map.uncompressNode(1);
+ Assert.assertEquals(3, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 1, 10001, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+ map.uncompressNode(2); // 'r'
+ map.uncompressNode(3); // 'a'
+ map.uncompressNode(4); // 'v'
+ map.uncompressNode(5); // 'e'
+ map.uncompressNode(6); // 'r'
+ Assert.assertEquals(8, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 0, 4, 0, 'a');
+ testNode(map, 4, 0, 5, 0, 'v');
+ testNode(map, 5, 0, 6, 0, 'e');
+ testNode(map, 6, 0, 7, 0, 'r');
+ testNode(map, 7, 6, 10001, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+ map.uncompressNode(7); // 'y'
+ Assert.assertEquals(9, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 0, 4, 0, 'a');
+ testNode(map, 4, 0, 5, 0, 'v');
+ testNode(map, 5, 0, 6, 0, 'e');
+ testNode(map, 6, 0, 7, 0, 'r');
+ testNode(map, 7, 0, 8, 0, 'y');
+ testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+
+
+ /* Now some tests where we call uncompressNode by adding a node that will cause it to be called. */
+
+ /* Same as above. Start with a new map. */
+ map = new TernaryTree();
+ map.put("bravery", 10001);
+ Assert.assertEquals(2, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 10001, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+ /* Add shorter word. */
+ map.put("braver", 10002);
+ Assert.assertEquals(10, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 0, 4, 0, 'a');
+ testNode(map, 4, 0, 5, 0, 'v');
+ testNode(map, 5, 0, 6, 0, 'e');
+ testNode(map, 6, 0, 9, 0, 'r');
+ testNode(map, 7, 0, 8, 0, 'y');
+ testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
+ testNode(map, 9, 0, 10002, 7, Character.MIN_VALUE);
+ Assert.assertEquals("bravery\u0000", map.getCompressedKeys());
+
+ /* This isn't a word, but we need the test. */
+ map = new TernaryTree();
+ map.put("bravery", 10001);
+ map.put("bravera", 10003);
+ Assert.assertEquals(10, map.getNodes().size());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 0, 4, 0, 'a');
+ testNode(map, 4, 0, 5, 0, 'v');
+ testNode(map, 5, 0, 6, 0, 'e');
+ testNode(map, 6, 0, 7, 0, 'r');
+ testNode(map, 7, 9, 8, 0, 'y');
+ testNode(map, 8, 0, 10001, 0, Character.MIN_VALUE);
+ testNode(map, 9, 8, 10003, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bravery\u0000a\u0000", map.getCompressedKeys());
+ }
+
+ /**
* Test of {@link TernaryNodesChar#cloneAsInt()}.
*/
@Test
@@ -392,7 +510,6 @@
map.put("One", 1);
map.put("Two", 2);
final TernaryNodesChar charNodes = (TernaryNodesChar) map.getNodes();
- charNodes.dumpTree();
Assert.assertEquals(4, charNodes.size());
testNode(charNodes, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(charNodes, 1, 0, 2, 3, 'O');
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-23 21:28:20
|
Revision: 11543
http://sourceforge.net/p/foray/code/11543
Author: victormote
Date: 2019-03-23 21:28:11 +0000 (Sat, 23 Mar 2019)
Log Message:
-----------
Add test of cloneAsInt. Add assertion and documentation about what types of nodes can be returned by TernaryNodes.findCharNode().
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 19:19:24 UTC (rev 11542)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 21:28:11 UTC (rev 11543)
@@ -58,6 +58,21 @@
private static final long serialVersionUID = 2866689417641820196L;
/**
+ * Enumeration of the valid node types.
+ */
+ public enum NodeType {
+
+ /** The key char in the node is a valid Unicode character. */
+ CHARACTER,
+
+ /** The key char in the node is 0xFFFF, marking a compressed key node. */
+ COMPRESSED_VALUE,
+
+ /** The key char in the node is 0x0000, marking an uncompressed value node. */
+ UNCOMPRESSED_VALUE;
+ }
+
+ /**
* A notional Node for {@link TernaryNodes}, useful mostly for iterators and debugging.
* Instances of this class are expected to be short-lived and used only for those purposes.
*/
@@ -389,31 +404,36 @@
* previously-found node.
* @param theChar The character being sought in the tree.
* @return Either {@code startingIndex}, the index to one of its descendants, or -1 if no match is found.
+ * The index returned will never be to a node whose type is {@link NodeType.UNCOMPRESSED_VALUE}.
*/
int findCharNode(final int startingIndex, final char theChar) {
+ int returnValue = 0;
+
if (startingIndex < 1) {
/* We are at index 0, which points nowhere. */
- return -1;
+ returnValue = -1;
+ } else if (isCompressedValueNode(startingIndex)) {
+ /* If the character at startingIndex marks a compressed branch, return it.
+ * A compressed branch is terminal, a leaf node, unable to point anywhere else. */
+ returnValue = startingIndex;
+ } else {
+ /* Pick which of the three branches to follow. */
+ final char keyChar = getKeyChar(startingIndex);
+ final int difference = theChar - keyChar;
+ if (difference == 0) {
+ returnValue = startingIndex;
+ } else if (difference < 0) {
+ returnValue = findCharNode(getLow(startingIndex), theChar);
+ } else {
+ /* difference > 0. */
+ returnValue = findCharNode(getHigh(startingIndex), theChar);
+ }
}
-
- final char keyChar = getKeyChar(startingIndex);
-
- /* If the character at startingIndex marks a compressed branch return it.
- * A compressed branch is terminal, a leaf node, unable to point anywhere else. */
- if (keyChar == Character.MAX_VALUE) {
- return startingIndex;
+ if (returnValue != -1
+ && getNodeType(returnValue) == NodeType.UNCOMPRESSED_VALUE) {
+ throw new IllegalStateException();
}
-
- /* Pick which of the three branches to follow. */
- final int difference = theChar - keyChar;
- if (difference == 0) {
- return startingIndex;
- }
- if (difference < 0) {
- return findCharNode(getLow(startingIndex), theChar);
- }
- /* difference > 0. */
- return findCharNode(getHigh(startingIndex), theChar);
+ return returnValue;
}
/**
@@ -470,4 +490,18 @@
return newNode;
}
+ /**
+ * Returns the type of node for a given node index.
+ * @param index The node index.
+ * @return The type of node at {@code index}.
+ */
+ public NodeType getNodeType(final int index) {
+ final char keyChar = this.keyChar[index];
+ switch(keyChar) {
+ case Character.MIN_VALUE: return NodeType.UNCOMPRESSED_VALUE;
+ case Character.MAX_VALUE: return NodeType.COMPRESSED_VALUE;
+ default: return NodeType.CHARACTER;
+ }
+ }
+
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 19:19:24 UTC (rev 11542)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 21:28:11 UTC (rev 11543)
@@ -265,6 +265,25 @@
}
/**
+ * Makes assertions about a given node.
+ * @param nodes The nodes being tested.
+ * @param index The index into {@code map}.
+ * @param expectedLow The expected low.
+ * @param expectedEqual The expected equal.
+ * @param expectedHigh The expected high.
+ * @param expectedKeyChar The expected keyChar value.
+ */
+ private void testNode(final TernaryNodes nodes, final int index, final int expectedLow, final int expectedEqual,
+ final int expectedHigh, final char expectedKeyChar) {
+ final TernaryNodes.Node node = nodes.createNotionalNode(index);
+ Assert.assertEquals(index, node.getIndex());
+ Assert.assertEquals(expectedLow, node.getLow());
+ Assert.assertEquals(expectedEqual, node.getEqual());
+ Assert.assertEquals(expectedHigh, node.getHigh());
+ Assert.assertEquals(expectedKeyChar, node.getKeyChar());
+ }
+
+ /**
* Test of a longer key first, following by a shorter word that is a subset of the longer.
*/
@Test
@@ -364,4 +383,28 @@
Assert.assertEquals(10, map.getNodes().findCharNode(8, 'r'));
}
+ /**
+ * Test of {@link TernaryNodesChar#cloneAsInt()}.
+ */
+ @Test
+ public void testCloneAsInt() {
+ final TernaryTree map = new TernaryTree();
+ map.put("One", 1);
+ map.put("Two", 2);
+ final TernaryNodesChar charNodes = (TernaryNodesChar) map.getNodes();
+ charNodes.dumpTree();
+ Assert.assertEquals(4, charNodes.size());
+ testNode(charNodes, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(charNodes, 1, 0, 2, 3, 'O');
+ testNode(charNodes, 2, 1, 1, 0, Character.MAX_VALUE);
+ testNode(charNodes, 3, 4, 2, 0, Character.MAX_VALUE);
+
+ final TernaryNodesInt intNodes = charNodes.cloneAsInt();
+ Assert.assertEquals(4, charNodes.size());
+ testNode(intNodes, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(intNodes, 1, 0, 2, 3, 'O');
+ testNode(intNodes, 2, 1, 1, 0, Character.MAX_VALUE);
+ testNode(intNodes, 3, 4, 2, 0, Character.MAX_VALUE);
+ }
+
}
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-23 19:19:24 UTC (rev 11542)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-23 21:28:11 UTC (rev 11543)
@@ -28,11 +28,8 @@
package org.foray.hyphen;
-import org.foray.common.data.TernaryTreeMap;
-
-import org.slf4j.LoggerFactory;
-
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -47,7 +44,7 @@
private static final long serialVersionUID = -8752423281137349847L;
/** The data structure containing the dictionary words. */
- private Map<CharSequence, SegmentDictionaryWord> wordMap = new TernaryTreeMap<SegmentDictionaryWord>();
+ private Map<CharSequence, SegmentDictionaryWord> wordMap = new HashMap<CharSequence, SegmentDictionaryWord>();
/** The array of word segments in this dictionary. */
private StringWordSegment[] wordSegments;
@@ -84,9 +81,6 @@
dictionarySegmentIndexes[segmentIndex] = (char) dictionarySegmentIndex;
}
final SegmentDictionaryWord dictWord = new SegmentDictionaryWord(this, dictionarySegmentIndexes);
- if ("limberness".equals(rawWord)) {
- LoggerFactory.getLogger(this.getClass()).info(rawWord);
- }
this.wordMap.put(rawWord, dictWord);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-23 19:19:30
|
Revision: 11542
http://sourceforge.net/p/foray/code/11542
Author: victormote
Date: 2019-03-23 19:19:24 +0000 (Sat, 23 Mar 2019)
Log Message:
-----------
Clean up size() and init() for TernaryTree. Revert changes to SegmentDictionary that were committed in error.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 02:03:13 UTC (rev 11541)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 19:19:24 UTC (rev 11542)
@@ -156,6 +156,13 @@
private char[] keyChar;
/**
+ * Constructor.
+ */
+ public TernaryNodes() {
+ init();
+ }
+
+ /**
* Returns the "low" value of a given node.
* If {@link #getKeyChar(int)} is a valid Unicode character, this array contains the index to the node containing
* the "low" branch, that is the branch that should be traversed to find a char that is less than
@@ -209,7 +216,7 @@
/**
* Initialize the data structure.
*/
- public void init() {
+ protected void init() {
this.freenode = 1;
this.keyChar = new char[TernaryNodes.DEFAULT_BLOCK_SIZE];
initIndexes(TernaryNodes.DEFAULT_BLOCK_SIZE);
@@ -274,14 +281,6 @@
public abstract TernaryNodes createInstance();
/**
- * Return the number of nodes in this structure.
- * @return The number of nodes in this structure.
- */
- public int length() {
- return this.keyChar.length;
- }
-
- /**
* Ensures that the internal data structures have enough nodes to handle a given number of nodes.
* @param newCapacity The new number of nodes that needs to be ensured.
*/
@@ -301,6 +300,13 @@
}
/**
+ * Packs the arrays to their current size, i.e. removes any unused array elements..
+ */
+ public void pack() {
+ resizeIndexes(this.freenode);
+ }
+
+ /**
* Resizes the arrays.
* @param newSize The new number of nodes in the tree.
*/
@@ -341,7 +347,7 @@
* Returns the number of nodes in the tree.
* @return The number of nodes in the tree.
*/
- public int getNodeCount() {
+ public int size() {
return this.freenode;
}
@@ -350,7 +356,7 @@
* @param index The index of the node to be tested.
* @return True if and only if the node is a compressed node.
*/
- boolean isCompressedNode(final int index) {
+ boolean isCompressedValueNode(final int index) {
return getKeyChar(index) == Character.MAX_VALUE;
}
@@ -359,7 +365,7 @@
* @param index The index of the node to be tested.
* @return True if and only if the node is a terminating node.
*/
- boolean isTerminatingNode(final int index) {
+ boolean isUncompressedValueNode(final int index) {
return getKeyChar(index) == Character.MIN_VALUE;
}
@@ -392,7 +398,8 @@
final char keyChar = getKeyChar(startingIndex);
- /* If the character at startingIndex marks a compressed branch return it. */
+ /* If the character at startingIndex marks a compressed branch return it.
+ * A compressed branch is terminal, a leaf node, unable to point anywhere else. */
if (keyChar == Character.MAX_VALUE) {
return startingIndex;
}
@@ -432,10 +439,11 @@
*/
public void dumpTree() {
final Logger logger = LoggerFactory.getLogger(this.getClass());
- for (int index = 0; index < this.length(); index ++) {
+ for (int index = 0; index < size(); index ++) {
final Node node = createNotionalNode(index);
logger.info(node.toString());
}
+ logger.info("-----------------------------------------------------------------------------------------");
}
/**
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-23 02:03:13 UTC (rev 11541)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-23 19:19:24 UTC (rev 11542)
@@ -100,9 +100,9 @@
public TernaryNodesInt cloneAsInt() {
final TernaryNodesInt newNodes = new TernaryNodesInt();
/* Presumably, this is done because we are out of room in the char version, so add some capacity. */
- newNodes.resize(getNodeCount() + DEFAULT_BLOCK_SIZE);
+ newNodes.resize(this.low.length + DEFAULT_BLOCK_SIZE);
/* Start copy at 1 instead of 0. Node 0 is not really explicity created. */
- for (int index = 1; index < getNodeCount(); index ++) {
+ for (int index = 1; index < this.low.length; index ++) {
/* Allocating the node explicitly should keep the node count correct. */
newNodes.allocateNewNode();
newNodes.setLow(index, getLow(index));
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 02:03:13 UTC (rev 11541)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 19:19:24 UTC (rev 11542)
@@ -228,7 +228,7 @@
* @param value The value.
*/
public void put(final CharSequence key, final int start, final int end, final int value) {
- final int newCapacity = this.nodes.getNodeCount() + end - start + 1;
+ final int newCapacity = this.nodes.size() + end - start + 1;
this.nodes.ensureCapacity(newCapacity);
put(this.nodes.getRootNodeIndex(), key, start, end, value);
}
@@ -458,7 +458,7 @@
return -1;
}
- if (this.nodes.isCompressedNode(charNodeIndex)) {
+ if (this.nodes.isCompressedValueNode(charNodeIndex)) {
if (CharSequenceUtils.compareNullTerminated(
this.compressedKeys, this.nodes.getLow(charNodeIndex), key, i, end) == 0) {
return charNodeIndex;
@@ -469,7 +469,7 @@
/* If we are at the end of the word, see if there is a terminating node for it. */
if (i == end - 1) {
final int targetNodeIndex = this.nodes.getEqual(charNodeIndex);
- if (this.nodes.isTerminatingNode(targetNodeIndex)) {
+ if (this.nodes.isUncompressedValueNode(targetNodeIndex)) {
return targetNodeIndex;
}
return -1;
@@ -565,7 +565,7 @@
balance();
/* Redimension the node arrays. */
- this.nodes.resize(this.nodes.getNodeCount());
+ this.nodes.pack();
/* Compact the compressedKeys. */
final StringBuilder kx = new StringBuilder();
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 02:03:13 UTC (rev 11541)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 19:19:24 UTC (rev 11542)
@@ -154,8 +154,7 @@
Assert.assertEquals(-1, map.get("ABCCXYZ".toCharArray(), 3, 4));
Assert.assertEquals(4, map.size());
- /* TODO: We don't fully understand the node count here. */
- Assert.assertEquals(11, map.getNodes().getNodeCount());
+ Assert.assertEquals(11, map.getNodes().size());
}
/**
@@ -273,7 +272,7 @@
final TernaryTree map = new TernaryTree();
map.put("superset", 2019);
- Assert.assertEquals(2, map.getNodes().getNodeCount());
+ Assert.assertEquals(2, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2019, 0, Character.MAX_VALUE);
Assert.assertEquals("superset\u0000", map.getCompressedKeys());
@@ -282,7 +281,7 @@
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
map.put("super", 2007);
- Assert.assertEquals(9, map.getNodes().getNodeCount());
+ Assert.assertEquals(9, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 's');
testNode(map, 2, 0, 3, 0, 'u');
@@ -298,7 +297,7 @@
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
map.put("sup", 1941);
- Assert.assertEquals(10, map.getNodes().getNodeCount());
+ Assert.assertEquals(10, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 's');
testNode(map, 2, 0, 3, 0, 'u');
@@ -328,7 +327,7 @@
map.put("braver", 4);
map.put("bravery", 5);
- Assert.assertEquals(13, map.getNodes().getNodeCount());
+ Assert.assertEquals(13, map.getNodes().size());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 'b');
testNode(map, 2, 0, 3, 0, 'r');
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-23 02:03:19
|
Revision: 11541
http://sourceforge.net/p/foray/code/11541
Author: victormote
Date: 2019-03-23 02:03:13 +0000 (Sat, 23 Mar 2019)
Log Message:
-----------
Start all TernaryTrees with 16-bit indexes, then convert to 31-bit only if the capacity is exceeded.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/PatternTree.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -54,11 +54,6 @@
/** The index to the root node. */
public static final int ROOT_NODE_INDEX = 1;
- /** SWAG of the maximum number of key-value pairs that can be stored in a nodes structure that uses chars for the
- * index storage. This may be used by applications that need to guess which {@link TernaryNodes} implementation to
- * choose. */
- public static final int SUGGESTED_MAX_QTY_CHAR_KV_PAIRS = 50000;
-
/** Constant needed for serialization. */
private static final long serialVersionUID = 2866689417641820196L;
@@ -351,20 +346,6 @@
}
/**
- * Allocates an index for a new node, after first checking for an overflow.
- * @return The index to the new node.
- */
- int createNode() {
- if (this.freenode >= getMaximumCapacity()) {
- throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
- + getMaximumCapacity());
- }
- final int newNode = this.freenode;
- this.freenode ++;
- return newNode;
- }
-
- /**
* Indicates whether a given node is a compressed node.
* @param index The index of the node to be tested.
* @return True if and only if the node is a compressed node.
@@ -463,4 +444,22 @@
*/
public abstract int getMaximumCapacity();
+ /**
+ * Indicates whether creating another node would exceed the capacity of this data structure.
+ * @return True if and only if creating a new node would exceed the capacity of this data structure.
+ */
+ public boolean isCapacityExceeded() {
+ return this.freenode >= getMaximumCapacity();
+ }
+
+ /**
+ * Allocates a new node.
+ * @return The new node index.
+ */
+ public int allocateNewNode() {
+ final int newNode = this.freenode;
+ this.freenode ++;
+ return newNode;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -93,6 +93,26 @@
return clone;
}
+ /**
+ * Copies the data from this collection into a new instance of {@link TernaryNodesInt}.
+ * @return A copy of the data from this structure, packaged in a new instance of {@link TernaryNodesInt}.
+ */
+ public TernaryNodesInt cloneAsInt() {
+ final TernaryNodesInt newNodes = new TernaryNodesInt();
+ /* Presumably, this is done because we are out of room in the char version, so add some capacity. */
+ newNodes.resize(getNodeCount() + DEFAULT_BLOCK_SIZE);
+ /* Start copy at 1 instead of 0. Node 0 is not really explicity created. */
+ for (int index = 1; index < getNodeCount(); index ++) {
+ /* Allocating the node explicitly should keep the node count correct. */
+ newNodes.allocateNewNode();
+ newNodes.setLow(index, getLow(index));
+ newNodes.setEqual(index, getEqual(index));
+ newNodes.setHigh(index, getHigh(index));
+ newNodes.setKeyChar(index, getKeyChar(index));
+ }
+ return newNodes;
+ }
+
@Override
public TernaryNodesChar createInstance() {
return new TernaryNodesChar();
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -36,6 +36,8 @@
import org.foray.common.primitive.CharSequenceUtils;
import org.foray.common.primitive.StringUtils;
+import org.slf4j.LoggerFactory;
+
import java.io.Serializable;
import java.util.Iterator;
import java.util.Stack;
@@ -126,9 +128,17 @@
/**
* Constructor.
+ */
+ public TernaryTree() {
+ this.nodes = new TernaryNodesChar();
+ init();
+ }
+
+ /**
+ * Private constructor used during cloning.
* @param nodes The data structure containing the branch indexes.
*/
- public TernaryTree(final TernaryNodes nodes) {
+ private TernaryTree(final TernaryNodes nodes) {
this.nodes = nodes;
init();
}
@@ -143,6 +153,24 @@
}
/**
+ * Allocates an index for a new node, after first checking for an overflow.
+ * @return The index to the new node.
+ */
+ int createNode() {
+ if (this.nodes.isCapacityExceeded()) {
+ if (this.nodes instanceof TernaryNodesChar) {
+ final TernaryNodesChar oldNodes = (TernaryNodesChar) this.nodes;
+ this.nodes = oldNodes.cloneAsInt();
+ LoggerFactory.getLogger(this.getClass()).info("Switched to TernaryNodesInt for greater capacity.");
+ } else {
+ throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
+ + this.nodes.getMaximumCapacity());
+ }
+ }
+ return this.nodes.allocateNewNode();
+ }
+
+ /**
* Put part or all of one char[] in the map.
* @param key The key to be added.
* @param value The value.
@@ -242,7 +270,7 @@
return currentNodeIndex;
} else {
/* This node is not a zero-terminated node. We need to create one to hold the value. */
- final int newNodeIndex = this.nodes.createNode();
+ final int newNodeIndex = createNode();
/* In addition to adding a node, we are adding a mapped pair here. */
this.length++;
/* We are interposing the new node between the parent and the current node. */
@@ -280,7 +308,7 @@
* @return The index to the newly-created node.
*/
private int createBranch(final CharSequence key, final int start, final int end, final int value) {
- final int currentNodeIndex = this.nodes.createNode();
+ final int currentNodeIndex = createNode();
final int len = end - start;
/* Holds data. */
this.nodes.setEqual(currentNodeIndex, value);
@@ -317,7 +345,7 @@
this.nodes.setKeyChar(nodeIndex, this.compressedKeys.charAt(this.nodes.getLow(nodeIndex)));
/* Create and initialize the new node. */
- final int newNodeIndex = this.nodes.createNode();
+ final int newNodeIndex = createNode();
this.nodes.setLow(newNodeIndex, this.nodes.getLow(nodeIndex));
this.nodes.setEqual(newNodeIndex, this.nodes.getEqual(nodeIndex));
this.nodes.setHigh(newNodeIndex, this.nodes.getHigh(nodeIndex));
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -51,22 +51,16 @@
/**
* Constructor.
- * @param nodes The data structure for holding the indexes.
- * This should be one of {@link TernaryNodesChar} or {@link TernaryNodesInt}.
- * Making an accurate estimate of this number is more important than in many {@link Map} implementations, as this
- * determines the type of internal data structure that should be used.
- *
*/
- public TernaryTreeMap(final TernaryNodes nodes) {
- init(nodes);
+ public TernaryTreeMap() {
+ init();
}
/**
* Initialize or clear the map data.
- * @param nodes The nodes that should be used by the internal ternary tree.
*/
- private void init(final TernaryNodes nodes) {
- this.keys = new TernaryTree(nodes);
+ private void init() {
+ this.keys = new TernaryTree();
this.values = new ArrayList<V>();
}
@@ -151,7 +145,7 @@
@Override
public void clear() {
- init(this.keys.getNodes().createInstance());
+ init();
}
@Override
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -48,7 +48,7 @@
*/
@Before
public void setUp() {
- this.out = new TernaryTreeMap<String>(new TernaryNodesChar());
+ this.out = new TernaryTreeMap<String>();
Assert.assertTrue(this.out.isEmpty());
this.out.put("Key 1", "Value 1");
this.out.put("Key 2", "Value 2");
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -46,7 +46,7 @@
@Test
public void testOutput01() {
/* Check the CharSequence putters for whole words. */
- TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ TernaryTree map = new TernaryTree();
map.put("Carlos", 'C');
map.put("Car", 'r');
map.put("palos", 'l');
@@ -55,7 +55,7 @@
checkGetters(map);
/* Check the CharSequence putters for words starting in the middle of a string. */
- map = new TernaryTree(new TernaryNodesChar());
+ map = new TernaryTree();
map.put("123Carlos", 3, 'C');
map.put("123Car", 3, 'r');
map.put("123palos", 3, 'l');
@@ -64,7 +64,7 @@
checkGetters(map);
/* Check the CharSequence putters for words starting and ending in the middle of a string. */
- map = new TernaryTree(new TernaryNodesChar());
+ map = new TernaryTree();
map.put("123CarlosPDQ", 3, 9, 'C');
map.put("123CarPDQ", 3, 6, 'r');
map.put("123palosPDQ", 3, 8, 'l');
@@ -73,7 +73,7 @@
checkGetters(map);
/* Check the char[] putters for whole words. */
- map = new TernaryTree(new TernaryNodesChar());
+ map = new TernaryTree();
map.put("Carlos".toCharArray(), 'C');
map.put("Car".toCharArray(), 'r');
map.put("palos".toCharArray(), 'l');
@@ -82,7 +82,7 @@
checkGetters(map);
/* Check the char[] putters for words starting in the middle of a string. */
- map = new TernaryTree(new TernaryNodesChar());
+ map = new TernaryTree();
map.put("123Carlos".toCharArray(), 3, 'C');
map.put("123Car".toCharArray(), 3, 'r');
map.put("123palos".toCharArray(), 3, 'l');
@@ -91,7 +91,7 @@
checkGetters(map);
/* Check the char[] putters for words starting and ending in the middle of a string. */
- map = new TernaryTree(new TernaryNodesChar());
+ map = new TernaryTree();
map.put("123CarlosPDQ".toCharArray(), 3, 9, 'C');
map.put("123CarPDQ".toCharArray(), 3, 6, 'r');
map.put("123palosPDQ".toCharArray(), 3, 8, 'l');
@@ -164,7 +164,7 @@
@Test
public void testOutput02() {
/* Check the CharSequence putters for whole words. */
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("Car", 'r');
map.put("Carlos", 'C');
map.optimize();
@@ -181,7 +181,7 @@
*/
@Test
public void testGetOnEmptyTree() {
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
Assert.assertEquals(-1, map.get("This is a test"));
}
@@ -191,7 +191,7 @@
*/
@Test
public void testPut01() {
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("40", 1);
map.put("45", 2);
map.put("4", 3);
@@ -205,7 +205,7 @@
@Test
public void testKeyNotFound() {
/* Put some entries into the tree. */
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("Carlos", 'C');
map.put("Car", 'r');
map.put("palos", 'l');
@@ -222,7 +222,7 @@
*/
@Test
public void iteratorTest() {
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("Julius Caesar", 'a');
map.put("Hamlet", 'b');
map.put("The Tempest", 'c');
@@ -270,7 +270,7 @@
*/
@Test
public void testEnclosedWord() {
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("superset", 2019);
Assert.assertEquals(2, map.getNodes().getNodeCount());
@@ -321,7 +321,7 @@
@SuppressWarnings("javadoc")
@Test
public void testFindCharNode() {
- final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ final TernaryTree map = new TernaryTree();
map.put("bread", 1);
map.put("brave", 2);
map.put("bravo", 3);
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/PatternTree.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/PatternTree.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/PatternTree.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -34,7 +34,6 @@
package org.foray.hyphen;
import org.foray.common.data.NibbleArrayBuilder;
-import org.foray.common.data.TernaryNodesChar;
import org.foray.common.data.TernaryTree;
import org.foray.common.primitive.BitUtils;
import org.foray.common.primitive.StringUtils;
@@ -120,7 +119,7 @@
/** A map whose key is String patterns, and whose value is an index into
* {@link #patternValues}. */
- private TernaryTree patternKeys = new TernaryTree(new TernaryNodesChar());
+ private TernaryTree patternKeys = new TernaryTree();
/**
* <p>The vector of interletter values for the Liang patterns.
@@ -135,7 +134,7 @@
= new HashMap<String, StringWord>();
/** The character classes. */
- private TernaryTree classes = new TernaryTree(new TernaryNodesChar());
+ private TernaryTree classes = new TernaryTree();
/** Temporary map to store interletter values during pattern loading. */
private transient TernaryTree tempInterletterValues;
@@ -183,7 +182,7 @@
void loadPatterns(final InputStream inputStream, final Logger logger) throws HyphenationException {
this.source = PatternTree.Source.PARSED;
final PatternParser pp = new PatternParser(this);
- this.tempInterletterValues = new TernaryTree(new TernaryNodesChar());
+ this.tempInterletterValues = new TernaryTree();
pp.parse(inputStream);
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-23 01:09:37 UTC (rev 11540)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-23 02:03:13 UTC (rev 11541)
@@ -28,8 +28,11 @@
package org.foray.hyphen;
+import org.foray.common.data.TernaryTreeMap;
+
+import org.slf4j.LoggerFactory;
+
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -44,7 +47,7 @@
private static final long serialVersionUID = -8752423281137349847L;
/** The data structure containing the dictionary words. */
- private Map<CharSequence, SegmentDictionaryWord> wordMap = new HashMap<CharSequence, SegmentDictionaryWord>();
+ private Map<CharSequence, SegmentDictionaryWord> wordMap = new TernaryTreeMap<SegmentDictionaryWord>();
/** The array of word segments in this dictionary. */
private StringWordSegment[] wordSegments;
@@ -81,6 +84,9 @@
dictionarySegmentIndexes[segmentIndex] = (char) dictionarySegmentIndex;
}
final SegmentDictionaryWord dictWord = new SegmentDictionaryWord(this, dictionarySegmentIndexes);
+ if ("limberness".equals(rawWord)) {
+ LoggerFactory.getLogger(this.getClass()).info(rawWord);
+ }
this.wordMap.put(rawWord, dictWord);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-23 01:09:46
|
Revision: 11540
http://sourceforge.net/p/foray/code/11540
Author: victormote
Date: 2019-03-23 01:09:37 +0000 (Sat, 23 Mar 2019)
Log Message:
-----------
Add tests and test-oriented helper code. Rewrite the TernaryTree getter logic.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-22 16:41:53 UTC (rev 11539)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-23 01:09:37 UTC (rev 11540)
@@ -28,6 +28,9 @@
package org.foray.common.data;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.Serializable;
import java.util.Arrays;
@@ -48,6 +51,9 @@
/** Allocation size for arrays. */
public static final int DEFAULT_BLOCK_SIZE = 2048;
+ /** The index to the root node. */
+ public static final int ROOT_NODE_INDEX = 1;
+
/** SWAG of the maximum number of key-value pairs that can be stored in a nodes structure that uses chars for the
* index storage. This may be used by applications that need to guess which {@link TernaryNodes} implementation to
* choose. */
@@ -119,8 +125,13 @@
@Override
public String toString() {
- return String.format("index: %5d, low: %5d, equal: %5d, high: %5d, key: %4x",
- this.index, this.low, this.equal, this.high, (int) this.keyChar);
+ char printableChar = this.keyChar;
+ if (printableChar < ' '
+ || printableChar == Character.MAX_VALUE) {
+ printableChar = ' ';
+ }
+ return String.format("index: %5d, low: %5d, equal: %5d, high: %5d, key: %4x %s",
+ this.index, this.low, this.equal, this.high, (int) this.keyChar, printableChar);
}
@Override
@@ -328,7 +339,7 @@
/* If we haven't created any nodes, yet, this is a special case. */
return 0;
}
- return 1;
+ return ROOT_NODE_INDEX;
}
/**
@@ -344,9 +355,9 @@
* @return The index to the new node.
*/
int createNode() {
- if (this.freenode >= Character.MAX_VALUE) {
+ if (this.freenode >= getMaximumCapacity()) {
throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
- + Integer.toString(Character.MAX_VALUE + 1));
+ + getMaximumCapacity());
}
final int newNode = this.freenode;
this.freenode ++;
@@ -353,4 +364,103 @@
return newNode;
}
+ /**
+ * Indicates whether a given node is a compressed node.
+ * @param index The index of the node to be tested.
+ * @return True if and only if the node is a compressed node.
+ */
+ boolean isCompressedNode(final int index) {
+ return getKeyChar(index) == Character.MAX_VALUE;
+ }
+
+ /**
+ * Indicates whether a given node is a terminating node.
+ * @param index The index of the node to be tested.
+ * @return True if and only if the node is a terminating node.
+ */
+ boolean isTerminatingNode(final int index) {
+ return getKeyChar(index) == Character.MIN_VALUE;
+ }
+
+ /**
+ * Indicates whether a given node has a key value equal to a specified char.
+ * @param index The index of the node to be tested.
+ * @param theChar The character being sought in the tree.
+ * @return True if and only if the node is an uncompressed node matching the {@code theChar}.
+ */
+ boolean isCharNode(final int index, final char theChar) {
+ return getKeyChar(index) == theChar;
+ }
+
+ /**
+ * Recursively finds the descendant-or-self node that matches a given char, starting at a given index.
+ * If a compressed branch is reached in the search, that branch index is returned.
+ * Please note that it may or may not match the string being sought.
+ * It is the responsibility of client code to determine whether the compressed branch should be used or not.
+ * @param startingIndex The index of the node at which the search should begin.
+ * Presumably, this should either be the {@link #ROOT_NODE_INDEX}, or the {@link #getEqual(int)} value from a
+ * previously-found node.
+ * @param theChar The character being sought in the tree.
+ * @return Either {@code startingIndex}, the index to one of its descendants, or -1 if no match is found.
+ */
+ int findCharNode(final int startingIndex, final char theChar) {
+ if (startingIndex < 1) {
+ /* We are at index 0, which points nowhere. */
+ return -1;
+ }
+
+ final char keyChar = getKeyChar(startingIndex);
+
+ /* If the character at startingIndex marks a compressed branch return it. */
+ if (keyChar == Character.MAX_VALUE) {
+ return startingIndex;
+ }
+
+ /* Pick which of the three branches to follow. */
+ final int difference = theChar - keyChar;
+ if (difference == 0) {
+ return startingIndex;
+ }
+ if (difference < 0) {
+ return findCharNode(getLow(startingIndex), theChar);
+ }
+ /* difference > 0. */
+ return findCharNode(getHigh(startingIndex), theChar);
+ }
+
+ /**
+ * Returns the highest index whose node has values in it.
+ * Useful mainly for testing the value in {@link #freenode}.
+ * @return The highest index whose node has value.
+ */
+ int getLastNonNullIndex() {
+ for (int index = this.keyChar.length - 1; index > -1; index --) {
+ if (this.keyChar[index] != 0
+ || getLow(index) != 0
+ || getEqual(index) != 0
+ || getHigh(index) != 0) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Dumps the content of the tree to a logger.
+ * Useful for tests.
+ */
+ public void dumpTree() {
+ final Logger logger = LoggerFactory.getLogger(this.getClass());
+ for (int index = 0; index < this.length(); index ++) {
+ final Node node = createNotionalNode(index);
+ logger.info(node.toString());
+ }
+ }
+
+ /**
+ * Returns the maximum capacity of this data structure.
+ * @return The maximum capacity of this data structure.
+ */
+ public abstract int getMaximumCapacity();
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-22 16:41:53 UTC (rev 11539)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesChar.java 2019-03-23 01:09:37 UTC (rev 11540)
@@ -105,4 +105,9 @@
this.equal = Arrays.copyOf(this.equal, newSize);
}
+ @Override
+ public int getMaximumCapacity() {
+ return Character.MAX_VALUE;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java 2019-03-22 16:41:53 UTC (rev 11539)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java 2019-03-23 01:09:37 UTC (rev 11540)
@@ -105,4 +105,9 @@
this.equal = Arrays.copyOf(this.equal, newSize);
}
+ @Override
+ public int getMaximumCapacity() {
+ return Integer.MAX_VALUE;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-22 16:41:53 UTC (rev 11539)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-23 01:09:37 UTC (rev 11540)
@@ -422,35 +422,34 @@
int getNodeIndex(final CharSequence key, final int start, final int end) {
int currentNodeIndex = this.nodes.getRootNodeIndex();
int i = start;
- char c;
- while (currentNodeIndex != 0) {
- if (this.nodes.getKeyChar(currentNodeIndex) == Character.MAX_VALUE) {
+ while (i < end) {
+ final char c = key.charAt(i);
+ final int charNodeIndex = this.nodes.findCharNode(currentNodeIndex, c);
+ if (charNodeIndex < 0) {
+ return -1;
+ }
+
+ if (this.nodes.isCompressedNode(charNodeIndex)) {
if (CharSequenceUtils.compareNullTerminated(
- this.compressedKeys, this.nodes.getLow(currentNodeIndex), key, i, end) == 0) {
- return currentNodeIndex;
+ this.compressedKeys, this.nodes.getLow(charNodeIndex), key, i, end) == 0) {
+ return charNodeIndex;
}
return -1;
}
- if (i >= end) {
- /* If we are past the end of the key, then pretend like we have a
- * null-terminator. */
- c = 0;
- } else {
- c = key.charAt(i);
- }
- final int difference = c - this.nodes.getKeyChar(currentNodeIndex);
- if (difference == 0) {
- if (c == 0) {
- return currentNodeIndex;
+
+ /* If we are at the end of the word, see if there is a terminating node for it. */
+ if (i == end - 1) {
+ final int targetNodeIndex = this.nodes.getEqual(charNodeIndex);
+ if (this.nodes.isTerminatingNode(targetNodeIndex)) {
+ return targetNodeIndex;
}
- i++;
- currentNodeIndex = this.nodes.getEqual(currentNodeIndex);
- } else if (difference < 0) {
- currentNodeIndex = this.nodes.getLow(currentNodeIndex);
- } else {
- currentNodeIndex = this.nodes.getHigh(currentNodeIndex);
+ return -1;
}
+
+ currentNodeIndex = this.nodes.getEqual(charNodeIndex);
+ i++;
+
}
return -1;
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-22 16:41:53 UTC (rev 11539)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-23 01:09:37 UTC (rev 11540)
@@ -192,13 +192,13 @@
@Test
public void testPut01() {
final TernaryTree map = new TernaryTree(new TernaryNodesChar());
- map.put("40", '1');
- map.put("45", '2');
- map.put("4", '3');
+ map.put("40", 1);
+ map.put("45", 2);
+ map.put("4", 3);
- Assert.assertEquals('1', (char) map.get("40"));
- Assert.assertEquals('2', (char) map.get("45"));
- Assert.assertEquals('3', (char) map.get("4"));
+ Assert.assertEquals(1, map.get("40"));
+ Assert.assertEquals(2, map.get("45"));
+ Assert.assertEquals(3, map.get("4"));
}
/** Test of retrieving the value for a key that is not in the map. */
@@ -315,4 +315,54 @@
Assert.assertEquals(9, map.getNodeIndex("sup", 0, "sup".length()));
}
+ /**
+ * Test of {@link TernaryNodes#findCharNode(int, char)}.
+ */
+ @SuppressWarnings("javadoc")
+ @Test
+ public void testFindCharNode() {
+ final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ map.put("bread", 1);
+ map.put("brave", 2);
+ map.put("bravo", 3);
+ map.put("braver", 4);
+ map.put("bravery", 5);
+
+ Assert.assertEquals(13, map.getNodes().getNodeCount());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 'b');
+ testNode(map, 2, 0, 3, 0, 'r');
+ testNode(map, 3, 5, 4, 0, 'e');
+ testNode(map, 4, 3, 1, 0, Character.MAX_VALUE);
+ testNode(map, 5, 0, 6, 0, 'a');
+ testNode(map, 6, 0, 7, 0, 'v');
+ testNode(map, 7, 0, 8, 9, 'e');
+ testNode(map, 8, 0, 2, 10, Character.MIN_VALUE);
+ testNode(map, 9, 10, 3, 0, Character.MAX_VALUE);
+ testNode(map, 10, 0, 11, 0, 'r');
+ testNode(map, 11, 0, 4, 12, Character.MIN_VALUE);
+ testNode(map, 12, 14, 5, 0, Character.MAX_VALUE);
+ Assert.assertEquals("bread\u0000ave\u0000o\u0000r\u0000y\u0000", map.getCompressedKeys());
+
+ Assert.assertEquals(1, map.getNodes().findCharNode(1, 'b'));
+ Assert.assertEquals(-1, map.getNodes().findCharNode(1, 'q'));
+
+ /* Find the 'a' in "bravo". We have already found "br", and therefore start at the equal branch of "r". */
+ Assert.assertEquals(5, map.getNodes().findCharNode(3, 'a'));
+ /* Find the 'v' in "bravo". We have already found "bra", and therefore start at the equal branch of "a". */
+ Assert.assertEquals(6, map.getNodes().findCharNode(6, 'v'));
+ /* Find the 'o' in "bravo". We have already found "brav", and therefore start at the equal branch of "v". */
+ Assert.assertEquals(9, map.getNodes().findCharNode(7, 'o'));
+
+ /* Find the 'e' in "brave". We have already found "brav", and therefore start at the equal branch of "v". */
+ Assert.assertEquals(7, map.getNodes().findCharNode(7, 'e'));
+
+ /* Find the 'a' in "bread". We have already found "bre", and therefore start at the equal branch of "e". */
+ Assert.assertEquals(4, map.getNodes().findCharNode(4, 'a'));
+
+ /* Find the second 'r' in "braver" and "bravery". We have already found "brave", and therefore start at the
+ * equal branch of "e". */
+ Assert.assertEquals(10, map.getNodes().findCharNode(8, 'r'));
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-22 16:42:00
|
Revision: 11539
http://sourceforge.net/p/foray/code/11539
Author: victormote
Date: 2019-03-22 16:41:53 +0000 (Fri, 22 Mar 2019)
Log Message:
-----------
Clean up notion of a root node, mostly for clarity.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-22 13:55:46 UTC (rev 11538)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-22 16:41:53 UTC (rev 11539)
@@ -45,6 +45,9 @@
*/
public abstract class TernaryNodes implements Serializable, Cloneable {
+ /** Allocation size for arrays. */
+ public static final int DEFAULT_BLOCK_SIZE = 2048;
+
/** SWAG of the maximum number of key-value pairs that can be stored in a nodes structure that uses chars for the
* index storage. This may be used by applications that need to guess which {@link TernaryNodes} implementation to
* choose. */
@@ -140,6 +143,9 @@
}
}
+ /** The index to the next available node. */
+ private int freenode;
+
/** The array of chars representing the "key". */
private char[] keyChar;
@@ -198,8 +204,9 @@
* Initialize the data structure.
*/
public void init() {
- this.keyChar = new char[TernaryTree.BLOCK_SIZE];
- initIndexes(TernaryTree.BLOCK_SIZE);
+ this.freenode = 1;
+ this.keyChar = new char[TernaryNodes.DEFAULT_BLOCK_SIZE];
+ initIndexes(TernaryNodes.DEFAULT_BLOCK_SIZE);
}
/**
@@ -240,7 +247,9 @@
@Override
public TernaryNodes clone() {
- return forceClone();
+ final TernaryNodes clone = forceClone();
+ clone.freenode = this.freenode;
+ return clone;
}
/**
@@ -272,7 +281,7 @@
*/
public void ensureCapacity(final int newCapacity) {
if (newCapacity > this.keyChar.length) {
- resize(this.keyChar.length + TernaryTree.BLOCK_SIZE);
+ resize(this.keyChar.length + TernaryNodes.DEFAULT_BLOCK_SIZE);
}
}
@@ -310,4 +319,38 @@
return node;
}
+ /**
+ * Returns the index to the root node of the tree.
+ * @return The index to the root node of the tree.
+ */
+ public int getRootNodeIndex() {
+ if (this.freenode == 1) {
+ /* If we haven't created any nodes, yet, this is a special case. */
+ return 0;
+ }
+ return 1;
+ }
+
+ /**
+ * Returns the number of nodes in the tree.
+ * @return The number of nodes in the tree.
+ */
+ public int getNodeCount() {
+ return this.freenode;
+ }
+
+ /**
+ * Allocates an index for a new node, after first checking for an overflow.
+ * @return The index to the new node.
+ */
+ int createNode() {
+ if (this.freenode >= Character.MAX_VALUE) {
+ throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
+ + Integer.toString(Character.MAX_VALUE + 1));
+ }
+ final int newNode = this.freenode;
+ this.freenode ++;
+ return newNode;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-22 13:55:46 UTC (rev 11538)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-22 16:41:53 UTC (rev 11539)
@@ -97,11 +97,7 @@
* marks whether the data in that node is compressed or not.
* 3. TODO: The zero-termination in CharVector is probably not needed, as the ending index can probably be stored in
* the hi branch of the compressed node, just as the starting index is stored in the lo branch.
- * 4. TODO: I think the "root" index will always be 0 or 1.
- * It is a bit misleading to store it as an instance variable, as it seems then to have more significance than
- * that.
- * Probably just checking for the existence of a node at index 1 would be sufficient (is freenode > 1).
- * 5. TODO: We miss an opportunity by using the branch compression.
+ * 4. TODO: We miss an opportunity by using the branch compression.
* The good news is that it saves nodes, but the bad news is that it saves nodes.
* It might be useful, in addition to returning mapped values, to return the node number that contains the
* mapped value.
@@ -111,9 +107,6 @@
* node index represents a compressed node.
*/
- /** Allocation size for arrays. */
- public static final int BLOCK_SIZE = 2048;
-
/** Constant used for serialization. */
private static final long serialVersionUID = 240904407206584695L;
@@ -126,12 +119,6 @@
* {@link TernaryNodes#getLow(int)} value for the node. */
private StringBuilder compressedKeys;
- /** The index of the root of the current branch?? */
- private int root;
-
- /** The index to the next available node. */
- private int freenode;
-
/** The number of key-value pairs mapped in the tree.
* This is not necessarily the same as the number of nodes in the tree, because of branch compression, and because
* it frequently takes more than one node to store the chars in a key. */
@@ -150,8 +137,6 @@
* Initializes the basic data structures of the tree.
*/
private void init() {
- this.root = 0;
- this.freenode = 1;
this.length = 0;
this.compressedKeys = new StringBuilder();
this.nodes.init();
@@ -215,9 +200,9 @@
* @param value The value.
*/
public void put(final CharSequence key, final int start, final int end, final int value) {
- final int newCapacity = this.getNodeCount() + end - start + 1;
+ final int newCapacity = this.nodes.getNodeCount() + end - start + 1;
this.nodes.ensureCapacity(newCapacity);
- this.root = put(this.root, key, start, end, value);
+ put(this.nodes.getRootNodeIndex(), key, start, end, value);
}
/**
@@ -257,7 +242,7 @@
return currentNodeIndex;
} else {
/* This node is not a zero-terminated node. We need to create one to hold the value. */
- final int newNodeIndex = createNode();
+ final int newNodeIndex = this.nodes.createNode();
/* In addition to adding a node, we are adding a mapped pair here. */
this.length++;
/* We are interposing the new node between the parent and the current node. */
@@ -295,7 +280,7 @@
* @return The index to the newly-created node.
*/
private int createBranch(final CharSequence key, final int start, final int end, final int value) {
- final int currentNodeIndex = createNode();
+ final int currentNodeIndex = this.nodes.createNode();
final int len = end - start;
/* Holds data. */
this.nodes.setEqual(currentNodeIndex, value);
@@ -332,7 +317,7 @@
this.nodes.setKeyChar(nodeIndex, this.compressedKeys.charAt(this.nodes.getLow(nodeIndex)));
/* Create and initialize the new node. */
- final int newNodeIndex = createNode();
+ final int newNodeIndex = this.nodes.createNode();
this.nodes.setLow(newNodeIndex, this.nodes.getLow(nodeIndex));
this.nodes.setEqual(newNodeIndex, this.nodes.getEqual(nodeIndex));
this.nodes.setHigh(newNodeIndex, this.nodes.getHigh(nodeIndex));
@@ -435,7 +420,7 @@
* @return The index to the node containing the value of {@code key} if it is in the map. Otherwise, returns -1.
*/
int getNodeIndex(final CharSequence key, final int start, final int end) {
- int currentNodeIndex = this.root;
+ int currentNodeIndex = this.nodes.getRootNodeIndex();
int i = start;
char c;
@@ -479,35 +464,11 @@
return this.length;
}
- /**
- * Returns the number of nodes in the tree.
- * @return The number of nodes in the tree.
- */
- public int getNodeCount() {
- return this.freenode;
- }
-
- /**
- * Allocates an index for a new node, after first checking for an overflow.
- * @return The index to the new node.
- */
- private int createNode() {
- if (this.freenode >= Character.MAX_VALUE) {
- throw new IllegalStateException("Node capacity of " + this.getClass().getName() + " is limited to "
- + Integer.toString(Character.MAX_VALUE + 1));
- }
- final int newNode = this.freenode;
- this.freenode ++;
- return newNode;
- }
-
@Override
public TernaryTree clone() {
final TernaryNodes newNodes = this.nodes.clone();
final TernaryTree t = new TernaryTree(newNodes);
t.compressedKeys = new StringBuilder(this.compressedKeys);
- t.root = this.root;
- t.freenode = this.freenode;
t.length = this.length;
return t;
@@ -577,13 +538,13 @@
balance();
/* Redimension the node arrays. */
- this.nodes.resize(this.freenode);
+ this.nodes.resize(this.nodes.getNodeCount());
/* Compact the compressedKeys. */
final StringBuilder kx = new StringBuilder();
final TernaryNodes nodes = this.nodes.createInstance();
final TernaryTree map = new TernaryTree(nodes);
- compact(kx, map, this.root);
+ compact(kx, map, this.nodes.getRootNodeIndex());
this.compressedKeys = kx;
this.compressedKeys.trimToSize();
}
@@ -736,7 +697,7 @@
public void rewind() {
this.ns.removeAllElements();
this.ks.setLength(0);
- this.cur = TernaryTree.this.root;
+ this.cur = TernaryTree.this.nodes.getRootNodeIndex();
run();
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-22 13:55:46 UTC (rev 11538)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-22 16:41:53 UTC (rev 11539)
@@ -155,7 +155,7 @@
Assert.assertEquals(4, map.size());
/* TODO: We don't fully understand the node count here. */
- Assert.assertEquals(11, map.getNodeCount());
+ Assert.assertEquals(11, map.getNodes().getNodeCount());
}
/**
@@ -177,6 +177,15 @@
}
/**
+ * Test to ensure that the map behaves properly when trying to retrieve an item when nothing has been put into it.
+ */
+ @Test
+ public void testGetOnEmptyTree() {
+ final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+ Assert.assertEquals(-1, map.get("This is a test"));
+ }
+
+ /**
* A test culled from a real-world failure. Add a compressed node. Add another node that should decompress the
* first one. Then add a node at the decompression point.
*/
@@ -264,7 +273,7 @@
final TernaryTree map = new TernaryTree(new TernaryNodesChar());
map.put("superset", 2019);
- Assert.assertEquals(2, map.getNodeCount());
+ Assert.assertEquals(2, map.getNodes().getNodeCount());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2019, 0, Character.MAX_VALUE);
Assert.assertEquals("superset\u0000", map.getCompressedKeys());
@@ -273,7 +282,7 @@
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
map.put("super", 2007);
- Assert.assertEquals(9, map.getNodeCount());
+ Assert.assertEquals(9, map.getNodes().getNodeCount());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 's');
testNode(map, 2, 0, 3, 0, 'u');
@@ -289,7 +298,7 @@
Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
map.put("sup", 1941);
- Assert.assertEquals(10, map.getNodeCount());
+ Assert.assertEquals(10, map.getNodes().getNodeCount());
testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
testNode(map, 1, 0, 2, 0, 's');
testNode(map, 2, 0, 3, 0, 'u');
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-22 13:55:53
|
Revision: 11538
http://sourceforge.net/p/foray/code/11538
Author: victormote
Date: 2019-03-22 13:55:46 +0000 (Fri, 22 Mar 2019)
Log Message:
-----------
Add some tests and some test-oriented code, related to TernaryTree.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-21 17:00:17 UTC (rev 11537)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodes.java 2019-03-22 13:55:46 UTC (rev 11538)
@@ -53,6 +53,93 @@
/** Constant needed for serialization. */
private static final long serialVersionUID = 2866689417641820196L;
+ /**
+ * A notional Node for {@link TernaryNodes}, useful mostly for iterators and debugging.
+ * Instances of this class are expected to be short-lived and used only for those purposes.
+ */
+ public class Node {
+
+ /** The index for this node. */
+ private int index;
+
+ /** The low for this node. */
+ private int low;
+
+ /** The equal for this node. */
+ private int equal;
+
+ /** The high for this node. */
+ private int high;
+
+ /** The keyChar for this node. */
+ private char keyChar;
+
+ /**
+ * Returns the index.
+ * @return The index.
+ */
+ public int getIndex() {
+ return this.index;
+ }
+
+ /**
+ * Returns the low.
+ * @return The low.
+ */
+ public int getLow() {
+ return this.low;
+ }
+
+ /**
+ * Returns the equal.
+ * @return The equal.
+ */
+ public int getEqual() {
+ return this.equal;
+ }
+
+ /**
+ * Returns the high.
+ * @return The high.
+ */
+ public int getHigh() {
+ return this.high;
+ }
+
+ /**
+ * Returns the keyChar.
+ * @return The keyChar.
+ */
+ public char getKeyChar() {
+ return this.keyChar;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("index: %5d, low: %5d, equal: %5d, high: %5d, key: %4x",
+ this.index, this.low, this.equal, this.high, (int) this.keyChar);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (! (other instanceof Node)) {
+ return false;
+ }
+ final Node otherNode = (Node) other;
+ if (this.index != otherNode.index
+ || this.low != otherNode.low
+ || this.equal != otherNode.equal
+ || this.high != otherNode.high
+ || this.keyChar != otherNode.keyChar) {
+ return false;
+ }
+ return true;
+ }
+ }
+
/** The array of chars representing the "key". */
private char[] keyChar;
@@ -204,4 +291,23 @@
*/
protected abstract void resizeIndexes(int newSize);
+ /**
+ * Creates and returns a notional Node for a given index.
+ * PLEASE NOTE: This method should NOT be used for ordinary processing as that would result in a lot of unnecessary
+ * object creation and garbage collection.
+ * Use the getters and setters for ordinary processing.
+ * It is expected that this method should be used ONLY for testing and iteration.
+ * @param index The index to the node.
+ * @return A new Node instance containing the data for the reqested node.
+ */
+ Node createNotionalNode(final int index) {
+ final Node node = new Node();
+ node.index = index;
+ node.low = getLow(index);
+ node.equal = getEqual(index);
+ node.high = getHigh(index);
+ node.keyChar = getKeyChar(index);
+ return node;
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-21 17:00:17 UTC (rev 11537)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTree.java 2019-03-22 13:55:46 UTC (rev 11538)
@@ -418,6 +418,23 @@
* @return The mapped value, if {@code key} is in the map. Otherwise, returns -1.
*/
public int get(final CharSequence key, final int start, final int end) {
+ final int nodeIndexForKey = this.getNodeIndex(key, start, end);
+ if (nodeIndexForKey < 0) {
+ return -1;
+ } else {
+ return this.nodes.getEqual(nodeIndexForKey);
+ }
+ }
+
+ /**
+ * Returns the index to the node containing a given key.
+ * @param key The key whose value is needed.
+ * @param start The index to the first element in {@code key} which should be considered part of the key.
+ * @param end The index to the first element in {@code key}, after {@code start}, which should NOT be
+ * considered part of the key.
+ * @return The index to the node containing the value of {@code key} if it is in the map. Otherwise, returns -1.
+ */
+ int getNodeIndex(final CharSequence key, final int start, final int end) {
int currentNodeIndex = this.root;
int i = start;
char c;
@@ -426,7 +443,7 @@
if (this.nodes.getKeyChar(currentNodeIndex) == Character.MAX_VALUE) {
if (CharSequenceUtils.compareNullTerminated(
this.compressedKeys, this.nodes.getLow(currentNodeIndex), key, i, end) == 0) {
- return this.nodes.getEqual(currentNodeIndex);
+ return currentNodeIndex;
}
return -1;
}
@@ -440,7 +457,7 @@
final int difference = c - this.nodes.getKeyChar(currentNodeIndex);
if (difference == 0) {
if (c == 0) {
- return this.nodes.getEqual(currentNodeIndex);
+ return currentNodeIndex;
}
i++;
currentNodeIndex = this.nodes.getEqual(currentNodeIndex);
@@ -860,4 +877,13 @@
}
+ /**
+ * Returns the compressed keys.
+ * This is useful mostly for testing.
+ * @return The compressed keys.
+ */
+ String getCompressedKeys() {
+ return this.compressedKeys.toString();
+ }
+
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-21 17:00:17 UTC (rev 11537)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-22 13:55:46 UTC (rev 11538)
@@ -59,6 +59,18 @@
}
/**
+ * Test of a put where the key already exists in the map.
+ */
+ @Test
+ public void testPutForExistingKey() {
+ final String actual = this.out.put("Key 4", "New Value 4");
+ /* Make sure the old value was returned. */
+ Assert.assertEquals("Value 4", actual);
+ /* Make sure the new value is now returned by a get. */
+ Assert.assertEquals("New Value 4", out.get("Key 4"));
+ }
+
+ /**
* Test method for {@link org.foray.common.data.TernaryTreeMap#size()}.
*/
@Test
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-21 17:00:17 UTC (rev 11537)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeTests.java 2019-03-22 13:55:46 UTC (rev 11538)
@@ -237,4 +237,73 @@
Assert.assertEquals('c', actual.get(3).getValue());
}
+ /**
+ * Makes assertions about a given node.
+ * @param map The tree being tested.
+ * @param index The index into {@code map}.
+ * @param expectedLow The expected low.
+ * @param expectedEqual The expected equal.
+ * @param expectedHigh The expected high.
+ * @param expectedKeyChar The expected keyChar value.
+ */
+ private void testNode(final TernaryTree map, final int index, final int expectedLow, final int expectedEqual,
+ final int expectedHigh, final char expectedKeyChar) {
+ final TernaryNodes.Node node = map.getNodes().createNotionalNode(index);
+ Assert.assertEquals(index, node.getIndex());
+ Assert.assertEquals(expectedLow, node.getLow());
+ Assert.assertEquals(expectedEqual, node.getEqual());
+ Assert.assertEquals(expectedHigh, node.getHigh());
+ Assert.assertEquals(expectedKeyChar, node.getKeyChar());
+ }
+
+ /**
+ * Test of a longer key first, following by a shorter word that is a subset of the longer.
+ */
+ @Test
+ public void testEnclosedWord() {
+ final TernaryTree map = new TernaryTree(new TernaryNodesChar());
+
+ map.put("superset", 2019);
+ Assert.assertEquals(2, map.getNodeCount());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2019, 0, Character.MAX_VALUE);
+ Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(1, map.getNodeIndex("superset", 0, "superset".length()));
+ Assert.assertEquals(-1, map.getNodeIndex("super", 0, "super".length()));
+ Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
+
+ map.put("super", 2007);
+ Assert.assertEquals(9, map.getNodeCount());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 's');
+ testNode(map, 2, 0, 3, 0, 'u');
+ testNode(map, 3, 0, 4, 0, 'p');
+ testNode(map, 4, 0, 5, 0, 'e');
+ testNode(map, 5, 0, 8, 0, 'r');
+ testNode(map, 6, 0, 7, 0, 's');
+ testNode(map, 7, 6, 2019, 0, Character.MAX_VALUE);
+ testNode(map, 8, 0, 2007, 6, Character.MIN_VALUE);
+ Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(7, map.getNodeIndex("superset", 0, "superset".length()));
+ Assert.assertEquals(8, map.getNodeIndex("super", 0, "super".length()));
+ Assert.assertEquals(-1, map.getNodeIndex("sup", 0, "sup".length()));
+
+ map.put("sup", 1941);
+ Assert.assertEquals(10, map.getNodeCount());
+ testNode(map, 0, 0, 0, 0, Character.MIN_VALUE);
+ testNode(map, 1, 0, 2, 0, 's');
+ testNode(map, 2, 0, 3, 0, 'u');
+ testNode(map, 3, 0, 9, 0, 'p');
+ testNode(map, 4, 0, 5, 0, 'e');
+ testNode(map, 5, 0, 8, 0, 'r');
+ testNode(map, 6, 0, 7, 0, 's');
+ testNode(map, 7, 6, 2019, 0, Character.MAX_VALUE);
+ testNode(map, 8, 0, 2007, 6, Character.MIN_VALUE);
+ testNode(map, 9, 0, 1941, 4, Character.MIN_VALUE);
+ Assert.assertEquals("superset\u0000", map.getCompressedKeys());
+ Assert.assertEquals(7, map.getNodeIndex("superset", 0, "superset".length()));
+ Assert.assertEquals(8, map.getNodeIndex("super", 0, "super".length()));
+ Assert.assertEquals(9, map.getNodeIndex("sup", 0, "sup".length()));
+ }
+
}
Modified: trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java
===================================================================
--- trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-21 17:00:17 UTC (rev 11537)
+++ trunk/foray/foray-hyphen/src/main/java/org/foray/hyphen/SegmentDictionary.java 2019-03-22 13:55:46 UTC (rev 11538)
@@ -44,7 +44,7 @@
private static final long serialVersionUID = -8752423281137349847L;
/** The data structure containing the dictionary words. */
- private Map<String, SegmentDictionaryWord> wordMap = new HashMap<String, SegmentDictionaryWord>();
+ private Map<CharSequence, SegmentDictionaryWord> wordMap = new HashMap<CharSequence, SegmentDictionaryWord>();
/** The array of word segments in this dictionary. */
private StringWordSegment[] wordSegments;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-21 17:00:29
|
Revision: 11537
http://sourceforge.net/p/foray/code/11537
Author: victormote
Date: 2019-03-21 17:00:17 +0000 (Thu, 21 Mar 2019)
Log Message:
-----------
Add immutable wrapper for a byte array.
Modified Paths:
--------------
trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArrayBuilder.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/IntArray.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
Added Paths:
-----------
trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArray.java
trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
Added: trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArray.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArray.java (rev 0)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArray.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2019 The FOray Project.
+ * http://www.foray.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This work is in part derived from the following work(s), used with the
+ * permission of the licensor:
+ * Apache FOP, licensed by the Apache Software Foundation
+ *
+ */
+
+/*
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ */
+
+package org.foray.common.data;
+
+import org.axsl.common.data.ByteSequence;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+/**
+ * Wrapper around an array of bytes, intended to be similar in scope and purpose to what {@link String} does for an
+ * array of chars.
+ * Instances of this class are immutable.
+ */
+public class ByteArray implements ByteSequence, Serializable {
+
+ /* *****************************************************************************************************************
+ * DEVELOPER NOTE: As methods are added to this class, please make them analogous to those in {@link String}.
+ **************************************************************************************************************** */
+
+ /** Constant needed for serialization. */
+ private static final long serialVersionUID = -8330116207758178277L;
+
+ /** The internal array. */
+ private byte[] array;
+
+ /**
+ * Constructor for an existing array.
+ * @param array The array to be wrapped. This array is copied into an internal data structure to prevent it from
+ * being changed.
+ */
+ public ByteArray(final byte... array) {
+ this.array = Arrays.copyOf(array, array.length);
+ }
+
+ /**
+ * Constructor for part of an existing array.
+ * @param array The array to be wrapped. This array is copied into an internal data structure to prevent it from
+ * being changed.
+ * @param start The index of the first element in {@code array} to be included in this instance.
+ * @param length The number of elements in {@code array} to be included in this instance.
+ */
+ public ByteArray(final byte[] array, final int start, final int length) {
+ this.array = Arrays.copyOfRange(array, start, start + length);
+ }
+
+ @Override
+ public int length() {
+ return this.array.length;
+ }
+
+ @Override
+ public byte byteAt(final int index) {
+ return this.array[index];
+ }
+
+ @Override
+ public ByteSequence subSequence(final int start, final int end) {
+ return new ByteArray(this.array, start, end - start);
+ }
+
+ @Override
+ public byte[] toArray() {
+ /* Return a defensive copy of the array. */
+ return Arrays.copyOf(this.array, this.array.length);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (other == null) {
+ return false;
+ }
+ if (! (other instanceof ByteSequence)) {
+ return false;
+ }
+ final ByteSequence otherSequence = (ByteSequence) other;
+ if (this.array.length != otherSequence.length()) {
+ return false;
+ }
+ for (int index = 0; index < this.array.length; index ++) {
+ if (byteAt(index) != otherSequence.byteAt(index)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.toString(this.array);
+ }
+
+ /**
+ * Convenience method that returns the value of the last element in this array.
+ * @return The last element in this array.
+ */
+ public byte lastByte() {
+ final int index = this.length() - 1;
+ return this.byteAt(index);
+ }
+
+}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArrayBuilder.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArrayBuilder.java 2019-03-21 05:54:45 UTC (rev 11536)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/ByteArrayBuilder.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -33,12 +33,15 @@
package org.foray.common.data;
+import org.axsl.common.data.ByteSequence;
+
import java.io.Serializable;
+import java.util.Arrays;
/**
* A vector of bytes.
*/
-public class ByteArrayBuilder implements Serializable {
+public class ByteArrayBuilder implements ByteSequence, Serializable {
/** Constant needed for serialization. */
static final long serialVersionUID = 977379027446677063L;
@@ -150,4 +153,19 @@
}
}
+ @Override
+ public byte byteAt(final int index) {
+ return this.backingArray[index];
+ }
+
+ @Override
+ public ByteSequence subSequence(final int start, final int end) {
+ return new ByteArray(this.backingArray, start, end - start);
+ }
+
+ @Override
+ public byte[] toArray() {
+ return Arrays.copyOf(this.backingArray, this.backingArray.length);
+ }
+
}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/IntArray.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/IntArray.java 2019-03-21 05:54:45 UTC (rev 11536)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/IntArray.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -40,9 +40,7 @@
public class IntArray implements IntSequence {
/* *****************************************************************************************************************
- * DEVELOPER NOTE: As methods are added to this class, please make appropriate changes to {@link IntSequence}
- * that are analogous to those in {@link CharSequence}, where possible. Where not possible, please make them
- * analogous to those in {@link String}.
+ * DEVELOPER NOTE: As methods are added to this class, please make them analogous to those in {@link String}.
**************************************************************************************************************** */
/** The internal array. */
Added: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java (rev 0)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryNodesInt.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2019 The FOray Project.
+ * http://www.foray.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This work is in part derived from the following work(s), used with the
+ * permission of the licensor:
+ * Apache FOP, licensed by the Apache Software Foundation
+ *
+ */
+
+/*
+ * $LastChangedRevision$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ */
+
+package org.foray.common.data;
+
+import java.util.Arrays;
+
+/**
+ * Implementation of {@link TernaryNodes} that uses int for the node index values.
+ */
+public class TernaryNodesInt extends TernaryNodes {
+
+ /** Constant needed for serialization. */
+ private static final long serialVersionUID = -4452990303384745674L;
+
+ /** The array of indexes to the "low" node. */
+ private int[] low;
+
+ /** The array of indexes to the "high" node. */
+ private int[] high;
+
+ /** The array of indexes to the "equal" node. */
+ private int[] equal;
+
+ @Override
+ public void initIndexes(final int blockSize) {
+ this.low = new int[blockSize];
+ this.high = new int[blockSize];
+ this.equal = new int[blockSize];
+ }
+
+ @Override
+ public int getLow(final int index) {
+ return this.low[(int) index];
+ }
+
+ @Override
+ public void setLow(final int index, final int value) {
+ this.low[index] = (char) value;
+ }
+
+ @Override
+ public int getHigh(final int index) {
+ return this.high[(int) index];
+ }
+
+ @Override
+ public void setHigh(final int index, final int value) {
+ this.high[index] = (char) value;
+ }
+
+ @Override
+ public int getEqual(final int index) {
+ return this.equal[(int) index];
+ }
+
+ @Override
+ public void setEqual(final int index, final int value) {
+ this.equal[index] = (char) value;
+ }
+
+ @Override
+ public TernaryNodesInt forceClone() {
+ final TernaryNodesInt clone = new TernaryNodesInt();
+ clone.low = Arrays.copyOf(this.low, this.low.length);
+ clone.high = Arrays.copyOf(this.high, this.high.length);
+ clone.equal = Arrays.copyOf(this.equal, this.equal.length);
+ return clone;
+ }
+
+ @Override
+ public TernaryNodesInt createInstance() {
+ return new TernaryNodesInt();
+ }
+
+ @Override
+ protected void resizeIndexes(final int newSize) {
+ this.low = Arrays.copyOf(this.low, newSize);
+ this.high = Arrays.copyOf(this.high, newSize);
+ this.equal = Arrays.copyOf(this.equal, newSize);
+ }
+
+}
Modified: trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java
===================================================================
--- trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-21 05:54:45 UTC (rev 11536)
+++ trunk/foray/foray-common/src/main/java/org/foray/common/data/TernaryTreeMap.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -51,16 +51,13 @@
/**
* Constructor.
- * @param expectedQtyOfNodes The number of key-value pairs expected to be mapped.
+ * @param nodes The data structure for holding the indexes.
+ * This should be one of {@link TernaryNodesChar} or {@link TernaryNodesInt}.
* Making an accurate estimate of this number is more important than in many {@link Map} implementations, as this
* determines the type of internal data structure that should be used.
*
*/
- public TernaryTreeMap(final int expectedQtyOfNodes) {
- TernaryNodes nodes = null;
- /* TODO: Right now, there is only one TernaryNodes implementation. Add logic here later to choose which
- * implementation to use, based on the expected quantity of nodes. */
- nodes = new TernaryNodesChar();
+ public TernaryTreeMap(final TernaryNodes nodes) {
init(nodes);
}
@@ -136,7 +133,7 @@
/* The key is not already in the map. Make a new entry. */
final int valuesIndex = size();
- this.keys.put(key, (char) valuesIndex);
+ this.keys.put(key, valuesIndex);
this.values.add(value);
return null;
}
Modified: trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java
===================================================================
--- trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-21 05:54:45 UTC (rev 11536)
+++ trunk/foray/foray-common/src/test/java/org/foray/common/data/TernaryTreeMapTests.java 2019-03-21 17:00:17 UTC (rev 11537)
@@ -48,7 +48,7 @@
*/
@Before
public void setUp() {
- this.out = new TernaryTreeMap<String>(100);
+ this.out = new TernaryTreeMap<String>(new TernaryNodesChar());
Assert.assertTrue(this.out.isEmpty());
this.out.put("Key 1", "Value 1");
this.out.put("Key 2", "Value 2");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <vic...@us...> - 2019-03-21 05:54:50
|
Revision: 11536
http://sourceforge.net/p/foray/code/11536
Author: victormote
Date: 2019-03-21 05:54:45 +0000 (Thu, 21 Mar 2019)
Log Message:
-----------
Re-serialize the parsed hyphenation patterns files using the new data scheme.
Modified Paths:
--------------
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/eng.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/fin.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/hun.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/ita.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/mah.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/pol.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/por.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/rus.jbso
===================================================================
(Binary files differ)
Modified: trunk/foray/foray-hyphen/src/main/resources/resources/org/foray/hyphen/patterns/spa.jbso
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|