Browse Source

Remove dictionary from HeightTree.

pull/15/head
Daniel Grunwald 15 years ago
parent
commit
27d20d4daf
  1. 30
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Document/CollapsingTests.cs
  2. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Document/HeightTests.cs
  3. 23
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/HeightTree.cs
  4. 6
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs

30
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Document/CollapsingTests.cs

@ -28,13 +28,13 @@ namespace ICSharpCode.AvalonEdit.Document @@ -28,13 +28,13 @@ namespace ICSharpCode.AvalonEdit.Document
{
CollapsedLineSection sec1 = heightTree.CollapseText(document.GetLineByNumber(from), document.GetLineByNumber(to));
for (int i = 1; i < from; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
for (int i = from; i <= to; i++) {
Assert.IsTrue(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsTrue(heightTree.GetIsCollapsed(i));
}
for (int i = to + 1; i <= 10; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
return sec1;
@ -52,7 +52,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -52,7 +52,7 @@ namespace ICSharpCode.AvalonEdit.Document
CollapsedLineSection sec1 = heightTree.CollapseText(document.GetLineByNumber(4), document.GetLineByNumber(6));
sec1.Uncollapse();
for (int i = 1; i <= 10; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
}
@ -65,7 +65,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -65,7 +65,7 @@ namespace ICSharpCode.AvalonEdit.Document
try {
SimpleCheck(from, to).Uncollapse();
for (int i = 1; i <= 10; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
} catch {
@ -82,13 +82,13 @@ namespace ICSharpCode.AvalonEdit.Document @@ -82,13 +82,13 @@ namespace ICSharpCode.AvalonEdit.Document
CollapsedLineSection sec1 = heightTree.CollapseText(document.GetLineByNumber(4), document.GetLineByNumber(6));
document.Insert(document.GetLineByNumber(5).Offset, "a\nb\nc");
for (int i = 1; i < 4; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
for (int i = 4; i <= 8; i++) {
Assert.IsTrue(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsTrue(heightTree.GetIsCollapsed(i));
}
for (int i = 9; i <= 12; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
}
@ -101,13 +101,13 @@ namespace ICSharpCode.AvalonEdit.Document @@ -101,13 +101,13 @@ namespace ICSharpCode.AvalonEdit.Document
int line6Offset = document.GetLineByNumber(6).Offset;
document.Remove(line4Offset, line6Offset - line4Offset);
for (int i = 1; i < 3; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
for (int i = 3; i <= 5; i++) {
Assert.IsTrue(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsTrue(heightTree.GetIsCollapsed(i));
}
for (int i = 6; i <= 8; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
}
@ -120,13 +120,13 @@ namespace ICSharpCode.AvalonEdit.Document @@ -120,13 +120,13 @@ namespace ICSharpCode.AvalonEdit.Document
int line8Offset = document.GetLineByNumber(8).Offset;
document.Remove(line5Offset, line8Offset - line5Offset);
for (int i = 1; i < 3; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
for (int i = 3; i <= 5; i++) {
Assert.IsTrue(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsTrue(heightTree.GetIsCollapsed(i));
}
for (int i = 6; i <= 7; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
}
@ -138,7 +138,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -138,7 +138,7 @@ namespace ICSharpCode.AvalonEdit.Document
int line3Offset = document.GetLineByNumber(3).Offset;
document.Remove(line3Offset - 1, 1);
for (int i = 1; i <= 9; i++) {
Assert.IsFalse(heightTree.GetIsCollapsed(document.GetLineByNumber(i)));
Assert.IsFalse(heightTree.GetIsCollapsed(i));
}
CheckHeights();
Assert.AreSame(null, sec1.Start);

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Document/HeightTests.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -62,7 +62,7 @@ namespace ICSharpCode.AvalonEdit.Document
internal static void CheckHeights(TextDocument document, HeightTree heightTree)
{
double[] heights = document.Lines.Select(l => heightTree.GetIsCollapsed(l) ? 0 : heightTree.GetHeight(l)).ToArray();
double[] heights = document.Lines.Select(l => heightTree.GetIsCollapsed(l.LineNumber) ? 0 : heightTree.GetHeight(l)).ToArray();
double[] visualPositions = new double[document.LineCount+1];
for (int i = 0; i < heights.Length; i++) {
visualPositions[i+1]=visualPositions[i]+heights[i];

23
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/HeightTree.cs

@ -17,8 +17,8 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -17,8 +17,8 @@ namespace ICSharpCode.AvalonEdit.Rendering
sealed class HeightTree : ILineTracker, IDisposable
{
// TODO: Optimize this. This tree takes alot of memory.
// (56 bytes for HeightTreeNode + ca. 25 bytes per node for the dictionary)
// We should try to get rid of the dictionary and find height nodes per index.
// (56 bytes for HeightTreeNode
// We should try to get rid of the dictionary and find height nodes per index. (DONE!)
// And we might do much better by compressing lines with the same height into a single node.
// That would also improve load times because we would always start with just a single node.
@ -39,7 +39,6 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -39,7 +39,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
#region Constructor
readonly TextDocument document;
Dictionary<DocumentLine, HeightTreeNode> dict;
HeightTreeNode root;
WeakLineTracker weakLineTracker;
@ -55,7 +54,6 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -55,7 +54,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
{
if (weakLineTracker != null)
weakLineTracker.Deregister();
this.dict = null;
this.root = null;
this.weakLineTracker = null;
}
@ -64,7 +62,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -64,7 +62,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
HeightTreeNode GetNode(DocumentLine ls)
{
return dict[ls];
return GetNodeByIndex(ls.LineNumber - 1);
}
#endregion
@ -83,13 +81,10 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -83,13 +81,10 @@ namespace ICSharpCode.AvalonEdit.Rendering
s.End = null;
}
dict = new Dictionary<DocumentLine, HeightTreeNode>((int)(document.LineCount / 0.7));
HeightTreeNode[] nodes = new HeightTreeNode[document.LineCount];
int lineNumber = 0;
foreach (DocumentLine ls in document.Lines) {
HeightTreeNode node = new HeightTreeNode(ls, DefaultLineHeight);
dict.Add(ls, node);
nodes[lineNumber++] = node;
nodes[lineNumber++] = new HeightTreeNode(ls, DefaultLineHeight);
}
Debug.Assert(nodes.Length > 0);
// now build the corresponding balanced tree
@ -135,11 +130,11 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -135,11 +130,11 @@ namespace ICSharpCode.AvalonEdit.Rendering
cs.End = null;
} else if (cs.Start == line) {
Uncollapse(cs);
cs.Start = GetLineByNumber(line.LineNumber + 1);
cs.Start = line.NextLine;
AddCollapsedSection(cs, cs.End.LineNumber - cs.Start.LineNumber + 1);
} else if (cs.End == line) {
Uncollapse(cs);
cs.End = GetLineByNumber(line.LineNumber - 1);
cs.End = line.PreviousLine;
AddCollapsedSection(cs, cs.End.LineNumber - cs.Start.LineNumber + 1);
}
}
@ -149,7 +144,6 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -149,7 +144,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
// clear collapsedSections from removed line: prevent damage if removed line is in "nodesToCheckForMerging"
node.lineNode.collapsedSections = null;
EndRemoval();
dict.Remove(line);
}
// void ILineTracker.AfterRemoveLine(DocumentLine line)
@ -168,7 +162,6 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -168,7 +162,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
HeightTreeNode InsertAfter(HeightTreeNode node, DocumentLine newLine)
{
HeightTreeNode newNode = new HeightTreeNode(newLine, DefaultLineHeight);
dict.Add(newLine, newNode);
if (node.right == null) {
if (node.lineNode.collapsedSections != null) {
// we are inserting directly after node - so copy all collapsedSections
@ -485,9 +478,9 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -485,9 +478,9 @@ namespace ICSharpCode.AvalonEdit.Rendering
UpdateAfterChildrenChange(node);
}
public bool GetIsCollapsed(DocumentLine line)
public bool GetIsCollapsed(int lineNumber)
{
var node = GetNode(line);
var node = GetNodeByIndex(lineNumber - 1);
return node.lineNode.IsDirectlyCollapsed || GetIsCollapedFromNode(node);
}

6
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs

@ -564,7 +564,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -564,7 +564,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
TextRunProperties globalTextRunProperties = CreateGlobalTextRunProperties();
VisualLineTextParagraphProperties paragraphProperties = CreateParagraphProperties(globalTextRunProperties);
while (heightTree.GetIsCollapsed(documentLine)) {
while (heightTree.GetIsCollapsed(documentLine.LineNumber)) {
documentLine = documentLine.PreviousLine;
}
@ -823,7 +823,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -823,7 +823,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
IVisualLineTransformer[] lineTransformersArray,
Size availableSize)
{
if (heightTree.GetIsCollapsed(documentLine))
if (heightTree.GetIsCollapsed(documentLine.LineNumber))
throw new InvalidOperationException("Trying to build visual line from collapsed line");
Debug.WriteLine("Building line " + documentLine.LineNumber);
@ -839,7 +839,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -839,7 +839,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
#if DEBUG
for (int i = visualLine.FirstDocumentLine.LineNumber + 1; i <= visualLine.LastDocumentLine.LineNumber; i++) {
if (!heightTree.GetIsCollapsed(document.GetLineByNumber(i)))
if (!heightTree.GetIsCollapsed(i))
throw new InvalidOperationException("Line " + i + " was skipped by a VisualLineElementGenerator, but it is not collapsed.");
}
#endif

Loading…
Cancel
Save