1 #Region "Microsoft.VisualBasic::65525e4d64b78f52b8642e2e423677a2, Microsoft.VisualBasic.Core\ApplicationServices\Tools\MMFProtocol\MapStream\MSReader.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class IMapBase
35     
36     '         Properties: URI
37     
38     '         Constructor: (+1 OverloadsSub New
39     
40     '         Function: Read, ToString
41     
42     '         Sub: (+2 Overloads) Dispose
43     
44     '     Class MSIOReader
45     
46     '         Constructor: (+1 OverloadsSub New
47     
48     '         Function: ReadBadge, ToString
49     
50     '         Sub: __clientThreadElapsed, __threadElapsed, Update
51     
52     
53     ' /********************************************************************************/
54
55 #End Region
56
57 Imports System.IO.MemoryMappedFiles
58 Imports Microsoft.VisualBasic.Parallel
59
60 Namespace MMFProtocol.MapStream
61
62     Public MustInherit Class IMapBase : Implements IDisposable
63
64         Public ReadOnly Property URI As String
65
66         Protected _chunkBuffer As Byte()
67         Protected _mmfileStream As MemoryMappedFile
68
69         Sub New(uri As String, ChunkSize As Long)
70             Me._URI = uri
71             Me._chunkBuffer = New Byte(ChunkSize - 1) {}
72         End Sub
73
74         Public Function Read() As MMFStream
75             Call _mmfileStream.CreateViewStream.Read(_chunkBuffer, Scan0, _chunkBuffer.Length)
76             Return New MMFStream(_chunkBuffer)
77         End Function
78
79         Public Overrides Function ToString() As String
80             Return URI
81         End Function
82
83 #Region "IDisposable Support"
84         Protected disposedValue As Boolean To detect redundant calls
85
86         ' IDisposable
87         Protected Overridable Sub Dispose(disposing As Boolean)
88             If Not Me.disposedValue Then
89                 If disposing Then
90                     ' TODO: dispose managed state (managed objects).
91                 End If
92
93                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
94                 ' TODO: set large fields to null.
95             End If
96             Me.disposedValue = True
97         End Sub
98
99         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
100         'Protected Overrides Sub Finalize()
101         '    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
102         '    Dispose(False)
103         '    MyBase.Finalize()
104         'End Sub
105
106         ' This code added by Visual Basic to correctly implement the disposable pattern.
107         Public Sub Dispose() Implements IDisposable.Dispose
108             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
109             Dispose(True)
110             ' TODO: uncomment the following line if Finalize() is overridden above.
111             ' GC.SuppressFinalize(Me)
112         End Sub
113 #End Region
114     End Class
115
116     Public Class MSIOReader : Inherits IMapBase
117         Implements IDisposable
118
119         ''' <summary>
120         ''' 内存映射文件的更新标识符
121         ''' </summary>
122         ''' <remarks></remarks>
123         Dim _udtBadge As Long
124         Dim _mappedStream As MMFStream
125
126         ReadOnly _dataArrivals As DataArrival
127
128         ''' <summary>
129         ''' 
130         ''' </summary>
131         ''' <param name="uri"></param>
132         ''' <param name="callback"></param>
133         ''' <param name="ChunkSize">内存映射文件的数据块的预分配大小</param>
134         Sub New(uri As String, callback As DataArrival, ChunkSize As Long)
135             Call MyBase.New(uri, ChunkSize)
136             _mmfileStream = MemoryMappedFile.OpenExisting(uri)
137             _dataArrivals = callback
138
139             Call Parallel.RunTask(AddressOf __threadElapsed)
140         End Sub
141
142         Public Overrides Function ToString() As String
143             Return $"{URI} ===> {NameOf(_udtBadge)}:={_udtBadge}"
144         End Function
145
146         Public Sub Update(thisUpdate As Long)
147             Me._udtBadge = thisUpdate
148         End Sub
149
150         ''' <summary>
151         ''' 由于考虑到可能会传递很大的数据块,所以在这里检测数据更新的话只读取头部的8个字节的数据
152         ''' </summary>
153         ''' <returns></returns>
154         Public Function ReadBadge() As Long
155             Dim buf As Byte() = New Byte(MMFStream.INT64 - 1) {}
156             Call _mmfileStream.CreateViewStream.Read(buf, Scan0, buf.Length)
157             Dim n As Long = BitConverter.ToInt64(buf, Scan0)
158             Return n
159         End Function
160
161         Private Sub __threadElapsed()
162             Do While Not Me.disposedValue
163                 Call __clientThreadElapsed()
164                 Call Threading.Thread.Sleep(1)
165             Loop
166         End Sub
167
168         Private Sub __clientThreadElapsed()
169             Dim flag As Long = ReadBadge()
170
171             If flag <= Me._udtBadge Then
172                 Return
173             Else ' 当从数据流中所读取到的更新标识符大于对象实例中的更新标识符的时候,认为数据发生了更新
174                 Me._mappedStream = Read()
175                 Me._udtBadge = _mappedStream.udtBadge
176                 Me._dataArrivals(_mappedStream.byteData)
177             End If
178         End Sub
179     End Class
180 End Namespace