OSDN Git Service

MMFへのアクセスをアンマネージドポインタ経由として高速化
[nmecab/NMeCabRepo2.git] / src / LibNMeCab / Core / Connector.cs
index e34ebcc..70843b2 100644 (file)
@@ -20,7 +20,8 @@ namespace NMeCab.Core
 \r
 #if MMF_MTX\r
         private MemoryMappedFile mmf;\r
-        private MemoryMappedViewAccessor matrix;\r
+        private MemoryMappedViewAccessor mmva;\r
+        private unsafe short* matrix;\r
 #else\r
         private short[] matrix;\r
 #endif\r
@@ -40,36 +41,33 @@ namespace NMeCab.Core
         }\r
 \r
 #if MMF_MTX\r
-\r
-        public void Open(string fileName)\r
+        public unsafe void Open(string fileName)\r
         {\r
-            //MMFインスタンスを生成するが、後でDisposeするために保持しておく\r
-            this.mmf = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open,\r
-                                                        null, 0L, MemoryMappedFileAccess.Read);\r
-            this.Open(this.mmf);\r
-        }\r
+            this.mmf = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, null, 0L, MemoryMappedFileAccess.Read);\r
+            this.mmva = this.mmf.CreateViewAccessor(0L, 0L, MemoryMappedFileAccess.Read);\r
 \r
-        public void Open(MemoryMappedFile mmf)\r
-        {\r
-            using (MemoryMappedViewStream stream = mmf.CreateViewStream(\r
-                                                        0L, 0L, MemoryMappedFileAccess.Read))\r
-            using (BinaryReader reader = new BinaryReader(stream))\r
+            byte* ptr = null;\r
+            this.mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);\r
+\r
+            using (var stream = mmf.CreateViewStream(0L, 0L, MemoryMappedFileAccess.Read))\r
+            using (var reader = new BinaryReader(stream))\r
             {\r
                 this.LSize = reader.ReadUInt16();\r
                 this.RSize = reader.ReadUInt16();\r
 \r
-                long offset = stream.Position;\r
-                long size = this.LSize * this.RSize * sizeof(short);\r
-                this.matrix = mmf.CreateViewAccessor(offset, size, MemoryMappedFileAccess.Read);\r
+                long fSize = stream.Position + sizeof(short) * this.LSize * this.RSize;\r
+                if (this.mmva.Capacity < fSize)\r
+                    throw new MeCabInvalidFileException("file size is invalid", fileName);\r
+\r
+                ptr += stream.Position;\r
+                this.matrix = (short*)ptr;\r
             }\r
         }\r
-\r
 #else\r
-\r
         public void Open(string fileName)\r
         {\r
-            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))\r
-            using (BinaryReader reader = new BinaryReader(stream))\r
+            using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))\r
+            using (var reader = new BinaryReader(stream))\r
             {\r
                 this.Open(reader, fileName);\r
             }\r
@@ -89,22 +87,16 @@ namespace NMeCab.Core
             if (reader.BaseStream.ReadByte() != -1)\r
                 throw new MeCabInvalidFileException("file size is invalid", fileName);\r
         }\r
-\r
 #endif\r
 \r
         #endregion\r
 \r
         #region Cost\r
 \r
-        public int Cost(MeCabNode lNode, MeCabNode rNode)\r
+        public unsafe int Cost(MeCabNode lNode, MeCabNode rNode)\r
         {\r
             int pos = lNode.RCAttr + this.LSize * rNode.LCAttr;\r
-\r
-#if MMF_MTX\r
-            return this.matrix.ReadInt16(pos * sizeof(short)) + rNode.WCost;\r
-#else\r
             return this.matrix[pos] + rNode.WCost;\r
-#endif\r
         }\r
 \r
         #endregion\r
@@ -129,8 +121,14 @@ namespace NMeCab.Core
             if (disposing)\r
             {\r
 #if MMF_MTX\r
-                if (this.mmf != null) this.mmf.Dispose();\r
-                if (this.matrix != null) this.matrix.Dispose();\r
+                if (this.mmva != null)\r
+                {\r
+                    this.mmva.SafeMemoryMappedViewHandle.ReleasePointer();\r
+                    this.mmva.Dispose();\r
+                }\r
+\r
+                if (this.mmf != null)\r
+                    this.mmf.Dispose();\r
 #endif\r
             }\r
 \r