OSDN Git Service

全置換えのアルゴリズムを高速化のために変更した
authorkonekoneko <test2214@hotmail.co.jp>
Thu, 9 Jul 2015 01:24:59 +0000 (10:24 +0900)
committerkonekoneko <test2214@hotmail.co.jp>
Thu, 9 Jul 2015 01:24:59 +0000 (10:24 +0900)
Common/Document.cs
Common/GapBuffer.cs
Common/LineToIndex.cs
Common/StringBuffer.cs
Common/UndoCommands.cs

index 671ab83..0e6a72e 100644 (file)
@@ -99,18 +99,24 @@ namespace FooEditEngine
         /// </summary>\r
         public int insertLength;\r
         /// <summary>\r
+        /// 更新イベントが発生した行。行が不明な場合や行をまたぐ場合はnullを指定すること。\r
+        /// </summary>\r
+        public int? row;\r
+        /// <summary>\r
         /// コンストラクター\r
         /// </summary>\r
         /// <param name="type">更新タイプ</param>\r
         /// <param name="startIndex">開始インデックス</param>\r
         /// <param name="removeLength">削除された長さ</param>\r
         /// <param name="insertLength">追加された長さ</param>\r
-        public DocumentUpdateEventArgs(UpdateType type, int startIndex, int removeLength, int insertLength)\r
+        /// <param name="row">開始行。nullを指定することができる</param>\r
+        public DocumentUpdateEventArgs(UpdateType type, int startIndex, int removeLength, int insertLength, int? row = null)\r
         {\r
             this.type = type;\r
             this.startIndex = startIndex;\r
             this.removeLength = removeLength;\r
             this.insertLength = insertLength;\r
+            this.row = row;\r
         }\r
     }\r
 \r
@@ -149,7 +155,7 @@ namespace FooEditEngine
                 this.buffer = new StringBuffer();\r
             else\r
                 this.buffer = new StringBuffer(doc.buffer);\r
-            this.buffer.Update += new DocumentUpdateEventHandler(buffer_Update);\r
+            this.buffer.Update = new DocumentUpdateEventHandler(buffer_Update);\r
             this.UpdateCalledAlways += (s, e) => { };\r
             this.Update += new DocumentUpdateEventHandler((s, e) => { });\r
             this.ChangeFireUpdateEvent += new EventHandler((s, e) => { });\r
@@ -681,7 +687,7 @@ namespace FooEditEngine
         /// </remarks>\r
         public void ReplaceAll2(string target, string pattern,bool ci = false)\r
         {\r
-            FastReplaceAllCommand cmd = new FastReplaceAllCommand(this.buffer, target, pattern,ci);\r
+            FastReplaceAllCommand cmd = new FastReplaceAllCommand(this.buffer, this.LayoutLines, target, pattern,ci);\r
             this.UndoManager.push(cmd);\r
             cmd.redo();\r
         }\r
@@ -713,7 +719,10 @@ namespace FooEditEngine
             switch (e.type)\r
             {\r
                 case UpdateType.Replace:\r
-                    this._LayoutLines.UpdateAsReplace(e.startIndex, e.removeLength, e.insertLength);\r
+                    if (e.row == null)\r
+                        this._LayoutLines.UpdateAsReplace(e.startIndex, e.removeLength, e.insertLength);\r
+                    else\r
+                        this._LayoutLines.UpdateLineAsReplace(e.row.Value, e.removeLength, e.insertLength);\r
                     break;\r
                 case UpdateType.Clear:\r
                     this._LayoutLines.Clear();\r
index a0b8bc2..ed4a972 100644 (file)
@@ -678,7 +678,7 @@ namespace Slusser.Collections.Generic
                                this._gapEnd -= count;
 
                                // Clear the contents of the gap
-                               Array.Clear(this._buffer, index, deltaCount);
+                               //Array.Clear(this._buffer, index, deltaCount);
                        }
                        else
                        {
@@ -691,7 +691,7 @@ namespace Slusser.Collections.Generic
                                this._gapEnd += count;
 
                                // Clear the contents of the gap
-                               Array.Clear(this._buffer, deltaIndex, this._gapEnd - deltaIndex);
+                               //Array.Clear(this._buffer, deltaIndex, this._gapEnd - deltaIndex);
                        }
                }
 
index 7e15546..4de8c20 100644 (file)
@@ -332,6 +332,22 @@ namespace FooEditEngine
             return result;\r
         }\r
 \r
+        internal void UpdateLineAsReplace(int row,int removedLength, int insertedLength)\r
+        {\r
+            int deltaLength = insertedLength - removedLength;\r
+\r
+            this.Lines[row] = new LineToIndexTableData(this.GetLineHeadIndex(row), this.GetLengthFromLineNumber(row) + deltaLength, true, true, null);\r
+\r
+            //行テーブルを更新する\r
+            this.UpdateLineHeadIndex(deltaLength, row, 1);\r
+\r
+            this.FoldingCollection.UpdateData(this.Document, this.GetLineHeadIndex(row), insertedLength, removedLength);\r
+\r
+            this._IsSync = false;\r
+\r
+            this.lastUpdateTicks = DateTime.Now.Ticks;\r
+        }\r
+\r
         internal void UpdateAsReplace(int index, int removedLength, int insertedLength)\r
         {\r
 #if DEBUG\r
@@ -340,6 +356,8 @@ namespace FooEditEngine
             int startRow, endRow;\r
             GetRemoveRange(index, removedLength, out startRow, out endRow);\r
 \r
+            int deltaLength = insertedLength - removedLength;\r
+\r
             var result = GetAnalyzeLength(startRow, endRow, index, removedLength, insertedLength);\r
             int HeadIndex = result.Item1;\r
             int analyzeLength = result.Item2;\r
@@ -350,8 +368,7 @@ namespace FooEditEngine
 \r
             //消すべき行が複数ある場合は消すが、そうでない場合は最適化のため長さを変えるだけにとどめておく\r
             int removeCount = endRow - startRow + 1;\r
-            int deltaLength = insertedLength - removedLength;\r
-            if(removeCount == 1 && newLines.Count == 1)\r
+            if (removeCount == 1 && newLines.Count == 1)\r
             {\r
                 this.Lines[startRow] = newLines.First();\r
             }\r
index 8abd5c9..8371e6a 100644 (file)
@@ -39,7 +39,7 @@ namespace FooEditEngine
 \r
         public StringBuffer()\r
         {\r
-            this.Update += (s, e) => { };\r
+            this.Update = (s, e) => { };\r
         }\r
 \r
         public StringBuffer(StringBuffer buffer)\r
@@ -114,7 +114,7 @@ namespace FooEditEngine
             get { return this.buf.Count; }\r
         }\r
 \r
