1 #Region "Microsoft.VisualBasic::0aca79be365c7d2a43e63d417c5f3757, Microsoft.VisualBasic.Core\ApplicationServices\Parallel\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
59 Namespace Parallel.MMFProtocol.MapStream
60
61     Public MustInherit Class IMapBase : Implements IDisposable
62
63         Public ReadOnly Property URI As String
64
65         Protected _chunkBuffer As Byte()
66         Protected _mmfileStream As MemoryMappedFile
67
68         Sub New(uri As String, ChunkSize As Long)
69             Me._URI = uri
70             Me._chunkBuffer = New Byte(ChunkSize - 1) {}
71         End Sub
72
73         Public Function Read() As MMFStream
74             Call _mmfileStream.CreateViewStream.Read(_chunkBuffer, Scan0, _chunkBuffer.Length)
75             Return New MMFStream(_chunkBuffer)
76         End Function
77
78         Public Overrides Function ToString() As String
79             Return URI
80         End Function
81
82 #Region "IDisposable Support"
83         Protected disposedValue As Boolean To detect redundant calls
84
85         ' IDisposable
86         Protected Overridable Sub Dispose(disposing As Boolean)
87             If Not Me.disposedValue Then
88                 If disposing Then
89                     ' TODO: dispose managed state (managed objects).
90                 End If
91
92                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
93                 ' TODO: set large fields to null.
94             End If
95             Me.disposedValue = True
96         End Sub
97
98         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
99         'Protected Overrides Sub Finalize()
100         '    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
101         '    Dispose(False)
102         '    MyBase.Finalize()
103         'End Sub
104
105         ' This code added by Visual Basic to correctly implement the disposable pattern.
106         Public Sub Dispose() Implements IDisposable.Dispose
107             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
108             Dispose(True)
109             ' TODO: uncomment the following line if Finalize() is overridden above.
110             ' GC.SuppressFinalize(Me)
111         End Sub
112 #End Region
113     End Class
114
115     Public Class MSIOReader : Inherits IMapBase
116         Implements IDisposable
117
118         ''' <summary>
119         ''' 内存映射文件的更新标识符
120         ''' </summary>
121         ''' <remarks></remarks>
122         Dim _udtBadge As Long
123         Dim _mappedStream As MMFStream
124
125         ReadOnly _dataArrivals As DataArrival
126
127         ''' <summary>
128         ''' 
129         ''' </summary>
130         ''' <param name="uri"></param>
131         ''' <param name="callback"></param>
132         ''' <param name="ChunkSize">内存映射文件的数据块的预分配大小</param>
133         Sub New(uri As String, callback As DataArrival, ChunkSize As Long)
134             Call MyBase.New(uri, ChunkSize)
135             _mmfileStream = MemoryMappedFile.OpenExisting(uri)
136             _dataArrivals = callback
137
138             Call Parallel.RunTask(AddressOf __threadElapsed)
139         End Sub
140
141         Public Overrides Function ToString() As String
142             Return $"{URI} ===> {NameOf(_udtBadge)}:={_udtBadge}"
143         End Function
144
145         Public Sub Update(thisUpdate As Long)
146             Me._udtBadge = thisUpdate
147         End Sub
148
149         ''' <summary>
150         ''' 由于考虑到可能会传递很大的数据块,所以在这里检测数据更新的话只读取头部的8个字节的数据
151         ''' </summary>
152         ''' <returns></returns>
153         Public Function ReadBadge() As Long
154             Dim buf As Byte() = New Byte(MMFStream.INT64 - 1) {}
155             Call _mmfileStream.CreateViewStream.Read(buf, Scan0, buf.Length)
156             Dim n As Long = BitConverter.ToInt64(buf, Scan0)
157             Return n
158         End Function
159
160         Private Sub __threadElapsed()
161             Do While Not Me.disposedValue
162                 Call __clientThreadElapsed()
163                 Call Threading.Thread.Sleep(1)
164             Loop
165         End Sub
166
167         Private Sub __clientThreadElapsed()
168             Dim flag As Long = ReadBadge()
169
170             If flag <= Me._udtBadge Then
171                 Return
172             Else ' 当从数据流中所读取到的更新标识符大于对象实例中的更新标识符的时候,认为数据发生了更新
173                 Me._mappedStream = Read()
174                 Me._udtBadge = _mappedStream.udtBadge
175                 Me._dataArrivals(_mappedStream.byteData)
176             End If
177         End Sub
178     End Class
179 End Namespace