@@ -91,6 +91,12 @@ public class TreeLineTracker implements ILineTracker {
9191 */
9292 private static final String NO_DELIM = "" ; //$NON-NLS-1$
9393
94+ // Delimiter type constants for memory optimization
95+ private static final byte DELIM_NONE = 0 ; // "" - no delimiter
96+ private static final byte DELIM_LF = 1 ; // "\n" - Unix/Linux
97+ private static final byte DELIM_CR = 2 ; // "\r" - old Mac
98+ private static final byte DELIM_CRLF = 3 ; // "\r\n" - Windows
99+
94100 /**
95101 * A node represents one line. Its character and line offsets are 0-based and
96102 * relative to the subtree covered by the node. All nodes under the left subtree
@@ -100,7 +106,7 @@ public class TreeLineTracker implements ILineTracker {
100106 private static final class Node {
101107 Node (int length , String delimiter ) {
102108 this .length = length ;
103- this .delimiter = delimiter ;
109+ this .delimiterType = stringToDelimiterType ( delimiter ) ;
104110 }
105111
106112 /**
@@ -115,8 +121,11 @@ private static final class Node {
115121 int offset ;
116122 /** The number of characters in this line. */
117123 int length ;
118- /** The line delimiter of this line, needed to answer the delimiter query. */
119- String delimiter ;
124+ /**
125+ * The line delimiter type of this line (0=none, 1=\n, 2=\r, 3=\r\n). Memory
126+ * optimized.
127+ */
128+ byte delimiterType ;
120129 /** The parent node, <code>null</code> if this is the root node. */
121130 Node parent ;
122131 /** The left subtree, possibly <code>null</code>. */
@@ -126,6 +135,24 @@ private static final class Node {
126135 /** The balance factor. */
127136 byte balance ;
128137
138+ /**
139+ * Returns the delimiter string for this node.
140+ *
141+ * @return the delimiter string
142+ */
143+ String getDelimiter () {
144+ return delimiterTypeToString (delimiterType );
145+ }
146+
147+ /**
148+ * Sets the delimiter for this node.
149+ *
150+ * @param delimiter the delimiter string
151+ */
152+ void setDelimiter (String delimiter ) {
153+ this .delimiterType = stringToDelimiterType (delimiter );
154+ }
155+
129156 @ Override
130157 public final String toString () {
131158 String bal ;
@@ -148,7 +175,8 @@ public final String toString() {
148175 default :
149176 bal = Byte .toString (balance );
150177 }
151- return "[" + offset + "+" + pureLength () + "+" + delimiter .length () + "|" + line + "|" + bal + "]" ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
178+ String delim = getDelimiter ();
179+ return "[" + offset + "+" + pureLength () + "+" + delim .length () + "|" + line + "|" + bal + "]" ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
152180 }
153181
154182 /**
@@ -157,7 +185,49 @@ public final String toString() {
157185 * @return the pure line length
158186 */
159187 int pureLength () {
160- return length - delimiter .length ();
188+ return length - getDelimiter ().length ();
189+ }
190+ }
191+
192+ /**
193+ * Converts a delimiter string to a delimiter type byte.
194+ *
195+ * @param delimiter the delimiter string
196+ * @return the delimiter type
197+ */
198+ private static byte stringToDelimiterType (String delimiter ) {
199+ if (delimiter == null || delimiter .isEmpty () || delimiter == NO_DELIM ) {
200+ return DELIM_NONE ;
201+ }
202+ switch (delimiter ) {
203+ case "\n " :
204+ return DELIM_LF ;
205+ case "\r " :
206+ return DELIM_CR ;
207+ case "\r \n " :
208+ return DELIM_CRLF ;
209+ default :
210+ return DELIM_NONE ;
211+ }
212+ }
213+
214+ /**
215+ * Converts a delimiter type byte to a delimiter string.
216+ *
217+ * @param delimiterType the delimiter type
218+ * @return the delimiter string
219+ */
220+ private static String delimiterTypeToString (byte delimiterType ) {
221+ switch (delimiterType ) {
222+ case DELIM_LF :
223+ return DELIMITERS [1 ]; // "\n"
224+ case DELIM_CR :
225+ return DELIMITERS [0 ]; // "\r"
226+ case DELIM_CRLF :
227+ return DELIMITERS [2 ]; // "\r\n"
228+ case DELIM_NONE :
229+ default :
230+ return NO_DELIM ;
161231 }
162232 }
163233
@@ -203,7 +273,7 @@ public TreeLineTracker(ListLineTracker tracker) {
203273 node = insertAfter (node , length , delim );
204274 }
205275
206- if (node . delimiter != NO_DELIM ) {
276+ if (! NO_DELIM . equals ( node . getDelimiter ()) ) {
207277 insertAfter (node , 0 , NO_DELIM );
208278 }
209279
@@ -693,13 +763,13 @@ private void replaceInternal(Node node, String text, int length, int firstLineDe
693763 // b) more lines to add between two chunks of the first node
694764 // remember what we split off the first line
695765 int remainder = firstLineDelta - length ;
696- String remDelim = node .delimiter ;
766+ String remDelim = node .getDelimiter () ;
697767
698768 // join the first line with the first added
699769 int consumed = info .delimiterIndex + info .delimiterLength ;
700770 int delta = consumed - firstLineDelta ;
701771 updateLength (node , delta );
702- node .delimiter = info .delimiter ;
772+ node .setDelimiter ( info .delimiter ) ;
703773
704774 // Inline addlines start
705775 info = nextDelimiterInfo (text , consumed );
@@ -755,7 +825,7 @@ private void replaceFromTo(Node node, Node last, String text, int length, int fi
755825 // join the first line with the first added
756826 int consumed = info .delimiterIndex + info .delimiterLength ;
757827 updateLength (node , consumed - firstLineDelta );
758- node .delimiter = info .delimiter ;
828+ node .setDelimiter ( info .delimiter ) ;
759829 length -= firstLineDelta ;
760830
761831 // Inline addLines start
@@ -802,7 +872,7 @@ private void updateLength(Node node, int delta) {
802872
803873 // check deletion
804874 final int lineDelta ;
805- boolean delete = node .length == 0 && node . delimiter != NO_DELIM ;
875+ boolean delete = node .length == 0 && ! NO_DELIM . equals ( node . getDelimiter ()) ;
806876 if (delete ) {
807877 lineDelta = -1 ;
808878 } else {
@@ -1147,7 +1217,8 @@ protected DelimiterInfo nextDelimiterInfo(String text, int offset) {
11471217 @ Override
11481218 public final String getLineDelimiter (int line ) throws BadLocationException {
11491219 Node node = nodeByLine (line );
1150- return node .delimiter == NO_DELIM ? null : node .delimiter ;
1220+ String delimiter = node .getDelimiter ();
1221+ return NO_DELIM .equals (delimiter ) ? null : delimiter ;
11511222 }
11521223
11531224 @ Override
0 commit comments