-        internal event DocumentUpdateEventHandler Update;\r
+        internal DocumentUpdateEventHandler Update;\r
 \r
         internal void Replace(StringBuffer buf)\r
         {\r
@@ -170,7 +170,7 @@ namespace FooEditEngine
             TextSearch ts = new TextSearch(target,ci);\r
             int left = 0, right = 0;\r
             char[] pattern_chars = pattern.ToCharArray();\r
-            while((right = ts.IndexOf(this.buf,left)) != -1)\r
+            while((right = ts.IndexOf(this.buf,left,this.buf.Count)) != -1)\r
             {\r
                 this.buf.RemoveRange(right, target.Length);\r
                 this.buf.InsertRange(right, pattern_chars, pattern.Length);\r
@@ -180,10 +180,30 @@ namespace FooEditEngine
             this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, 0, 0, buf.Count));\r
         }\r
 \r
+        internal void ReplaceAll(LineToIndexTable layoutlines,string target, string pattern, bool ci = false)\r
+        {\r
+            TextSearch ts = new TextSearch(target, ci);\r
+            char[] pattern_chars = pattern.ToCharArray();\r
+            for(int i = 0; i < layoutlines.Count; i++)\r
+            {\r
+                int lineHeadIndex = layoutlines.GetIndexFromLineNumber(i), lineLength = layoutlines.GetLengthFromLineNumber(i);\r
+                int left = lineHeadIndex, right = lineHeadIndex;\r
+                int newLineLength = lineLength;\r
+                while ((right = ts.IndexOf(this.buf, left, lineHeadIndex + newLineLength)) != -1)\r
+                {\r
+                    this.buf.RemoveRange(right, target.Length);\r
+                    this.buf.InsertRange(right, pattern_chars, pattern.Length);\r
+                    left = right + pattern.Length;\r
+                    newLineLength += pattern.Length - target.Length;\r
+                }\r
+                this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, lineHeadIndex, lineLength, newLineLength, i));\r
+            }\r
+        }\r
+\r
         internal int IndexOf(string target, int start,bool ci = false)\r
         {\r
             TextSearch ts = new TextSearch(target,ci);\r
-            return ts.IndexOf(this.buf, start);\r
+            return ts.IndexOf(this.buf, start,this.buf.Count);\r
         }\r
 \r
         /// <summary>\r
@@ -257,17 +277,17 @@ namespace FooEditEngine
                     this.qsTable[pattern[i]] = len - i;\r
             }\r
         }\r
-        public int IndexOf(GapBuffer<char> buf, int start)\r
+        public int IndexOf(GapBuffer<char> buf, int start,int end)\r
         {\r
             //QuickSearch法\r
             int buflen = buf.Count - 1;\r
             int plen = this.patternLength;\r
             int i = start;\r
-            int end = buf.Count - plen;\r
+            int search_end = end - plen;\r
             //最適化のためわざとコピペした\r
             if (this.caseInsenstive)\r
             {\r
-                while (i <= end)\r
+                while (i <= search_end)\r
                 {\r
                     int j = 0;\r
                     while (j < plen)\r
@@ -301,7 +321,7 @@ namespace FooEditEngine
             }\r
             else\r
             {\r
-                while (i <= end)\r
+                while (i <= search_end)\r
                 {\r
                     int j = 0;\r
                     while (j < plen)\r
index 40a1445..50d43c9 100644 (file)
@@ -137,12 +137,14 @@ namespace FooEditEngine
         string targetPattern;
         string replacePattern;
         bool caseInsensitve;
-        public FastReplaceAllCommand(StringBuffer buffer,string targetPattern, string replacePattern,bool ci)
+        LineToIndexTable layoutLines;
+        public FastReplaceAllCommand(StringBuffer buffer,LineToIndexTable layoutlines,string targetPattern, string replacePattern,bool ci)
         {
             this.buffer = buffer;
             this.replacePattern = replacePattern;
             this.targetPattern = targetPattern;
             this.caseInsensitve = ci;
+            this.layoutLines = layoutlines;
         }
 
         public void undo()
@@ -153,7 +155,7 @@ namespace FooEditEngine
         public void redo()
         {
             this.oldBuffer = new StringBuffer(this.buffer);
-            this.buffer.Replace(this.targetPattern, this.replacePattern,this.caseInsensitve);
+            this.buffer.ReplaceAll(this.layoutLines, this.targetPattern, this.replacePattern,this.caseInsensitve);
         }
 
         public bool marge(ICommand a)