##// END OF EJS Templates
Added implab nuget spec
cin -
r234:8dd666e6b6bf v2
parent child
Show More
@@ -0,0 +1,17
1 <?xml version="1.0"?>
2 <package >
3 <metadata>
4 <id>Implab</id>
5 <version>$version$</version>
6 <title>$title$</title>
7 <authors>Implab team</authors>
8 <owners>Implab team</owners>
9 <projectUrl>https://implab.org/</projectUrl>
10 <!-- <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl> -->
11 <requireLicenseAcceptance>false</requireLicenseAcceptance>
12 <description>Common components for asynchronous applications, tracing, logging, json and xml traits.</description>
13 <releaseNotes>Added strong name.</releaseNotes>
14 <copyright>Copyright 2017</copyright>
15 <tags>async xml json</tags>
16 </metadata>
17 </package> No newline at end of file
1 NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,22
1 Copyright 2012 Sergey Smirnov
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions are met:
5
6 1. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
8
9 2. Redistributions in binary form must reproduce the above copyright notice,
10 this list of conditions and the following disclaimer in the documentation
11 and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. No newline at end of file
@@ -1,183 +1,182
1 1 using Implab.Formats.Json;
2 2 using Implab.Parallels;
3 3 using Implab.Xml;
4 4 using System;
5 5 using System.Collections.Concurrent;
6 6 using System.Collections.Generic;
7 7 using System.IO;
8 8 using System.Linq;
9 9 using System.Text;
10 10 using System.Threading;
11 11 using System.Threading.Tasks;
12 12 using System.Xml;
13 13 using System.Xml.Serialization;
14 14
15 15 namespace Implab.Playground {
16 16 public class Program {
17 17
18 18 static void EnqueueRange<T>(ConcurrentQueue<T> q, T[] data, int offset, int len) {
19 19 for (var i = offset; i < offset + len; i++)
20 20 q.Enqueue(data[i]);
21 21 }
22 22
23 23 static bool TryDequeueRange<T>(ConcurrentQueue<T> q,T[] buffer,int offset, int len, out int actual) {
24 24 actual = 0;
25 25 T res;
26 26 while(q.TryDequeue(out res)) {
27 27 buffer[offset + actual] = res;
28 28 actual++;
29 29 if (actual == len)
30 30 break;
31 31 }
32 32 return actual != 0;
33 33 }
34 34
35 35 static void EnqueueRange<T>(SimpleAsyncQueue<T> q, T[] data, int offset, int len) {
36 36 for (var i = offset; i < offset + len; i++)
37 37 q.Enqueue(data[i]);
38 38 }
39 39
40 40 static bool TryDequeueRange<T>(SimpleAsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
41 41 actual = 0;
42 42 T res;
43 43 while (q.TryDequeue(out res)) {
44 44 buffer[offset + actual] = res;
45 45 actual++;
46 46 if (actual == len)
47 47 break;
48 48 }
49 49 return actual != 0;
50 50 }
51 51
52 /*
53 52 static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
54 53 for (var i = offset; i < offset + len; i++)
55 54 q.Enqueue(data[i]);
56 55 }
57 56
58 57 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
59 58 actual = 0;
60 59 T res;
61 60 while (q.TryDequeue(out res)) {
62 61 buffer[offset + actual] = res;
63 62 actual++;
64 63 if (actual == len)
65 64 break;
66 65 }
67 66 return actual != 0;
68 67 }
69 */
68
70 69
71 static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
70 /*static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
72 71 q.EnqueueRange(data, offset, len);
73 72 }
74 73
75 74 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
76 75 return q.TryDequeueRange(buffer, offset, len, out actual);
77 }
76 }*/
78 77
79 78
80 79 static void Main(string[] args) {
81 80
82 81 //var queue = new ConcurrentQueue<int>();
83 82 var queue = new AsyncQueue<int>();
84 83 //var queue = new SimpleAsyncQueue<int>();
85 84
86 85 const int wBatch = 32;
87 86 const long wCount = 1000000;
88 87 const long total = wBatch * wCount * 3;
89 88
90 89 long r1 = 0, r2 = 0, r3 = 0;
91 90 const int rBatch = 1000;
92 91 long read = 0;
93 92
94 93 var t1 = Environment.TickCount;
95 94
96 95 AsyncPool.RunThread(
97 96 () => {
98 97 var buffer = new int[wBatch];
99 98 for (int i = 0; i < wBatch; i++)
100 99 buffer[i] = 1;
101 100
102 101 for (int i = 0; i < wCount; i++)
103 102 EnqueueRange(queue, buffer, 0, wBatch);
104 103 Console.WriteLine("done writer #1: {0} ms", Environment.TickCount - t1);
105 104 },
106 105 () => {
107 106 var buffer = new int[wBatch];
108 107 for (int i = 0; i < wBatch; i++)
109 108 buffer[i] = 1;
110 109
111 110 for (int i = 0; i < wCount; i++)
112 111 EnqueueRange(queue, buffer, 0, wBatch);
113 112 Console.WriteLine("done writer #2: {0} ms", Environment.TickCount - t1);
114 113 },
115 114 () => {
116 115 var buffer = new int[wBatch];
117 116 for (int i = 0; i < wBatch; i++)
118 117 buffer[i] = 1;
119 118
120 119 for (int i = 0; i < wCount; i++)
121 120 EnqueueRange(queue, buffer, 0, wBatch);
122 121 Console.WriteLine("done writer #3: {0} ms", Environment.TickCount - t1);
123 122 },
124 123 () => {
125 124 var buffer = new int[rBatch];
126 125
127 126 while (read < total) {
128 127 int actual;
129 128 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
130 129 for (int i = 0; i < actual; i++)
131 130 r1 += buffer[i];
132 131 Interlocked.Add(ref read, actual);
133 132 }
134 133 }
135 134
136 135 Console.WriteLine("done reader #1: {0} ms", Environment.TickCount - t1);
137 136 }/*,
138 137 () => {
139 138 var buffer = new int[rBatch];
140 139
141 140 while (read < total) {
142 141 int actual;
143 142 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
144 143 for (int i = 0; i < actual; i++)
145 144 r2 += buffer[i];
146 145 Interlocked.Add(ref read, actual);
147 146 }
148 147 }
149 148
150 149 Console.WriteLine("done reader #2: {0} ms", Environment.TickCount - t1);
151 150 }*//*,
152 151 () => {
153 152 var buffer = new int[rBatch];
154 153
155 154 while (read < total) {
156 155 int actual;
157 156 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
158 157 for (int i = 0; i < actual; i++)
159 158 r3 += buffer[i];
160 159 Interlocked.Add(ref read, actual);
161 160 }
162 161 }
163 162
164 163 Console.WriteLine("done reader #3: {0} ms", Environment.TickCount - t1);
165 164 }*/
166 165 )
167 166 .PromiseAll()
168 167 .Join();
169 168
170 169
171 170 Console.WriteLine(
172 171 "done: {0} ms, summ#1: {1}, summ#2: {2}, total: {3}, count: {4}",
173 172 Environment.TickCount - t1,
174 173 r1,
175 174 r2,
176 175 r1 + r2 + r3,
177 176 total
178 177 );
179 178
180 179 Console.WriteLine("done");
181 180 }
182 181 }
183 182 }
@@ -1,283 +1,296
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 3 <PropertyGroup>
4 4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 7 <OutputType>Library</OutputType>
8 8 <RootNamespace>Implab</RootNamespace>
9 9 <AssemblyName>Implab</AssemblyName>
10 10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
11 11 <TargetFrameworkProfile />
12 12 </PropertyGroup>
13 13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14 14 <DebugSymbols>true</DebugSymbols>
15 15 <DebugType>full</DebugType>
16 16 <Optimize>false</Optimize>
17 17 <OutputPath>bin\Debug</OutputPath>
18 18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
19 19 <ErrorReport>prompt</ErrorReport>
20 20 <WarningLevel>4</WarningLevel>
21 21 <ConsolePause>false</ConsolePause>
22 22 <RunCodeAnalysis>true</RunCodeAnalysis>
23 23 </PropertyGroup>
24 24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 25 <DebugType>full</DebugType>
26 26 <Optimize>true</Optimize>
27 27 <OutputPath>bin\Release</OutputPath>
28 28 <ErrorReport>prompt</ErrorReport>
29 29 <WarningLevel>4</WarningLevel>
30 30 <ConsolePause>false</ConsolePause>
31 31 </PropertyGroup>
32 32 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
33 33 <DebugSymbols>true</DebugSymbols>
34 34 <DebugType>full</DebugType>
35 35 <Optimize>false</Optimize>
36 36 <OutputPath>bin\Debug</OutputPath>
37 37 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
38 38 <ErrorReport>prompt</ErrorReport>
39 39 <WarningLevel>4</WarningLevel>
40 40 <RunCodeAnalysis>true</RunCodeAnalysis>
41 41 <ConsolePause>false</ConsolePause>
42 42 </PropertyGroup>
43 43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
44 44 <Optimize>true</Optimize>
45 45 <OutputPath>bin\Release</OutputPath>
46 46 <ErrorReport>prompt</ErrorReport>
47 47 <WarningLevel>4</WarningLevel>
48 48 <ConsolePause>false</ConsolePause>
49 49 <DefineConstants>NET_4_5</DefineConstants>
50 50 </PropertyGroup>
51 51 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
52 52 <DebugSymbols>true</DebugSymbols>
53 53 <DebugType>full</DebugType>
54 54 <Optimize>false</Optimize>
55 55 <OutputPath>bin\Debug</OutputPath>
56 56 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
57 57 <ErrorReport>prompt</ErrorReport>
58 58 <WarningLevel>4</WarningLevel>
59 59 <RunCodeAnalysis>true</RunCodeAnalysis>
60 60 <ConsolePause>false</ConsolePause>
61 61 </PropertyGroup>
62 62 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
63 63 <Optimize>true</Optimize>
64 64 <OutputPath>bin\Release</OutputPath>
65 65 <DefineConstants>NET_4_5;MONO;</DefineConstants>
66 66 <ErrorReport>prompt</ErrorReport>
67 67 <WarningLevel>4</WarningLevel>
68 68 <ConsolePause>false</ConsolePause>
69 69 </PropertyGroup>
70 <PropertyGroup>
71 <SignAssembly>true</SignAssembly>
72 </PropertyGroup>
73 <PropertyGroup>
74 <AssemblyOriginatorKeyFile>implab.snk</AssemblyOriginatorKeyFile>
75 </PropertyGroup>
70 76 <ItemGroup>
71 77 <Reference Include="System" />
72 78 <Reference Include="System.Xml" />
73 79 <Reference Include="mscorlib" />
74 80 <Reference Include="System.Xml.Linq" />
75 81 </ItemGroup>
76 82 <ItemGroup>
77 83 <Compile Include="Components\StateChangeEventArgs.cs" />
78 84 <Compile Include="CustomEqualityComparer.cs" />
79 85 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
80 86 <Compile Include="Diagnostics\LogChannel.cs" />
81 87 <Compile Include="Diagnostics\LogicalOperation.cs" />
82 88 <Compile Include="Diagnostics\TextFileListener.cs" />
83 89 <Compile Include="Diagnostics\Trace.cs" />
84 90 <Compile Include="Diagnostics\TraceLog.cs" />
85 91 <Compile Include="Diagnostics\TraceEvent.cs" />
86 92 <Compile Include="Diagnostics\TraceEventType.cs" />
87 93 <Compile Include="Diagnostics\TraceSourceAttribute.cs" />
88 94 <Compile Include="Formats\CharMap.cs" />
89 95 <Compile Include="Formats\InputScanner.cs" />
90 96 <Compile Include="Formats\Json\JsonStringScanner.cs" />
91 97 <Compile Include="Formats\Json\JsonTextScanner.cs" />
92 98 <Compile Include="ICancellable.cs" />
93 99 <Compile Include="IProgressHandler.cs" />
94 100 <Compile Include="IProgressNotifier.cs" />
95 101 <Compile Include="IPromiseT.cs" />
96 102 <Compile Include="IPromise.cs" />
97 103 <Compile Include="IServiceLocator.cs" />
98 104 <Compile Include="ITaskController.cs" />
99 105 <Compile Include="Parallels\DispatchPool.cs" />
100 106 <Compile Include="Parallels\ArrayTraits.cs" />
101 107 <Compile Include="Parallels\SimpleAsyncQueue.cs" />
102 108 <Compile Include="Parallels\WorkerPool.cs" />
103 109 <Compile Include="ProgressInitEventArgs.cs" />
104 110 <Compile Include="Properties\AssemblyInfo.cs" />
105 111 <Compile Include="Parallels\AsyncPool.cs" />
106 112 <Compile Include="Safe.cs" />
107 113 <Compile Include="SyncContextPromise.cs" />
108 114 <Compile Include="ValueEventArgs.cs" />
109 115 <Compile Include="PromiseExtensions.cs" />
110 116 <Compile Include="SyncContextPromiseT.cs" />
111 117 <Compile Include="Diagnostics\OperationContext.cs" />
112 118 <Compile Include="Diagnostics\TraceContext.cs" />
113 119 <Compile Include="Diagnostics\LogEventArgs.cs" />
114 120 <Compile Include="Diagnostics\LogEventArgsT.cs" />
115 121 <Compile Include="Diagnostics\Extensions.cs" />
116 122 <Compile Include="PromiseEventType.cs" />
117 123 <Compile Include="Parallels\AsyncQueue.cs" />
118 124 <Compile Include="PromiseT.cs" />
119 125 <Compile Include="IDeferred.cs" />
120 126 <Compile Include="IDeferredT.cs" />
121 127 <Compile Include="Promise.cs" />
122 128 <Compile Include="PromiseTransientException.cs" />
123 129 <Compile Include="Parallels\Signal.cs" />
124 130 <Compile Include="Parallels\SharedLock.cs" />
125 131 <Compile Include="Diagnostics\ILogWriter.cs" />
126 132 <Compile Include="Diagnostics\ListenerBase.cs" />
127 133 <Compile Include="Parallels\BlockingQueue.cs" />
128 134 <Compile Include="AbstractEvent.cs" />
129 135 <Compile Include="AbstractPromise.cs" />
130 136 <Compile Include="AbstractPromiseT.cs" />
131 137 <Compile Include="FuncTask.cs" />
132 138 <Compile Include="FuncTaskBase.cs" />
133 139 <Compile Include="FuncTaskT.cs" />
134 140 <Compile Include="ActionChainTaskBase.cs" />
135 141 <Compile Include="ActionChainTask.cs" />
136 142 <Compile Include="ActionChainTaskT.cs" />
137 143 <Compile Include="FuncChainTaskBase.cs" />
138 144 <Compile Include="FuncChainTask.cs" />
139 145 <Compile Include="FuncChainTaskT.cs" />
140 146 <Compile Include="ActionTaskBase.cs" />
141 147 <Compile Include="ActionTask.cs" />
142 148 <Compile Include="ActionTaskT.cs" />
143 149 <Compile Include="ICancellationToken.cs" />
144 150 <Compile Include="SuccessPromise.cs" />
145 151 <Compile Include="SuccessPromiseT.cs" />
146 152 <Compile Include="PromiseAwaiterT.cs" />
147 153 <Compile Include="PromiseAwaiter.cs" />
148 154 <Compile Include="Components\ComponentContainer.cs" />
149 155 <Compile Include="Components\Disposable.cs" />
150 156 <Compile Include="Components\DisposablePool.cs" />
151 157 <Compile Include="Components\ObjectPool.cs" />
152 158 <Compile Include="Components\ServiceLocator.cs" />
153 159 <Compile Include="Components\IInitializable.cs" />
154 160 <Compile Include="TaskController.cs" />
155 161 <Compile Include="Components\App.cs" />
156 162 <Compile Include="Components\IRunnable.cs" />
157 163 <Compile Include="Components\ExecutionState.cs" />
158 164 <Compile Include="Components\RunnableComponent.cs" />
159 165 <Compile Include="Components\IFactory.cs" />
160 166 <Compile Include="Automaton\IAlphabet.cs" />
161 167 <Compile Include="Automaton\ParserException.cs" />
162 168 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
163 169 <Compile Include="Automaton\IAlphabetBuilder.cs" />
164 170 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
165 171 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
166 172 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
167 173 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
168 174 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
169 175 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
170 176 <Compile Include="Automaton\RegularExpressions\Token.cs" />
171 177 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
172 178 <Compile Include="Automaton\AutomatonTransition.cs" />
173 179 <Compile Include="Formats\Json\JsonElementContext.cs" />
174 180 <Compile Include="Formats\Json\JsonElementType.cs" />
175 181 <Compile Include="Formats\Json\JsonGrammar.cs" />
176 182 <Compile Include="Formats\Json\JsonReader.cs" />
177 183 <Compile Include="Formats\Json\JsonScanner.cs" />
178 184 <Compile Include="Formats\Json\JsonTokenType.cs" />
179 185 <Compile Include="Formats\Json\JsonWriter.cs" />
180 186 <Compile Include="Formats\Json\StringTranslator.cs" />
181 187 <Compile Include="Automaton\MapAlphabet.cs" />
182 188 <Compile Include="Formats\CharAlphabet.cs" />
183 189 <Compile Include="Formats\ByteAlphabet.cs" />
184 190 <Compile Include="Automaton\IDFATable.cs" />
185 191 <Compile Include="Automaton\IDFATableBuilder.cs" />
186 192 <Compile Include="Automaton\DFATable.cs" />
187 193 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
188 194 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
189 195 <Compile Include="Formats\Grammar.cs" />
190 196 <Compile Include="Automaton\RegularExpressions\EndTokenT.cs" />
191 197 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
192 198 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitorT.cs" />
193 199 <Compile Include="Automaton\AutomatonConst.cs" />
194 200 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
195 201 <Compile Include="Components\LazyAndWeak.cs" />
196 202 <Compile Include="AbstractTask.cs" />
197 203 <Compile Include="AbstractTaskT.cs" />
198 204 <Compile Include="FailedPromise.cs" />
199 205 <Compile Include="FailedPromiseT.cs" />
200 206 <Compile Include="Components\PollingComponent.cs" />
201 207 <Compile Include="Xml\JsonXmlReader.cs" />
202 208 <Compile Include="Xml\JsonXmlReaderOptions.cs" />
203 209 <Compile Include="Xml\JsonXmlReaderPosition.cs" />
204 210 <Compile Include="Xml\SerializationHelpers.cs" />
205 211 <Compile Include="Xml\SerializersPool.cs" />
206 212 <Compile Include="Xml\XmlSimpleAttribute.cs" />
207 213 <Compile Include="Xml\XmlNameContext.cs" />
208 214 </ItemGroup>
209 215 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
210 <ItemGroup />
216 <ItemGroup>
217 <None Include="Implab.nuspec">
218 <SubType>Designer</SubType>
219 </None>
220 <None Include="implab.snk" />
221 </ItemGroup>
211 222 <ProjectExtensions>
212 223 <MonoDevelop>
213 224 <Properties>
214 225 <Policies>
215 226 <CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpacingAfterMethodDeclarationName="True" SpaceAfterMethodCallName="True" SpaceBeforeOpenSquareBracket="True" SpaceBeforeColonInBaseTypeDeclaration="True" scope="text/x-csharp" />
216 227 <TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" TabsToSpaces="True" EolMarker="Unix" scope="text/x-csharp" />
217 228 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
218 229 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
219 230 <XmlFormattingPolicy scope="application/xml">
220 231 <DefaultFormat OmitXmlDeclaration="False" NewLineChars="&#xA;" IndentContent="True" ContentIndentString=" " AttributesInNewLine="False" MaxAttributesPerLine="10" AttributesIndentString=" " WrapAttributes="False" AlignAttributes="False" AlignAttributeValues="False" QuoteChar="&quot;" SpacesBeforeAssignment="0" SpacesAfterAssignment="0" EmptyLinesBeforeStart="0" EmptyLinesAfterStart="0" EmptyLinesBeforeEnd="0" EmptyLinesAfterEnd="0" />
221 232 </XmlFormattingPolicy>
222 233 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
223 234 <NameConventionPolicy>
224 235 <Rules>
225 236 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
226 237 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
227 238 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
228 239 <RequiredPrefixes>
229 240 <String>I</String>
230 241 </RequiredPrefixes>
231 242 </NamingRule>
232 243 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
233 244 <RequiredSuffixes>
234 245 <String>Attribute</String>
235 246 </RequiredSuffixes>
236 247 </NamingRule>
237 248 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
238 249 <RequiredSuffixes>
239 250 <String>EventArgs</String>
240 251 </RequiredSuffixes>
241 252 </NamingRule>
242 253 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
243 254 <RequiredSuffixes>
244 255 <String>Exception</String>
245 256 </RequiredSuffixes>
246 257 </NamingRule>
247 258 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
248 259 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
249 260 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
250 261 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
251 262 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
252 263 <RequiredPrefixes>
253 264 <String>m_</String>
254 265 </RequiredPrefixes>
255 266 </NamingRule>
256 267 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
257 268 <RequiredPrefixes>
258 269 <String>_</String>
259 270 </RequiredPrefixes>
260 271 </NamingRule>
261 272 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
262 273 <RequiredPrefixes>
263 274 <String>m_</String>
264 275 </RequiredPrefixes>
265 276 </NamingRule>
266 277 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
267 278 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
268 279 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
269 280 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
270 281 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
271 282 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
272 283 <RequiredPrefixes>
273 284 <String>T</String>
274 285 </RequiredPrefixes>
275 286 </NamingRule>
276 287 </Rules>
277 288 </NameConventionPolicy>
278 289 </Policies>
279 290 </Properties>
280 291 </MonoDevelop>
281 292 </ProjectExtensions>
282 <ItemGroup />
293 <ItemGroup>
294 <Content Include="license.txt" />
295 </ItemGroup>
283 296 </Project> No newline at end of file
@@ -1,562 +1,563
1 1 using System.Threading;
2 2 using System.Collections.Generic;
3 3 using System;
4 4 using System.Collections;
5 5 using System.Diagnostics;
6 using System.Runtime.CompilerServices;
6 7
7 8 namespace Implab.Parallels {
8 9 public class AsyncQueue<T> : IEnumerable<T> {
9 10 class Chunk {
10 11 public volatile Chunk next;
11 12
12 13 volatile int m_low;
13 14 volatile int m_hi;
14 15 volatile int m_alloc;
15 16 readonly int m_size;
16 17 readonly T[] m_data;
17 18
18 19 public Chunk(int size) {
19 20 m_size = size;
20 21 m_data = new T[size];
21 22 }
22 23
23 24 public Chunk(int size, T value) {
24 25 m_size = size;
25 26 m_hi = 1;
26 27 m_alloc = 1;
27 28 m_data = new T[size];
28 29 m_data[0] = value;
29 30 }
30 31
31 32 public Chunk(int size, int allocated) {
32 33 m_size = size;
33 34 m_hi = allocated;
34 35 m_alloc = allocated;
35 36 m_data = new T[size];
36 37 }
37 38
38 39 public void WriteData(T[] data, int offset, int dest, int length) {
39 40 Array.Copy(data, offset, m_data, dest, length);
40 41 }
41 42
42 43 public int Low {
43 44 get { return m_low; }
44 45 }
45 46
46 47 public int Hi {
47 48 get { return m_hi; }
48 49 }
49 50
50 51 public int Size {
51 52 get { return m_size; }
52 53 }
53 54
55 [MethodImpl(MethodImplOptions.AggressiveInlining)]
56 void AwaitWrites(int mark) {
57 if (m_hi != mark) {
58 SpinWait spin = new SpinWait();
59 do {
60 spin.SpinOnce();
61 } while (m_hi != mark);
62 }
63 }
64
54 65 public bool TryEnqueue(T value) {
55 66 int alloc;
56 67 do {
57 68 alloc = m_alloc;
58 69 if (alloc >= m_size)
59 70 return false;
60 71 } while(alloc != Interlocked.CompareExchange(ref m_alloc, alloc + 1, alloc));
61 72
62 73 m_data[alloc] = value;
63 74
64 SpinWait spin = new SpinWait();
65 // m_hi is volatile
66 while (alloc != m_hi) {
67 // spin wait for commit
68 spin.SpinOnce();
69 }
75 AwaitWrites(alloc);
70 76 m_hi = alloc + 1;
71 77
72 78 return true;
73 79 }
74 80
75 81 /// <summary>
76 82 /// Prevents from allocating new space in the chunk and waits for all write operations to complete
77 83 /// </summary>
78 84 public void Seal() {
79 85 var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size), m_size);
80 SpinWait spin = new SpinWait();
81 while (m_hi != actual) {
82 spin.SpinOnce();
83 }
86 AwaitWrites(actual);
84 87 }
85 88
86 89 public bool TryDequeue(out T value, out bool recycle) {
87 90 int low;
88 91 do {
89 92 low = m_low;
90 93 if (low >= m_hi) {
91 94 value = default(T);
92 95 recycle = (low == m_size);
93 96 return false;
94 97 }
95 98 } while (low != Interlocked.CompareExchange(ref m_low, low + 1, low));
96 99
97 100 recycle = (low + 1 == m_size);
98 101 value = m_data[low];
99 102
100 103 return true;
101 104 }
102 105
103 106 public bool TryEnqueueBatch(T[] batch, int offset, int length, out int enqueued) {
104 107 int alloc;
105 108 do {
106 109 alloc = m_alloc;
107 110 if (alloc >= m_size) {
108 111 enqueued = 0;
109 112 return false;
110 113 } else {
111 114 enqueued = Math.Min(length, m_size - alloc);
112 115 }
113 116 } while (alloc != Interlocked.CompareExchange(ref m_alloc, alloc + enqueued, alloc));
114 117
115 118 Array.Copy(batch, offset, m_data, alloc, enqueued);
116 119
117 SpinWait spin = new SpinWait();
118 while (alloc != m_hi) {
119 spin.SpinOnce();
120 }
121
120 AwaitWrites(alloc);
122 121 m_hi = alloc + enqueued;
123 122 return true;
124 123 }
125 124
126 125 public bool TryDequeueBatch(T[] buffer, int offset, int length, out int dequeued, out bool recycle) {
127 126 int low, hi, batchSize;
128 127
129 128 do {
130 129 low = m_low;
131 130 hi = m_hi;
132 131 if (low >= hi) {
133 132 dequeued = 0;
134 133 recycle = (low == m_size);
135 134 return false;
136 135 }
137 136 batchSize = Math.Min(hi - low, length);
138 137 } while (low != Interlocked.CompareExchange(ref m_low, low + batchSize, low));
139 138
140 139 dequeued = batchSize;
141 140 recycle = (low + batchSize == m_size);
142 141 Array.Copy(m_data, low, buffer, offset, batchSize);
143 142
144 143 return true;
145 144 }
146 145
147 146 public T GetAt(int pos) {
148 147 return m_data[pos];
149 148 }
150 149 }
151 150
152 151 public const int DEFAULT_CHUNK_SIZE = 32;
153 152 public const int MAX_CHUNK_SIZE = 256;
154 153
155 154 Chunk m_first;
156 155 Chunk m_last;
157 156
158 157 public AsyncQueue() {
159 158 m_first = m_last = new Chunk(DEFAULT_CHUNK_SIZE);
160 159 }
161 160
162 161 /// <summary>
163 162 /// Adds the specified value to the queue.
164 163 /// </summary>
165 164 /// <param name="value">Tha value which will be added to the queue.</param>
166 165 public void Enqueue(T value) {
167 166 var last = m_last;
168 167 SpinWait spin = new SpinWait();
169 168 while (!last.TryEnqueue(value)) {
170 169 // try to extend queue
171 170 var chunk = new Chunk(DEFAULT_CHUNK_SIZE, value);
172 171 var t = Interlocked.CompareExchange(ref m_last, chunk, last);
173 172 if (t == last) {
174 173 last.next = chunk;
175 174 break;
176 175 } else {
177 176 last = t;
178 177 }
179 178 spin.SpinOnce();
180 179 }
181 180 }
182 181
183 182 /// <summary>
184 183 /// Adds the specified data to the queue.
185 184 /// </summary>
186 185 /// <param name="data">The buffer which contains the data to be enqueued.</param>
187 186 /// <param name="offset">The offset of the data in the buffer.</param>
188 187 /// <param name="length">The size of the data to read from the buffer.</param>
189 188 public void EnqueueRange(T[] data, int offset, int length) {
190 189 if (data == null)
191 190 throw new ArgumentNullException("data");
192 191 if (offset < 0)
193 192 throw new ArgumentOutOfRangeException("offset");
194 193 if (length < 1 || offset + length > data.Length)
195 194 throw new ArgumentOutOfRangeException("length");
196 195
197 196 while (length > 0) {
198 197 var last = m_last;
199 198 int enqueued;
200 199
201 200 if (last.TryEnqueueBatch(data, offset, length, out enqueued)) {
202 201 length -= enqueued;
203 202 offset += enqueued;
204 203 }
205 204
206 205 if (length > 0) {
207 206 // we have something to enqueue
208 207
209 208 var tail = length % MAX_CHUNK_SIZE;
210 209
211 210 var chunk = new Chunk(Math.Max(tail, DEFAULT_CHUNK_SIZE), tail);
212 211
213 212 if (last != Interlocked.CompareExchange(ref m_last, chunk, last))
214 213 continue; // we wasn't able to catch the writer, roundtrip
215 214
216 215 // we are lucky
217 216 // we can exclusively write our batch, the other writers will continue their work
218 217
219 218 length -= tail;
220 219
221 220
222 221 for(var i = 0; i < length; i+= MAX_CHUNK_SIZE) {
223 222 var node = new Chunk(MAX_CHUNK_SIZE, MAX_CHUNK_SIZE);
224 223 node.WriteData(data, offset, 0, MAX_CHUNK_SIZE);
225 224 offset += MAX_CHUNK_SIZE;
226 225 // fence last.next is volatile
227 226 last.next = node;
228 227 last = node;
229 228 }
230 229
231 230 if (tail > 0)
232 231 chunk.WriteData(data, offset, 0, tail);
233 232
234 233 // fence last.next is volatile
235 234 last.next = chunk;
236 235 return;
237 236 }
238 237 }
239 238 }
240 239
241 240 /// <summary>
242 241 /// Tries to retrieve the first element from the queue.
243 242 /// </summary>
244 243 /// <returns><c>true</c>, if element is dequeued, <c>false</c> otherwise.</returns>
245 244 /// <param name="value">The value of the dequeued element.</param>
246 245 public bool TryDequeue(out T value) {
247 246 var chunk = m_first;
248 247 do {
249 248 bool recycle;
250 249
251 250 var result = chunk.TryDequeue(out value, out recycle);
252 251
253 252 if (recycle && chunk.next != null) {
254 253 // this chunk is waste
255 254 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
256 255 } else {
257 256 return result; // this chunk is usable and returned actual result
258 257 }
259 258
260 259 if (result) // this chunk is waste but the true result is always actual
261 260 return true;
262 261 } while (true);
263 262 }
264 263
265 264 /// <summary>
266 265 /// Tries to dequeue the specified amount of data from the queue.
267 266 /// </summary>
268 267 /// <returns><c>true</c>, if data was deuqueued, <c>false</c> otherwise.</returns>
269 268 /// <param name="buffer">The buffer to which the data will be written.</param>
270 269 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
271 270 /// <param name="length">The maximum amount of data to be retrieved.</param>
272 271 /// <param name="dequeued">The actual amout of the retrieved data.</param>
273 272 public bool TryDequeueRange(T[] buffer, int offset, int length, out int dequeued) {
274 273 if (buffer == null)
275 274 throw new ArgumentNullException("buffer");
276 275 if (offset < 0)
277 276 throw new ArgumentOutOfRangeException("offset");
278 277 if (length < 1 || offset + length > buffer.Length)
279 278 throw new ArgumentOutOfRangeException("length");
280 279
281 280 var chunk = m_first;
282 281 dequeued = 0;
283 282 do {
284 283 bool recycle;
285 284 int actual;
286 285 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
287 286 offset += actual;
288 287 length -= actual;
289 288 dequeued += actual;
290 289 }
291 290
292 291 if (recycle && chunk.next != null) {
293 292 // this chunk is waste
294 293 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
295 294 } else {
296 295 chunk = null;
297 296 }
298 297
299 298 if (length == 0)
300 299 return true;
301 300 } while (chunk != null);
302 301
303 302 return dequeued != 0;
304 303 }
305 304
306 305 /// <summary>
307 306 /// Tries to dequeue all remaining data in the first chunk.
308 307 /// </summary>
309 308 /// <returns><c>true</c>, if data was dequeued, <c>false</c> otherwise.</returns>
310 309 /// <param name="buffer">The buffer to which the data will be written.</param>
311 310 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
312 311 /// <param name="length">Tha maximum amount of the data to be dequeued.</param>
313 312 /// <param name="dequeued">The actual amount of the dequeued data.</param>
314 313 public bool TryDequeueChunk(T[] buffer, int offset, int length, out int dequeued) {
315 314 if (buffer == null)
316 315 throw new ArgumentNullException("buffer");
317 316 if (offset < 0)
318 317 throw new ArgumentOutOfRangeException("offset");
319 318 if (length < 1 || offset + length > buffer.Length)
320 319 throw new ArgumentOutOfRangeException("length");
321 320
322 321 var chunk = m_first;
323 322 do {
324 323 bool recycle;
325 324 chunk.TryDequeueBatch(buffer, offset, length, out dequeued, out recycle);
326 325
327 326 if (recycle && chunk.next != null) {
328 327 // this chunk is waste
329 328 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
330 329 } else {
331 330 chunk = null;
332 331 }
333 332
334 333 // if we have dequeued any data, then return
335 334 if (dequeued != 0)
336 335 return true;
337 336
338 337 } while (chunk != null);
339 338
340 339 return false;
341 340 }
342 341
343 342
344 343 public void Clear() {
345 344 // start the new queue
346 345 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
347 346 do {
348 347 var first = m_first;
349 348 if (first.next == null && first != m_last) {
350 349 continue;
351 350 }
352 351
353 352 // here we will create inconsistency which will force others to spin
354 353 // and prevent from fetching. chunk.next = null
355 354 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
356 355 continue;// inconsistent
357 356
358 357 m_last = chunk;
359 358 return;
360 359 } while (true);
361 360 }
362 361
363 362 public List<T> Drain() {
364 // start the new queue
365 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
366
363 Chunk chunk = null;
367 364 do {
368 365 var first = m_first;
369 366 // first.next is volatile
370 367 if (first.next == null) {
371 368 if (first != m_last)
372 369 continue;
373 370 else if (first.Hi == first.Low)
374 371 return new List<T>();
375 372 }
376 373
374 // start the new queue
375 if (chunk == null)
376 chunk = new Chunk(DEFAULT_CHUNK_SIZE);
377
377 378 // here we will create inconsistency which will force others to spin
378 379 // and prevent from fetching. chunk.next = null
379 380 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
380 381 continue;// inconsistent
381 382
382 383 var last = Interlocked.Exchange(ref m_last, chunk);
383 384
384 385 return ReadChunks(first, last);
385 386
386 387 } while (true);
387 388 }
388 389
389 390 static List<T> ReadChunks(Chunk chunk, object last) {
390 391 var result = new List<T>();
391 392 var buffer = new T[MAX_CHUNK_SIZE];
392 393 int actual;
393 394 bool recycle;
394 395 SpinWait spin = new SpinWait();
395 396 while (chunk != null) {
396 397 // ensure all write operations on the chunk are complete
397 398 chunk.Seal();
398 399
399 400 // we need to read the chunk using this way
400 401 // since some client still may completing the dequeue
401 402 // operation, such clients most likely won't get results
402 403 while (chunk.TryDequeueBatch(buffer, 0, buffer.Length, out actual, out recycle))
403 404 result.AddRange(new ArraySegmentCollection(buffer, 0, actual));
404 405
405 406 if (chunk == last) {
406 407 chunk = null;
407 408 } else {
408 409 while (chunk.next == null)
409 410 spin.SpinOnce();
410 411 chunk = chunk.next;
411 412 }
412 413 }
413 414
414 415 return result;
415 416 }
416 417
417 418 struct ArraySegmentCollection : ICollection<T> {
418 419 readonly T[] m_data;
419 420 readonly int m_offset;
420 421 readonly int m_length;
421 422
422 423 public ArraySegmentCollection(T[] data, int offset, int length) {
423 424 m_data = data;
424 425 m_offset = offset;
425 426 m_length = length;
426 427 }
427 428
428 429 #region ICollection implementation
429 430
430 431 public void Add(T item) {
431 432 throw new NotSupportedException();
432 433 }
433 434
434 435 public void Clear() {
435 436 throw new NotSupportedException();
436 437 }
437 438
438 439 public bool Contains(T item) {
439 440 return false;
440 441 }
441 442
442 443 public void CopyTo(T[] array, int arrayIndex) {
443 444 Array.Copy(m_data, m_offset, array, arrayIndex, m_length);
444 445 }
445 446
446 447 public bool Remove(T item) {
447 448 throw new NotSupportedException();
448 449 }
449 450
450 451 public int Count {
451 452 get {
452 453 return m_length;
453 454 }
454 455 }
455 456
456 457 public bool IsReadOnly {
457 458 get {
458 459 return true;
459 460 }
460 461 }
461 462
462 463 #endregion
463 464
464 465 #region IEnumerable implementation
465 466
466 467 public IEnumerator<T> GetEnumerator() {
467 468 for (int i = m_offset; i < m_length + m_offset; i++)
468 469 yield return m_data[i];
469 470 }
470 471
471 472 #endregion
472 473
473 474 #region IEnumerable implementation
474 475
475 476 IEnumerator IEnumerable.GetEnumerator() {
476 477 return GetEnumerator();
477 478 }
478 479
479 480 #endregion
480 481 }
481 482
482 483 #region IEnumerable implementation
483 484
484 485 class Enumerator : IEnumerator<T> {
485 486 Chunk m_current;
486 487 int m_pos = -1;
487 488
488 489 public Enumerator(Chunk fisrt) {
489 490 m_current = fisrt;
490 491 }
491 492
492 493 #region IEnumerator implementation
493 494
494 495 public bool MoveNext() {
495 496 if (m_current == null)
496 497 return false;
497 498
498 499 if (m_pos == -1)
499 500 m_pos = m_current.Low;
500 501 else
501 502 m_pos++;
502 503
503 504 if (m_pos == m_current.Hi) {
504 505
505 506 m_current = m_pos == m_current.Size ? m_current.next : null;
506 507
507 508 m_pos = 0;
508 509
509 510 if (m_current == null)
510 511 return false;
511 512 }
512 513
513 514 return true;
514 515 }
515 516
516 517 public void Reset() {
517 518 throw new NotSupportedException();
518 519 }
519 520
520 521 object IEnumerator.Current {
521 522 get {
522 523 return Current;
523 524 }
524 525 }
525 526
526 527 #endregion
527 528
528 529 #region IDisposable implementation
529 530
530 531 public void Dispose() {
531 532 }
532 533
533 534 #endregion
534 535
535 536 #region IEnumerator implementation
536 537
537 538 public T Current {
538 539 get {
539 540 if (m_pos == -1 || m_current == null)
540 541 throw new InvalidOperationException();
541 542 return m_current.GetAt(m_pos);
542 543 }
543 544 }
544 545
545 546 #endregion
546 547 }
547 548
548 549 public IEnumerator<T> GetEnumerator() {
549 550 return new Enumerator(m_first);
550 551 }
551 552
552 553 #endregion
553 554
554 555 #region IEnumerable implementation
555 556
556 557 IEnumerator IEnumerable.GetEnumerator() {
557 558 return GetEnumerator();
558 559 }
559 560
560 561 #endregion
561 562 }
562 563 }
@@ -1,27 +1,24
1 1 using System.Reflection;
2 using System.Runtime.CompilerServices;
3 2 using System.Runtime.InteropServices;
4 3
5 4 // Information about this assembly is defined by the following attributes.
6 5 // Change them to the values specific to your project.
7 6
8 7 [assembly: AssemblyTitle("Implab")]
9 8 [assembly: AssemblyDescription("Tools")]
10 [assembly: AssemblyConfiguration("")]
11 [assembly: AssemblyCompany("")]
12 [assembly: AssemblyProduct("")]
9 [assembly: AssemblyCompany("Implab.org")]
13 10 [assembly: AssemblyCopyright("Implab")]
14 [assembly: AssemblyTrademark("")]
11 [assembly: AssemblyTrademark("Implab")]
15 12 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
16 13 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
17 14 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
18 15
19 16 [assembly: AssemblyVersion("2.1.*")]
20 17 [assembly: ComVisible(false)]
21 18
22 19 // The following attributes are used to specify the signing key for the assembly,
23 20 // if desired. See the Mono documentation for more information about signing.
24 21
25 22 //[assembly: AssemblyDelaySign(false)]
26 23 //[assembly: AssemblyKeyFile("")]
27 24
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now