diff --git a/ConfigurationTests/AppConfig.cs b/ConfigurationTests/AppConfig.cs deleted file mode 100644 index 781c7bf..0000000 --- a/ConfigurationTests/AppConfig.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace ConfigurationTests -{ - public class AppConfig - { - public string Url; - public int BatchSize; - public IEnumerable Sheme; - public int[] Port; - public ServiceConfig Service; - public IEnumerable List; - } - - public class ServiceConfig - { - public string AppName; - public string AppKey; - public string ServiceGroup; - public string ServiceType; - } -} diff --git a/ConfigurationTests/ConfigurationTests.csproj b/ConfigurationTests/ConfigurationTests.csproj deleted file mode 100644 index c638033..0000000 --- a/ConfigurationTests/ConfigurationTests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - netcoreapp2.2 - - - - - - - - - Always - - - - diff --git a/ConfigurationTests/Program.cs b/ConfigurationTests/Program.cs deleted file mode 100644 index e6abd10..0000000 --- a/ConfigurationTests/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using ZeroLevel; - -namespace ConfigurationTests -{ - class Program - { - static void Main(string[] args) - { - var config = Configuration.ReadSetFromIniFile("config.ini").Bind(); - Console.WriteLine(config.Url); - Console.WriteLine(config.BatchSize); - Console.WriteLine("Ports"); - foreach (var port in config.Port) - { - Console.WriteLine($"\t{port}"); - } - Console.WriteLine("Shemes"); - foreach (var sheme in config.Sheme) - { - Console.WriteLine($"\t{sheme}"); - } - Console.WriteLine($"Range list: {string.Join(", ", config.List)}"); - - Console.WriteLine("Service"); - Console.WriteLine($"\tAppKey: {config.Service.AppKey}"); - Console.WriteLine($"\tAppName: {config.Service.AppName}"); - Console.WriteLine($"\tServiceGroup: {config.Service.ServiceGroup}"); - Console.WriteLine($"\tServiceType: {config.Service.ServiceType}"); - - Console.ReadKey(); - } - } -} - diff --git a/ConfigurationTests/config.ini b/ConfigurationTests/config.ini deleted file mode 100644 index a3518a0..0000000 --- a/ConfigurationTests/config.ini +++ /dev/null @@ -1,15 +0,0 @@ -url=https://habr.ru -batchSize=1000 -sheme=socks -sheme=http -sheme=https -port=80 -port=90 -port=8800 -list=1-5,7,9 - -[service] -AppName=TestApp -AppKey=test.app -ServiceGroup=System -ServiceType=service \ No newline at end of file diff --git a/DependencyInjectionTests/DependencyInjectionTests.csproj b/DependencyInjectionTests/DependencyInjectionTests.csproj deleted file mode 100644 index 18ef193..0000000 --- a/DependencyInjectionTests/DependencyInjectionTests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - netcoreapp3.0 - - - - - - - - - Always - - - - diff --git a/DependencyInjectionTests/config.ini b/DependencyInjectionTests/config.ini deleted file mode 100644 index 0cbcf83..0000000 --- a/DependencyInjectionTests/config.ini +++ /dev/null @@ -1 +0,0 @@ -url=github.com \ No newline at end of file diff --git a/FileTransferClient/App.config b/FileTransferTest/FileTransferClient/App.config similarity index 59% rename from FileTransferClient/App.config rename to FileTransferTest/FileTransferClient/App.config index 56efbc7..4bfa005 100644 --- a/FileTransferClient/App.config +++ b/FileTransferTest/FileTransferClient/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/FileTransferClient/App.xaml b/FileTransferTest/FileTransferClient/App.xaml similarity index 100% rename from FileTransferClient/App.xaml rename to FileTransferTest/FileTransferClient/App.xaml diff --git a/FileTransferClient/App.xaml.cs b/FileTransferTest/FileTransferClient/App.xaml.cs similarity index 100% rename from FileTransferClient/App.xaml.cs rename to FileTransferTest/FileTransferClient/App.xaml.cs diff --git a/FileTransferClient/FileTransferClient.csproj b/FileTransferTest/FileTransferClient/FileTransferClient.csproj similarity index 78% rename from FileTransferClient/FileTransferClient.csproj rename to FileTransferTest/FileTransferClient/FileTransferClient.csproj index 9f3e473..22d48dd 100644 --- a/FileTransferClient/FileTransferClient.csproj +++ b/FileTransferTest/FileTransferClient/FileTransferClient.csproj @@ -8,12 +8,13 @@ WinExe FileTransferClient FileTransferClient - v4.7.2 + v4.8 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true true + AnyCPU @@ -34,6 +35,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + @@ -95,7 +118,7 @@ - + {06c9e60e-d449-41a7-9bf0-a829aaf5d214} ZeroLevel diff --git a/FileTransferClient/MainWindow.xaml b/FileTransferTest/FileTransferClient/MainWindow.xaml similarity index 100% rename from FileTransferClient/MainWindow.xaml rename to FileTransferTest/FileTransferClient/MainWindow.xaml diff --git a/FileTransferClient/MainWindow.xaml.cs b/FileTransferTest/FileTransferClient/MainWindow.xaml.cs similarity index 100% rename from FileTransferClient/MainWindow.xaml.cs rename to FileTransferTest/FileTransferClient/MainWindow.xaml.cs diff --git a/FileTransferClient/Properties/AssemblyInfo.cs b/FileTransferTest/FileTransferClient/Properties/AssemblyInfo.cs similarity index 100% rename from FileTransferClient/Properties/AssemblyInfo.cs rename to FileTransferTest/FileTransferClient/Properties/AssemblyInfo.cs diff --git a/FileTransferClient/Properties/Resources.Designer.cs b/FileTransferTest/FileTransferClient/Properties/Resources.Designer.cs similarity index 86% rename from FileTransferClient/Properties/Resources.Designer.cs rename to FileTransferTest/FileTransferClient/Properties/Resources.Designer.cs index bfe9b61..6ba3805 100644 --- a/FileTransferClient/Properties/Resources.Designer.cs +++ b/FileTransferTest/FileTransferClient/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace FileTransferClient.Properties -{ - - +namespace FileTransferClient.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace FileTransferClient.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FileTransferClient.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/FileTransferClient/Properties/Resources.resx b/FileTransferTest/FileTransferClient/Properties/Resources.resx similarity index 100% rename from FileTransferClient/Properties/Resources.resx rename to FileTransferTest/FileTransferClient/Properties/Resources.resx diff --git a/FileTransferServer/Properties/Settings.Designer.cs b/FileTransferTest/FileTransferClient/Properties/Settings.Designer.cs similarity index 82% rename from FileTransferServer/Properties/Settings.Designer.cs rename to FileTransferTest/FileTransferClient/Properties/Settings.Designer.cs index 50bcd50..10e2f9e 100644 --- a/FileTransferServer/Properties/Settings.Designer.cs +++ b/FileTransferTest/FileTransferClient/Properties/Settings.Designer.cs @@ -8,21 +8,17 @@ // //------------------------------------------------------------------------------ -namespace FileTransferServer.Properties -{ - - +namespace FileTransferClient.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/FileTransferClient/Properties/Settings.settings b/FileTransferTest/FileTransferClient/Properties/Settings.settings similarity index 100% rename from FileTransferClient/Properties/Settings.settings rename to FileTransferTest/FileTransferClient/Properties/Settings.settings diff --git a/FileTransferServer/App.config b/FileTransferTest/FileTransferServer/App.config similarity index 59% rename from FileTransferServer/App.config rename to FileTransferTest/FileTransferServer/App.config index 56efbc7..4bfa005 100644 --- a/FileTransferServer/App.config +++ b/FileTransferTest/FileTransferServer/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/FileTransferServer/App.xaml b/FileTransferTest/FileTransferServer/App.xaml similarity index 100% rename from FileTransferServer/App.xaml rename to FileTransferTest/FileTransferServer/App.xaml diff --git a/FileTransferServer/App.xaml.cs b/FileTransferTest/FileTransferServer/App.xaml.cs similarity index 100% rename from FileTransferServer/App.xaml.cs rename to FileTransferTest/FileTransferServer/App.xaml.cs diff --git a/FileTransferServer/FileTransferServer.csproj b/FileTransferTest/FileTransferServer/FileTransferServer.csproj similarity index 78% rename from FileTransferServer/FileTransferServer.csproj rename to FileTransferTest/FileTransferServer/FileTransferServer.csproj index d2186e3..0580d2c 100644 --- a/FileTransferServer/FileTransferServer.csproj +++ b/FileTransferTest/FileTransferServer/FileTransferServer.csproj @@ -8,12 +8,13 @@ WinExe FileTransferServer FileTransferServer - v4.7.2 + v4.8 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true true + AnyCPU @@ -34,6 +35,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + @@ -95,7 +118,7 @@ - + {06c9e60e-d449-41a7-9bf0-a829aaf5d214} ZeroLevel diff --git a/FileTransferServer/MainWindow.xaml b/FileTransferTest/FileTransferServer/MainWindow.xaml similarity index 100% rename from FileTransferServer/MainWindow.xaml rename to FileTransferTest/FileTransferServer/MainWindow.xaml diff --git a/FileTransferServer/MainWindow.xaml.cs b/FileTransferTest/FileTransferServer/MainWindow.xaml.cs similarity index 100% rename from FileTransferServer/MainWindow.xaml.cs rename to FileTransferTest/FileTransferServer/MainWindow.xaml.cs diff --git a/FileTransferServer/Properties/AssemblyInfo.cs b/FileTransferTest/FileTransferServer/Properties/AssemblyInfo.cs similarity index 100% rename from FileTransferServer/Properties/AssemblyInfo.cs rename to FileTransferTest/FileTransferServer/Properties/AssemblyInfo.cs diff --git a/FileTransferServer/Properties/Resources.Designer.cs b/FileTransferTest/FileTransferServer/Properties/Resources.Designer.cs similarity index 86% rename from FileTransferServer/Properties/Resources.Designer.cs rename to FileTransferTest/FileTransferServer/Properties/Resources.Designer.cs index 1f1bd16..c613e1a 100644 --- a/FileTransferServer/Properties/Resources.Designer.cs +++ b/FileTransferTest/FileTransferServer/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace FileTransferServer.Properties -{ - - +namespace FileTransferServer.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace FileTransferServer.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FileTransferServer.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/FileTransferServer/Properties/Resources.resx b/FileTransferTest/FileTransferServer/Properties/Resources.resx similarity index 100% rename from FileTransferServer/Properties/Resources.resx rename to FileTransferTest/FileTransferServer/Properties/Resources.resx diff --git a/FileTransferClient/Properties/Settings.Designer.cs b/FileTransferTest/FileTransferServer/Properties/Settings.Designer.cs similarity index 82% rename from FileTransferClient/Properties/Settings.Designer.cs rename to FileTransferTest/FileTransferServer/Properties/Settings.Designer.cs index b7f3576..c18311a 100644 --- a/FileTransferClient/Properties/Settings.Designer.cs +++ b/FileTransferTest/FileTransferServer/Properties/Settings.Designer.cs @@ -8,21 +8,17 @@ // //------------------------------------------------------------------------------ -namespace FileTransferClient.Properties -{ - - +namespace FileTransferServer.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/FileTransferServer/Properties/Settings.settings b/FileTransferTest/FileTransferServer/Properties/Settings.settings similarity index 100% rename from FileTransferServer/Properties/Settings.settings rename to FileTransferTest/FileTransferServer/Properties/Settings.settings diff --git a/Lemmatization/Model/Sentence.cs b/Lemmatization/Model/Sentence.cs deleted file mode 100644 index bff2738..0000000 --- a/Lemmatization/Model/Sentence.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Lemmatization -{ - public class Sentence - { - public Token[] Tokens; - } -} diff --git a/Lemmatization/Model/Token.cs b/Lemmatization/Model/Token.cs deleted file mode 100644 index 42a72f2..0000000 --- a/Lemmatization/Model/Token.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Lemmatization -{ - public class Token - { - public TokenType Type; - public string Value; - } -} diff --git a/Lemmatization/Model/TokenType.cs b/Lemmatization/Model/TokenType.cs deleted file mode 100644 index 69740e6..0000000 --- a/Lemmatization/Model/TokenType.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Lemmatization -{ - public enum TokenType - { - Unknown, - /// - /// Знак пукнтуации - /// - Punctuation, - /// - /// Аббревиатура - /// - Аbbreviation, - /// - /// Слово - /// - Word, - /// - /// Идентификатор (может содержать не только буквы) - /// - Identity, - /// - /// Число - /// - Number, - /// - /// Номер телефона - /// - PhoneNumber, - /// - /// Ссылка - /// - Link - } -} diff --git a/Lemmatization/Services/Adapters/LemmaLexer.cs b/Lemmatization/Services/Adapters/LemmaLexer.cs deleted file mode 100644 index 6bb9939..0000000 --- a/Lemmatization/Services/Adapters/LemmaLexer.cs +++ /dev/null @@ -1,21 +0,0 @@ -using LemmaSharp; -using ZeroLevel.Services.Semantic; - -namespace Lemmatization -{ - public class LemmaLexer - : ILexer - { - private readonly ILemmatizer _lemmatizer; - - public LemmaLexer() - { - _lemmatizer = new LemmatizerPrebuiltFull(LanguagePrebuilt.Russian); - } - - public string Lex(string word) - { - return _lemmatizer.Lemmatize(word.Trim().ToLowerInvariant()); - } - } -} diff --git a/Lemmatization/Services/SpecTextReader.cs b/Lemmatization/Services/SpecTextReader.cs deleted file mode 100644 index 9e1ef97..0000000 --- a/Lemmatization/Services/SpecTextReader.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Lemmatization -{ - public class SpecTextReader - { - private int _position; - private readonly string _template; - - public bool EOF => _position >= _template?.Length; - public bool StartPosition => _position == 0; - public bool LastPosition => _position == _template?.Length - 1; - public char Current => EOF ? char.MinValue : _template[_position]; - public char Next => EOF || LastPosition ? char.MinValue : _template[_position + 1]; - public char Preview => StartPosition ? char.MinValue : _template[_position - 1]; - - public SpecTextReader(string template) - { - _template = template; - _position = 0; - } - - public bool Move(int offset = 1) - { - if (EOF) return false; - if (LastPosition) { _position = _template.Length; return false; } - _position += offset; - if (_position >= _template.Length) - { - _position = _template.Length; - } - return true; - } - - public int SkipSpaces() - { - int count = 0; - while (EOF == false && char.IsWhiteSpace(Current)) { Move(); count++; } - return count; - } - - public void SkipBreaks() - { - while (EOF == false && char.IsWhiteSpace(Current)) Move(); - } - - public bool MoveBack() - { - _position = _position - 1; - if (_position < 0) - { - _position = 0; - return false; - } - return true; - } - - public int FindOffsetTo(char symbol) - { - if (_position == -1 || EOF || LastPosition) return -1; - var search_position = _position; - var sym = _template[search_position]; - while (search_position < _template.Length && false == sym.Equals(symbol)) - { - search_position++; - sym = _template[search_position]; - } - return sym.Equals(symbol) ? search_position - _position : -1; - } - - public bool Test(char sym, int offset = 0) - { - var index = _position + offset; - if (index < 0 || index >= _template.Length) return false; - return _template[index].Equals(sym); - } - - public string ReadIdentity() - { - string identity = string.Empty; - var offset = _position; - if (offset < _template.Length && char.IsLetter(_template[offset])) - { - var index = offset + 1; - while (index < _template.Length && (char.IsLetterOrDigit(_template[index]) || _template[index] == '_' || _template[index] == '-')) - index++; - identity = _template.Substring(offset, index - offset); - } - return identity.ToLowerInvariant(); - } - - public string ReadWord() - { - string identity = string.Empty; - var offset = _position; - if (offset < _template.Length && char.IsLetterOrDigit(_template[offset])) - { - var index = offset + 1; - while (index < _template.Length && char.IsLetterOrDigit(_template[index])) - index++; - identity = _template.Substring(offset, index - offset); - } - return identity; - } - - public static Token[] ParseToTokens(string line) - { - var list = new List(); - char[] buffer = new char[64]; - int count = 0; - - var add = new Action(ch => - { - buffer[count++] = ch; - if (buffer.Length == count) - { - // При нехватке места в буфере, расширяем в два раза место - var arr = new char[buffer.Length * 2]; - for (var k = 0; k < buffer.Length; k++) { arr[k] = buffer[k]; } - buffer = arr; - } - }); - - TokenType tt = TokenType.Unknown; - for (int i = 0; i < line.Length; i++) - { - if (char.IsLetter(line[i])) - { - if (tt == TokenType.Unknown) tt = TokenType.Word; - else if (tt == TokenType.Number) tt = TokenType.Identity; - add(line[i]); - } - else if (char.IsDigit(line[i])) - { - if (tt == TokenType.Unknown) tt = TokenType.Number; - else if (tt == TokenType.Word) tt = TokenType.Identity; - add(line[i]); - } - else if (char.IsWhiteSpace(line[i]) && tt != TokenType.Unknown) - { - if (count > 0) - { - list.Add(new Token { Type = tt, Value = new string(buffer, 0, count) }); - count = 0; - } - } - else - { - if (count > 0) - { - list.Add(new Token { Type = tt, Value = new string(buffer, 0, count) }); - count = 0; - } - if (char.IsWhiteSpace(line[i]) == false) - { - list.Add(new Token { Type = TokenType.Punctuation, Value = line[i].ToString() }); - } - } - } - if (count > 0) - { - list.Add(new Token { Type = tt, Value = new string(buffer, 0, count) }); - } - return list.ToArray(); - } - - public static IEnumerable ReadSentenses(string text) - { - if (false == string.IsNullOrEmpty(text)) - { - char[] buffer = new char[512]; - int count = 0; - - var add = new Action(ch => - { - buffer[count++] = ch; - if (buffer.Length == count) - { - // При нехватке места в буфере, расширяем в два раза место - var arr = new char[buffer.Length * 2]; - for (var k = 0; k < buffer.Length; k++) { arr[k] = buffer[k]; } - buffer = arr; - } - }); - - for (int i = 0; i < text.Length; i++) - { - switch (text[i]) - { - case '.': - if (count > 0) - { - yield return new Sentence { Tokens = ParseToTokens(new string(buffer, 0, count)) }; - count = 0; - } - break; - default: - add(text[i]); - break; - } - } - } - } - } -} diff --git a/TFIDFbee/TFIDFbee.sln b/TFIDFbee/TFIDFbee.sln deleted file mode 100644 index 23c1ec8..0000000 --- a/TFIDFbee/TFIDFbee.sln +++ /dev/null @@ -1,61 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TFIDFbee", "TFIDFbee\TFIDFbee.csproj", "{7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lemmatization", "..\Lemmatization\Lemmatization.csproj", "{98102DAA-F649-45FD-BBE9-F393DBF82275}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel", "..\ZeroLevel\ZeroLevel.csproj", "{6AF46F95-EA67-4258-96B1-7BBC57EB965D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{41061774-D2A1-4291-8909-62E4A63B03B4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Debug|x64.ActiveCfg = Debug|x64 - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Debug|x64.Build.0 = Debug|x64 - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Release|Any CPU.Build.0 = Release|Any CPU - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Release|x64.ActiveCfg = Release|Any CPU - {7B39E0A1-3DE4-4702-8D61-5C9A6CF164C6}.Release|x64.Build.0 = Release|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Debug|Any CPU.Build.0 = Debug|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Debug|x64.ActiveCfg = Debug|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Debug|x64.Build.0 = Debug|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Release|Any CPU.ActiveCfg = Release|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Release|Any CPU.Build.0 = Release|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Release|x64.ActiveCfg = Release|Any CPU - {98102DAA-F649-45FD-BBE9-F393DBF82275}.Release|x64.Build.0 = Release|Any CPU - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Debug|x64.ActiveCfg = Debug|x64 - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Debug|x64.Build.0 = Debug|x64 - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Release|Any CPU.Build.0 = Release|Any CPU - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Release|x64.ActiveCfg = Release|x64 - {6AF46F95-EA67-4258-96B1-7BBC57EB965D}.Release|x64.Build.0 = Release|x64 - {41061774-D2A1-4291-8909-62E4A63B03B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Debug|x64.ActiveCfg = Debug|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Debug|x64.Build.0 = Debug|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Release|Any CPU.Build.0 = Release|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Release|x64.ActiveCfg = Release|Any CPU - {41061774-D2A1-4291-8909-62E4A63B03B4}.Release|x64.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {F440F94E-537A-44F4-9103-BD6C7BCAF6E3} - EndGlobalSection -EndGlobal diff --git a/TFIDFbee/TFIDFbee/Document.cs b/TFIDFbee/TFIDFbee/Document.cs deleted file mode 100644 index a1183a9..0000000 --- a/TFIDFbee/TFIDFbee/Document.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TFIDFbee -{ - public class Document - { - public string Title { get; set; } - public string Text { get; set; } - } -} diff --git a/TFIDFbee/TFIDFbee/Program.cs b/TFIDFbee/TFIDFbee/Program.cs deleted file mode 100644 index ef8e6be..0000000 --- a/TFIDFbee/TFIDFbee/Program.cs +++ /dev/null @@ -1,178 +0,0 @@ -using Lemmatization; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using TFIDFbee.Reader; -using ZeroLevel.Services.Semantic; - -namespace TFIDFbee -{ - class Program - { - private const string source = @"D:\Desktop\lenta-ru-data-set_19990901_20171204_limit_1000.json"; - private readonly static ILexProvider _lexer = new LexProvider(new LemmaLexer()); - private readonly static ConcurrentDictionary _scoring = new ConcurrentDictionary(); - - static void Main(string[] args) - { - IDF idf = new IDF(); - IDocumentReader reader = new JsonByLineReader(source, _lexer); - foreach (var batch in reader.ReadBatches(1000)) - { - foreach (var doc in batch) - { - idf.Append(doc); - } - } - foreach (var batch in reader.ReadBatches(1000)) - { - foreach (var doc in batch) - { - var tfidf = TFIDF.TfIdf(doc, idf); - Console.WriteLine(String.Join(" ", tfidf.OrderByDescending(p => p.Value).Take(10).Select(p => p.Key))); - Console.WriteLine(); - Console.WriteLine(" ***"); - Console.WriteLine(); - Thread.Sleep(1000); - } - } - - - /* - Log.AddConsoleLogger(ZeroLevel.Logging.LogLevel.FullDebug); - Configuration.Save(Configuration.ReadFromApplicationConfig()); - IDocumentReader reader = new JsonByLineReader(source, s => ExtractLemmas(s)); - - ZeroLevel.Services.Semantic.Helpers.BagOfTerms codebook; - if (File.Exists("model.bin")) - { - Log.Info("Load model from file"); - using (var stream = new FileStream("model.bin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - codebook = MessageSerializer.Deserialize(stream); - } - } - else - { - Log.Info("Create and train model"); - codebook = new ZeroLevel.Services.Semantic.Helpers.BagOfTerms(); - foreach (var batch in reader.ReadBatches(1000)) - { - codebook.Learn(batch); - Log.Info($"\r\n\tDocuments: {codebook.NumberOfDocuments}\r\n\tWords: {codebook.NumberOfWords}"); - } - using (var stream = new FileStream("model.bin", FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - { - MessageSerializer.Serialize(stream, codebook); - } - } - - - Log.Info("Create vectors"); - - foreach (var docs in reader.ReadRawDocumentBatches(1000)) - { - foreach (var doc in docs) - { - var words = ExtractLemmas(doc.Item2).Concat(ExtractLemmas(doc.Item1)).Distinct().ToArray(); - var vector = codebook.Transform(words); - for (var i = 0; i< words.Length; i++) - { - var word = words[i]; - if (false == _scoring.ContainsKey(word)) - { - _scoring.TryAdd(word, vector) - } - } - } - } - using (var stream = new FileStream("vectors.bin", FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - { - MessageSerializer.SerializeCompatible>(stream, vectors); - } - - - Log.Info("Find similar documents"); - var list = new List>(); - long total_count = ((long)vectors.Count * (long)vectors.Count); - long count = 0; - double d = (double.Epsilon * 2.0d); - for (int i = 0; i < vectors.Count; i++) - { - for (int j = i + 1; j < vectors.Count - 1; j++) - { - count++; - if (count % 10000000 == 0) - { - Log.Info($"Progress: {((count * 100.0d) / total_count)} %.\tFound similars: {list.Count}."); - } - if (i == j) continue; - var diff = vectors[i].Measure(vectors[j]); - if (diff > d && diff < 0.0009d) - { - list.Add(Tuple.Create(diff, i, j)); - } - } - } - - Log.Info("Prepare to show similar documents"); - var to_present = list.OrderBy(e => e.Item1).Take(2000).ToArray(); - var to_present_map = new Dictionary>(); - foreach (var e in to_present) - { - if (!to_present_map.ContainsKey(e.Item2)) - { - to_present_map.Add(e.Item2, null); - } - if (!to_present_map.ContainsKey(e.Item3)) - { - to_present_map.Add(e.Item3, null); - } - } - - int index = 0; - foreach (var docs in reader.ReadRawDocumentBatches(1000)) - { - foreach (var doc in docs) - { - if (to_present_map.ContainsKey(index)) - { - to_present_map[index] = doc; - } - index++; - } - } - - Log.Info("Show similar documents"); - index = 0; - using (var output = new StreamWriter("out.txt")) - { - foreach (var e in to_present) - { - output.WriteLine($"#{index++}: {e.Item1}"); - output.WriteLine("-------------1--------------"); - output.WriteLine(to_present_map[e.Item2].Item1); - output.WriteLine(to_present_map[e.Item2].Item2); - output.WriteLine("-------------2--------------"); - output.WriteLine(to_present_map[e.Item3].Item1); - output.WriteLine(to_present_map[e.Item3].Item2); - output.WriteLine("#############################"); - output.WriteLine(); - } - } - */ - Console.WriteLine("Completed"); - Console.ReadKey(); - } - - private static IEnumerable ExtractLemmas(string text) - { - return - _lexer.ExtractUniqueLexTokensWithoutStopWords(text) - .Select(t => t.Token) - .Where(s => s.Any(c => char.IsLetter(c))); - } - } -} diff --git a/TFIDFbee/TFIDFbee/Reader/IDocumentReader.cs b/TFIDFbee/TFIDFbee/Reader/IDocumentReader.cs deleted file mode 100644 index 1ea2a21..0000000 --- a/TFIDFbee/TFIDFbee/Reader/IDocumentReader.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; -using ZeroLevel.Services.Semantic.Helpers; - -namespace TFIDFbee.Reader -{ - public interface IDocumentReader - { - IEnumerable> ReadBatches(int size); - } -} diff --git a/TFIDFbee/TFIDFbee/Reader/JsonByLineReader.cs b/TFIDFbee/TFIDFbee/Reader/JsonByLineReader.cs deleted file mode 100644 index aab8d70..0000000 --- a/TFIDFbee/TFIDFbee/Reader/JsonByLineReader.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using ZeroLevel.Services.Semantic; -using ZeroLevel.Services.Semantic.Helpers; - -namespace TFIDFbee.Reader -{ - public class JsonByLineReader - : IDocumentReader - { - private readonly string _file; - private readonly ILexProvider _lexer; - - public JsonByLineReader(string file, ILexProvider lexer) - { - _file = file; - _lexer = lexer; - } - - public IEnumerable> ReadBatches(int size) - { - string line; - var batch = new List(); - string title = null; - string text = null; - using (StreamReader reader = new StreamReader(_file)) - { - while ((line = reader.ReadLine()) != null) - { - var titleIndex = line.IndexOf("\"metaTitle\":"); - if (titleIndex >= 0) - { - var start = line.IndexOf("\"", titleIndex + 12); - var end = line.LastIndexOf("\""); - if (start < end && start != -1 && end != -1) - { - title = line.Substring(start + 1, end - start - 1); - } - } - else - { - var textIndex = line.IndexOf("\"plaintext\":"); - if (textIndex >= 0 && title != null) - { - var start = line.IndexOf("\"", textIndex + 12); - var end = line.LastIndexOf("\""); - if (start < end && start != -1 && end != -1) - { - text = line.Substring(start + 1, end - start - 1); - batch.Add(new BagOfTerms(title + " " + text, _lexer)); - if (batch.Count >= size) - { - yield return batch; - batch.Clear(); - GC.Collect(2); - } - title = null; - text = null; - } - } - } - } - } - if (batch.Count > 0) - { - yield return batch; - } - } - } -} diff --git a/TFIDFbee/TFIDFbee/Reader/StateMachineReader.cs b/TFIDFbee/TFIDFbee/Reader/StateMachineReader.cs deleted file mode 100644 index 8916a87..0000000 --- a/TFIDFbee/TFIDFbee/Reader/StateMachineReader.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using ZeroLevel.Services.Semantic; -using ZeroLevel.Services.Semantic.Helpers; - -namespace TFIDFbee.Reader -{ - public class StateMachineReader - : IDocumentReader - { - private readonly string _file; - private readonly ILexProvider _lexer; - - public StateMachineReader(string file, ILexProvider lexer) - { - _file = file; - _lexer = lexer; - } - - private IEnumerable Parse() - { - var result = new string[2]; - var parser = new RecordParser((k, v) => - { - switch (k) - { - case "metaTitle": result[0] = v; break; - case "plaintext": result[1] = v; break; - } - }); - char[] buffer = new char[16536]; - int count = 0; - using (StreamReader reader = new StreamReader(_file)) - { - while ((count = reader.Read(buffer, 0, buffer.Length)) > 0) - { - parser.Append(new string(buffer, 0, count)); - - if (!string.IsNullOrEmpty(result[0]) && !string.IsNullOrEmpty(result[1])) - { - yield return result; - result[0] = null; - result[1] = null; - } - } - } - } - - public IEnumerable> ReadBatches(int size) - { - var list = new List(); - foreach (var record in Parse()) - { - list.Add(new BagOfTerms(record[0] + " " + record[1], _lexer)); - if (list.Count > size) - { - yield return list.ToArray(); - list.Clear(); - } - } - if (list.Count > 0) - { - yield return list.ToArray(); - } - } - } -} diff --git a/TFIDFbee/TFIDFbee/RecordParser.cs b/TFIDFbee/TFIDFbee/RecordParser.cs deleted file mode 100644 index 65d7374..0000000 --- a/TFIDFbee/TFIDFbee/RecordParser.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Text; - -namespace TFIDFbee -{ - public class RecordParser - { - private enum RPState - { - WaitKey, - ParseKey, - WaitKeyConfirm, - WaitValue, - ParseValue - } - private readonly StringBuilder _builder = new StringBuilder(); - private RPState State = RPState.WaitKey; - private char _previous = '\0'; - private string _key; - private string _value; - private readonly Action _callback; - - public RecordParser(Action callback) - { - _callback = callback; - } - - public void Append(string text) - { - foreach (var ch in text) - { - switch (State) - { - case RPState.WaitKey: - if (ch.Equals('"')) - { - State = RPState.ParseKey; - _builder.Clear(); - } - break; - case RPState.ParseKey: - if (ch.Equals('"') && _previous != '\\') - { - if (_builder.Length > 0) - { - State = RPState.WaitKeyConfirm; - } - else - { - State = RPState.WaitKey; - } - } - else - { - _builder.Append(ch); - } - break; - case RPState.WaitKeyConfirm: - if (ch.Equals(':')) - { - _key = _builder.ToString(); - State = RPState.WaitValue; - } - else if (ch == ' ' || ch == '\r' || ch == '\n') - { - // nothing - } - else - { - State = RPState.WaitKey; - } - break; - case RPState.WaitValue: - if (ch.Equals('"')) - { - State = RPState.ParseValue; - _builder.Clear(); - } - else if (ch == ' ' || ch == '\r' || ch == '\n') - { - // nothing - } - else - { - State = RPState.WaitKey; - } - break; - case RPState.ParseValue: - if (ch.Equals('"') && _previous != '\\') - { - if (_builder.Length > 0) - { - _value = _builder.ToString(); - _callback(_key, _value); - } - State = RPState.WaitKey; - } - else - { - _builder.Append(ch); - } - break; - } - _previous = ch; - } - } - } -} diff --git a/TFIDFbee/TFIDFbee/TFIDFbee.csproj b/TFIDFbee/TFIDFbee/TFIDFbee.csproj deleted file mode 100644 index dad7995..0000000 --- a/TFIDFbee/TFIDFbee/TFIDFbee.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - Exe - netcoreapp3.1 - AnyCPU;x64 - - - - - - - - diff --git a/TFIDFbee/Tests/Program.cs b/TFIDFbee/Tests/Program.cs deleted file mode 100644 index fc54845..0000000 --- a/TFIDFbee/Tests/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using ZeroLevel.Services.Web; - -namespace Tests -{ - class Program - { - public String responseToWords(String response) - { - response = response - .ToLowerInvariant() - .Replace("", ",") - .Replace("", ",") - .Replace("(); - foreach (String word in response.Split(",")) - { - if (!string.IsNullOrWhiteSpace(word) && word.Length > 1) - { - array.Add(word); - } - } - array.Sort(); - response = string.Join(' ', array); - return response; - } - - private HttpClient GetClient() - { - var handler = new HttpClientHandler - { - AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, - UseDefaultCredentials = ZeroLevel.Configuration.Default.FirstOrDefault("useDefaultCredentianls"), - ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; } - }; - if (ZeroLevel.Configuration.Default.FirstOrDefault("useDefaultCredentianls")) - { - handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials; - } - var httpClient = new HttpClient(handler); - httpClient.DefaultRequestHeaders.Add("user-agent", UserAgents.Next()); - return httpClient; - } - - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/TFIDFbee/Tests/Tests.csproj b/TFIDFbee/Tests/Tests.csproj deleted file mode 100644 index f90f0c0..0000000 --- a/TFIDFbee/Tests/Tests.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - - - diff --git a/TestApp/Program.cs b/TestApp/Program.cs index 04923dd..11b5bd4 100644 --- a/TestApp/Program.cs +++ b/TestApp/Program.cs @@ -1,6 +1,12 @@ using Newtonsoft.Json; +using System; +using System.IO; +using System.Text; using ZeroLevel; +using ZeroLevel.Implementation.Semantic.Helpers; using ZeroLevel.Logging; +using ZeroLevel.Services.Serialization; +using ZeroLevel.Services.Trees; namespace TestApp { diff --git a/TestApp/TestApp.csproj b/TestApp/TestApp.csproj index 3220245..87d1d0a 100644 --- a/TestApp/TestApp.csproj +++ b/TestApp/TestApp.csproj @@ -3,6 +3,7 @@ Exe netcoreapp3.0 + AnyCPU;x64 diff --git a/TestPipeLine/Consumer/App.config b/TestPipeLine/Consumer/App.config index d9cdee5..6b307de 100644 --- a/TestPipeLine/Consumer/App.config +++ b/TestPipeLine/Consumer/App.config @@ -1,17 +1,17 @@ - + - + - - - - - + + + + + - \ No newline at end of file + diff --git a/TestPipeLine/Consumer/Consumer.csproj b/TestPipeLine/Consumer/Consumer.csproj index aa12fe6..1cf4aea 100644 --- a/TestPipeLine/Consumer/Consumer.csproj +++ b/TestPipeLine/Consumer/Consumer.csproj @@ -8,10 +8,11 @@ Exe Consumer Consumer - v4.7.2 + v4.8 512 true true + AnyCPU @@ -32,6 +33,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + diff --git a/TestPipeLine/Processor/App.config b/TestPipeLine/Processor/App.config index c0eba0f..f166411 100644 --- a/TestPipeLine/Processor/App.config +++ b/TestPipeLine/Processor/App.config @@ -1,17 +1,17 @@ - + - + - - - - - + + + + + - \ No newline at end of file + diff --git a/TestPipeLine/Processor/Processor.csproj b/TestPipeLine/Processor/Processor.csproj index 3e65033..614d554 100644 --- a/TestPipeLine/Processor/Processor.csproj +++ b/TestPipeLine/Processor/Processor.csproj @@ -8,10 +8,11 @@ Exe Processor Processor - v4.7.2 + v4.8 512 true true + AnyCPU @@ -32,6 +33,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + diff --git a/TestPipeLine/Source/App.config b/TestPipeLine/Source/App.config index 16180a0..dd4204c 100644 --- a/TestPipeLine/Source/App.config +++ b/TestPipeLine/Source/App.config @@ -1,17 +1,17 @@ - + - + - - - - - + + + + + - \ No newline at end of file + diff --git a/TestPipeLine/Source/Source.csproj b/TestPipeLine/Source/Source.csproj index 188e0eb..519a040 100644 --- a/TestPipeLine/Source/Source.csproj +++ b/TestPipeLine/Source/Source.csproj @@ -8,10 +8,11 @@ Exe Source Source - v4.7.2 + v4.8 512 true true + AnyCPU @@ -32,6 +33,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + diff --git a/TestPipeLine/Watcher/App.config b/TestPipeLine/Watcher/App.config index ed6214b..43e743a 100644 --- a/TestPipeLine/Watcher/App.config +++ b/TestPipeLine/Watcher/App.config @@ -1,17 +1,17 @@ - + - + - - - - - + + + + + - \ No newline at end of file + diff --git a/TestPipeLine/Watcher/Watcher.csproj b/TestPipeLine/Watcher/Watcher.csproj index 4250320..a78a7e0 100644 --- a/TestPipeLine/Watcher/Watcher.csproj +++ b/TestPipeLine/Watcher/Watcher.csproj @@ -8,10 +8,11 @@ Exe Watcher Watcher - v4.7.2 + v4.8 512 true true + AnyCPU @@ -32,6 +33,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + diff --git a/ZeroLevel.WPF/BaseViewModel.cs b/WPFExamples/BaseViewModel.cs similarity index 100% rename from ZeroLevel.WPF/BaseViewModel.cs rename to WPFExamples/BaseViewModel.cs diff --git a/ZeroLevel.WPF/Behaviours/ListBoxAutoScrollBehavior.cs b/WPFExamples/Behaviours/ListBoxAutoScrollBehavior.cs similarity index 100% rename from ZeroLevel.WPF/Behaviours/ListBoxAutoScrollBehavior.cs rename to WPFExamples/Behaviours/ListBoxAutoScrollBehavior.cs diff --git a/ZeroLevel.WPF/Controls/AlignableWrapPanel.cs b/WPFExamples/Controls/AlignableWrapPanel.cs similarity index 99% rename from ZeroLevel.WPF/Controls/AlignableWrapPanel.cs rename to WPFExamples/Controls/AlignableWrapPanel.cs index be1ba97..9d7fb74 100644 --- a/ZeroLevel.WPF/Controls/AlignableWrapPanel.cs +++ b/WPFExamples/Controls/AlignableWrapPanel.cs @@ -20,6 +20,7 @@ using System; using System.Windows; using System.Windows.Controls; +using System.Windows.Forms; namespace ZeroLevel.WPF { diff --git a/ZeroLevel.WPF/Controls/ControlUnlocker.cs b/WPFExamples/Controls/ControlUnlocker.cs similarity index 100% rename from ZeroLevel.WPF/Controls/ControlUnlocker.cs rename to WPFExamples/Controls/ControlUnlocker.cs diff --git a/ZeroLevel.WPF/Controls/VirtualToggleButton.cs b/WPFExamples/Controls/VirtualToggleButton.cs similarity index 100% rename from ZeroLevel.WPF/Controls/VirtualToggleButton.cs rename to WPFExamples/Controls/VirtualToggleButton.cs diff --git a/ZeroLevel.WPF/Convertors/BaseConvertor.cs b/WPFExamples/Convertors/BaseConvertor.cs similarity index 100% rename from ZeroLevel.WPF/Convertors/BaseConvertor.cs rename to WPFExamples/Convertors/BaseConvertor.cs diff --git a/ZeroLevel.WPF/Convertors/BoolToVisibilityConverter.cs b/WPFExamples/Convertors/BoolToVisibilityConverter.cs similarity index 100% rename from ZeroLevel.WPF/Convertors/BoolToVisibilityConverter.cs rename to WPFExamples/Convertors/BoolToVisibilityConverter.cs diff --git a/ZeroLevel.WPF/Convertors/BooleanAndConverter.cs b/WPFExamples/Convertors/BooleanAndConverter.cs similarity index 100% rename from ZeroLevel.WPF/Convertors/BooleanAndConverter.cs rename to WPFExamples/Convertors/BooleanAndConverter.cs diff --git a/ZeroLevel.WPF/Helpers/BitmapSourceHelper.cs b/WPFExamples/Helpers/BitmapSourceHelper.cs similarity index 100% rename from ZeroLevel.WPF/Helpers/BitmapSourceHelper.cs rename to WPFExamples/Helpers/BitmapSourceHelper.cs diff --git a/ZeroLevel.WPF/RelayCommand.cs b/WPFExamples/RelayCommand.cs similarity index 100% rename from ZeroLevel.WPF/RelayCommand.cs rename to WPFExamples/RelayCommand.cs diff --git a/WebSemanticService/semantic/Semantic.API.Proxy/Semantic.API.Proxy.csproj b/WebSemanticService/semantic/Semantic.API.Proxy/Semantic.API.Proxy.csproj index c0097a3..eaaca62 100644 --- a/WebSemanticService/semantic/Semantic.API.Proxy/Semantic.API.Proxy.csproj +++ b/WebSemanticService/semantic/Semantic.API.Proxy/Semantic.API.Proxy.csproj @@ -43,12 +43,12 @@ - ..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - C:\Users\a.bozhenov\Desktop\SEOPortal\Utils\Semantic\packages\ZeroLevel.3.0.0\lib\netstandard2.0\ZeroLevel.dll + + ..\..\packages\ZeroLevel.3.3.3\lib\netstandard2.0\ZeroLevel.dll diff --git a/WebSemanticService/semantic/Semantic.API.Proxy/packages.config b/WebSemanticService/semantic/Semantic.API.Proxy/packages.config index 7fcda0d..94c6105 100644 --- a/WebSemanticService/semantic/Semantic.API.Proxy/packages.config +++ b/WebSemanticService/semantic/Semantic.API.Proxy/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/WebSemanticService/semantic/Semantic.API/Semantic.API.csproj b/WebSemanticService/semantic/Semantic.API/Semantic.API.csproj index 57b3a8e..72e918e 100644 --- a/WebSemanticService/semantic/Semantic.API/Semantic.API.csproj +++ b/WebSemanticService/semantic/Semantic.API/Semantic.API.csproj @@ -46,23 +46,23 @@ - - ..\..\packages\Microsoft.Owin.4.0.1\lib\net45\Microsoft.Owin.dll + + ..\..\packages\Microsoft.Owin.4.1.0\lib\net45\Microsoft.Owin.dll - - ..\..\packages\Microsoft.Owin.FileSystems.4.0.1\lib\net45\Microsoft.Owin.FileSystems.dll + + ..\..\packages\Microsoft.Owin.FileSystems.4.1.0\lib\net45\Microsoft.Owin.FileSystems.dll - - packages\Microsoft.Owin.Host.HttpListener.4.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll + + ..\..\packages\Microsoft.Owin.Host.HttpListener.4.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll - - packages\Microsoft.Owin.Hosting.4.0.1\lib\net45\Microsoft.Owin.Hosting.dll + + ..\..\packages\Microsoft.Owin.Hosting.4.1.0\lib\net45\Microsoft.Owin.Hosting.dll - - ..\..\packages\Microsoft.Owin.StaticFiles.4.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll + + ..\..\packages\Microsoft.Owin.StaticFiles.4.1.0\lib\net45\Microsoft.Owin.StaticFiles.dll - packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll ..\..\packages\Owin.1.0\lib\net40\Owin.dll @@ -82,8 +82,8 @@ ..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.7\lib\net45\System.Web.Http.Owin.dll - - packages\ZeroLevel.2.0.8\lib\netstandard2.0\ZeroLevel.dll + + ..\..\packages\ZeroLevel.3.3.3\lib\netstandard2.0\ZeroLevel.dll diff --git a/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/Test.Semantic.API.Proxy.csproj b/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/Test.Semantic.API.Proxy.csproj index 552484d..5a86304 100644 --- a/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/Test.Semantic.API.Proxy.csproj +++ b/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/Test.Semantic.API.Proxy.csproj @@ -41,8 +41,8 @@ - - ..\..\..\packages\ZeroLevel.2.0.8\lib\netstandard2.0\ZeroLevel.dll + + ..\..\..\packages\ZeroLevel.3.3.3\lib\netstandard2.0\ZeroLevel.dll diff --git a/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/packages.config b/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/packages.config index 778ce5c..37b9420 100644 --- a/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/packages.config +++ b/WebSemanticService/semantic/Semantic.API/Test.Semantic.API.Proxy/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/WebSemanticService/semantic/Semantic.API/app.config b/WebSemanticService/semantic/Semantic.API/app.config index 329da66..ebe1710 100644 --- a/WebSemanticService/semantic/Semantic.API/app.config +++ b/WebSemanticService/semantic/Semantic.API/app.config @@ -23,7 +23,7 @@ - + diff --git a/WebSemanticService/semantic/Semantic.API/packages.config b/WebSemanticService/semantic/Semantic.API/packages.config index 45070f6..5709de8 100644 --- a/WebSemanticService/semantic/Semantic.API/packages.config +++ b/WebSemanticService/semantic/Semantic.API/packages.config @@ -4,12 +4,12 @@ - - - - - - + + + + + + - + \ No newline at end of file diff --git a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj b/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj index f349b94..8ac8cbd 100644 --- a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj +++ b/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj @@ -2,7 +2,8 @@ Exe - netcoreapp2.2 + netcoreapp3.1 + AnyCPU;x64 diff --git a/ZeroLevel.EventServer/ZeroLevel.EventServer.csproj b/ZeroLevel.EventServer/ZeroLevel.EventServer.csproj deleted file mode 100644 index e3deba8..0000000 --- a/ZeroLevel.EventServer/ZeroLevel.EventServer.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - - - - - - - - - - Always - - - - diff --git a/ZeroLevel.EventServer/config.ini b/ZeroLevel.EventServer/config.ini deleted file mode 100644 index 7fc2d70..0000000 --- a/ZeroLevel.EventServer/config.ini +++ /dev/null @@ -1 +0,0 @@ -discovery=localhost:9030 diff --git a/ZeroLevel.EventServer/EventRepository.cs b/ZeroLevel.EventsServer/EventRepository.cs similarity index 100% rename from ZeroLevel.EventServer/EventRepository.cs rename to ZeroLevel.EventsServer/EventRepository.cs diff --git a/ZeroLevel.EventServer/EventService.cs b/ZeroLevel.EventsServer/EventService.cs similarity index 100% rename from ZeroLevel.EventServer/EventService.cs rename to ZeroLevel.EventsServer/EventService.cs diff --git a/ZeroLevel.EventServer/Model/BaseEvent.cs b/ZeroLevel.EventsServer/Model/BaseEvent.cs similarity index 100% rename from ZeroLevel.EventServer/Model/BaseEvent.cs rename to ZeroLevel.EventsServer/Model/BaseEvent.cs diff --git a/ZeroLevel.EventServer/Model/Condition.cs b/ZeroLevel.EventsServer/Model/Condition.cs similarity index 100% rename from ZeroLevel.EventServer/Model/Condition.cs rename to ZeroLevel.EventsServer/Model/Condition.cs diff --git a/ZeroLevel.EventServer/Model/EventAfterEvent.cs b/ZeroLevel.EventsServer/Model/EventAfterEvent.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventAfterEvent.cs rename to ZeroLevel.EventsServer/Model/EventAfterEvent.cs diff --git a/ZeroLevel.EventServer/Model/EventAfterEvents.cs b/ZeroLevel.EventsServer/Model/EventAfterEvents.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventAfterEvents.cs rename to ZeroLevel.EventsServer/Model/EventAfterEvents.cs diff --git a/ZeroLevel.EventServer/Model/EventInfoRecord.cs b/ZeroLevel.EventsServer/Model/EventInfoRecord.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventInfoRecord.cs rename to ZeroLevel.EventsServer/Model/EventInfoRecord.cs diff --git a/ZeroLevel.EventServer/Model/EventResult.cs b/ZeroLevel.EventsServer/Model/EventResult.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventResult.cs rename to ZeroLevel.EventsServer/Model/EventResult.cs diff --git a/ZeroLevel.EventServer/Model/EventResultState.cs b/ZeroLevel.EventsServer/Model/EventResultState.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventResultState.cs rename to ZeroLevel.EventsServer/Model/EventResultState.cs diff --git a/ZeroLevel.EventServer/Model/EventType.cs b/ZeroLevel.EventsServer/Model/EventType.cs similarity index 100% rename from ZeroLevel.EventServer/Model/EventType.cs rename to ZeroLevel.EventsServer/Model/EventType.cs diff --git a/ZeroLevel.EventServer/Model/OneTimeEvent.cs b/ZeroLevel.EventsServer/Model/OneTimeEvent.cs similarity index 100% rename from ZeroLevel.EventServer/Model/OneTimeEvent.cs rename to ZeroLevel.EventsServer/Model/OneTimeEvent.cs diff --git a/ZeroLevel.EventServer/Model/PeriodicTimeEvent.cs b/ZeroLevel.EventsServer/Model/PeriodicTimeEvent.cs similarity index 100% rename from ZeroLevel.EventServer/Model/PeriodicTimeEvent.cs rename to ZeroLevel.EventsServer/Model/PeriodicTimeEvent.cs diff --git a/ZeroLevel.EventServer/Program.cs b/ZeroLevel.EventsServer/Program.cs similarity index 100% rename from ZeroLevel.EventServer/Program.cs rename to ZeroLevel.EventsServer/Program.cs diff --git a/Lemmatization/Lemmatization.csproj b/ZeroLevel.EventsServer/ZeroLevel.EventsServer.csproj similarity index 57% rename from Lemmatization/Lemmatization.csproj rename to ZeroLevel.EventsServer/ZeroLevel.EventsServer.csproj index 9e12723..2bc99ac 100644 --- a/Lemmatization/Lemmatization.csproj +++ b/ZeroLevel.EventsServer/ZeroLevel.EventsServer.csproj @@ -2,14 +2,11 @@ netstandard2.0 + AnyCPU;x64 - - - - - + diff --git a/ZeroLevel.Logger/ZeroLevel.Logger.csproj b/ZeroLevel.Logger/ZeroLevel.Logger.csproj index 16f7ba0..6361a35 100644 --- a/ZeroLevel.Logger/ZeroLevel.Logger.csproj +++ b/ZeroLevel.Logger/ZeroLevel.Logger.csproj @@ -3,6 +3,7 @@ Exe netcoreapp3.1 + AnyCPU;x64 diff --git a/ZeroLevel.SqLite/BaseSqLiteDB.cs b/ZeroLevel.SqLite/BaseSqLiteDB.cs index bd8fb26..0cae7c2 100644 --- a/ZeroLevel.SqLite/BaseSqLiteDB.cs +++ b/ZeroLevel.SqLite/BaseSqLiteDB.cs @@ -1,5 +1,5 @@ -using System; -using System.Data.SQLite; +using System.Data.SQLite; +using System; using System.IO; using ZeroLevel.Services.FileSystem; diff --git a/ZeroLevel.SqLite/ZeroLevel.SqLite.csproj b/ZeroLevel.SqLite/ZeroLevel.SqLite.csproj index 4a55243..b49c5ed 100644 --- a/ZeroLevel.SqLite/ZeroLevel.SqLite.csproj +++ b/ZeroLevel.SqLite/ZeroLevel.SqLite.csproj @@ -11,11 +11,11 @@ Based on System.Data.SQLite.Core https://github.com/ogoun/Zero zero.png + AnyCPU;x64 - @@ -25,4 +25,8 @@ Based on System.Data.SQLite.Core + + + + diff --git a/ZeroLevel.SqlServer/BaseSqlDbMapper.cs b/ZeroLevel.SqlServer/BaseSqlDbMapper.cs deleted file mode 100644 index c943058..0000000 --- a/ZeroLevel.SqlServer/BaseSqlDbMapper.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Text; - -namespace ZeroLevel.SqlServer -{ - public abstract class BaseSqlDbMapper - { - protected abstract IDbMapper Mapper { get; } - protected readonly string _tableName; - - public string TableName { get { return _tableName; } } - - protected BaseSqlDbMapper(string tableName) - { - _tableName = tableName; - } - - public object GetIdentity(object entity) - { - if (Mapper.IdentityField != null) - return Mapper.IdentityField.Getter(entity); - return null; - } - - public string IdentityName - { - get - { - return Mapper.IdentityField?.Name; - } - } - - #region QUERIES - #region INDEXES - public string GetIndexExistsQuery(IDbField field) - { - if (field.IsIndexed) - { - return string.Format( - "SELECT COUNT(*) FROM sys.indexes WHERE name = 'idx_{0}_{1}' AND object_id = OBJECT_ID('{2}')", - _tableName, field.Name, _tableName); - } - return null; - } - - public string GetCreateIndexQuery(IDbField field) - { - if (field.IsIndexed) - { - return string.Format("CREATE INDEX idx_{0}_{1} ON [{2}]({3});", _tableName, field.Name, _tableName, field.Name); - } - return null; - } - #endregion - - #region CREATE - public static HashSet FieldsHasSize = new HashSet - { - DbType.String, DbType.Decimal, DbType.AnsiString, DbType.AnsiStringFixedLength, - DbType.StringFixedLength, DbType.VarNumeric - }; - - private string _createString = null; - private readonly object _createStringBuildLocker = new object(); - public string GetCreateQuery(bool rebuild = false) - { - lock (_createStringBuildLocker) - { - if (_createString == null || rebuild) - { - StringBuilder create = new StringBuilder("CREATE TABLE [" + _tableName + "]"); - create.Append("("); - Mapper.TraversalFields(f => - { - var sqlType = DbTypeMapper.ToSqlDbType(f.ClrType); - create.Append("[" + f.Name + "] " + sqlType); - if (FieldsHasSize.Contains(f.DbType) && f.Size != 0) - { - if (f.DbType == DbType.Decimal) - { - int p = 19, s = 4; - if (f.Size > 0) - { - p = (int)f.Size; - if (s >= p) - { - if (p <= 2) s = 0; - else s = p - 1; - } - } - create.AppendFormat("({0},{1})", p, s); - } - else - { - create.AppendFormat("({0})", ((f.Size == -1) ? "max" : f.Size.ToString())); - } - } - if (f.IsIdentity) - { - create.Append(" PRIMARY KEY"); - } - if (f.AllowNull) - { - create.Append(" NULL"); - } - else - { - create.Append(" NOT NULL"); - } - if (f.AutoIncrement) - { - create.Append(" IDENTITY (0, 1)"); - } - create.Append(","); - }); - _createString = create.ToString().TrimEnd(',') + ")"; - } - } - return _createString; - } - #endregion - #endregion - - public SqlParameter[] CreateSqlDbParameters(object entity) - { - if (entity.GetType() != Mapper.EntityType) - throw new InvalidCastException("Entity type is different from serializer entity type"); - var list = new List(); - Mapper.TraversalFields(field => - { - var par = new SqlParameter(); - par.Value = ValueToSqlServerObject(field.Getter(entity), field.ClrType); - // ADO.NET bug - // https://connect.microsoft.com/VisualStudio/feedback/details/381934/sqlparameter-dbtype-dbtype-time-sets-the-parameter-to-sqldbtype-datetime-instead-of-sqldbtype-time - if (field.DbType == DbType.Time) - { - par.SqlDbType = SqlDbType.Time; - } - else - { - par.DbType = field.DbType; // Если задать в конструкторе, то тип может переопределиться при задании значения - } - par.ParameterName = field.Name; - list.Add(par); - }); - return list.ToArray(); - } - - #region Datetime helper - private static DateTime MinSqlDbDateTimeValue = new DateTime(1753, 01, 01); - - protected object ValueToSqlServerObject(object obj, Type type) - { - if (type == typeof(DateTime)) - { - return DateTimeToSqlDbValue((DateTime)obj); - } - return obj ?? DBNull.Value; - } - /// - /// Подготовка даты к записи в SQLServer - /// (минимальные значения даты в .NET и SQL Server отличаются) - /// - protected object DateTimeToSqlDbValue(DateTime dt) - { - if (DateTime.Compare(dt, MinSqlDbDateTimeValue) <= 0) - return DBNull.Value; - return dt; - } - /// - /// Конвертер из элементов строки DataTable в DonNet тип - /// - /// Тип на выходе - /// Значение из БД - /// Результат - protected Tout Convert(object value) - { - if (null == value || DBNull.Value == value) - return default(Tout); - return (Tout)System.Convert.ChangeType(value, typeof(Tout)); - } - #endregion - } -} diff --git a/ZeroLevel.SqlServer/Contracts/BaseEntity.cs b/ZeroLevel.SqlServer/Contracts/BaseEntity.cs deleted file mode 100644 index 34283ee..0000000 --- a/ZeroLevel.SqlServer/Contracts/BaseEntity.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace ZeroLevel.SqlServer -{ - [DataContract] - [Serializable] - public abstract class BaseEntity : IEntity - { - #region Properties - [DataMember] - [DbMember(false, true, false)] - public Guid Id - { - get; - set; - } - #endregion - - #region Ctors - protected BaseEntity() - { - Id = Guid.NewGuid(); - } - protected BaseEntity(Guid id) - { - if (id == Guid.Empty) - throw new ArgumentException("Entity id must not be empty"); - Id = id; - } - protected BaseEntity(BaseEntity other) - { - if (other == null) - throw new ArgumentNullException(nameof(other)); - Id = other.Id; - } - #endregion - - public abstract object Clone(); - - #region Equal - public bool Equals(BaseEntity other) - { - if (this == null) // и так бывает - throw new NullReferenceException(); - if (other == null) - return false; - if (ReferenceEquals(this, other)) - return true; - if (this.GetType() != other.GetType()) - return false; - return Id == other.Id; - } - - public override bool Equals(object obj) - { - if (this == null) - throw new NullReferenceException(); - - return Equals(obj as BaseEntity); - } - - public static bool operator ==(BaseEntity first, BaseEntity second) => Equals(first, second); - public static bool operator !=(BaseEntity first, BaseEntity second) => !Equals(first, second); - #endregion - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/BaseVersionedEntity.cs b/ZeroLevel.SqlServer/Contracts/BaseVersionedEntity.cs deleted file mode 100644 index e8d9b33..0000000 --- a/ZeroLevel.SqlServer/Contracts/BaseVersionedEntity.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace ZeroLevel.SqlServer -{ - [DataContract] - [Serializable] - public abstract class BaseVersionedEntity : BaseEntity, IVersionedEntity - { - #region Properties - [DataMember] - [DbMember(false)] - public long Version - { - get; - internal set; - } - #endregion - - #region Ctors - protected BaseVersionedEntity() - : base() - { - } - // Конструктор protected BaseVersionedEntity(Guid id) исключен, т.к. без версии нет смысла создавать обхект с известным ID - - protected BaseVersionedEntity(Guid id, long version) - : base(id) - { - Version = version; - } - protected BaseVersionedEntity(BaseVersionedEntity other) - : base(other) - { - Version = other.Version; - } - #endregion - - public bool Equals(BaseVersionedEntity other) - { - if (base.Equals(other) == false) return false; - return Version == other.Version; - } - - public override bool Equals(object obj) - { - return Equals(obj as BaseVersionedEntity); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/DbIndexAttribute.cs b/ZeroLevel.SqlServer/Contracts/DbIndexAttribute.cs deleted file mode 100644 index 31f6008..0000000 --- a/ZeroLevel.SqlServer/Contracts/DbIndexAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public class DbIndexAttribute : Attribute - { - public DbIndexAttribute() { } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/DbMemberAttribute.cs b/ZeroLevel.SqlServer/Contracts/DbMemberAttribute.cs deleted file mode 100644 index c93c7de..0000000 --- a/ZeroLevel.SqlServer/Contracts/DbMemberAttribute.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public class DbMemberAttribute : Attribute - { - #region Properties - public bool AllowNull { get; } - public bool AutoIncrement { get; } - public bool IsIdentity { get; } - public long Size { get; } - #endregion - - #region Ctors - public DbMemberAttribute(bool allowNull) - : this(allowNull, -1, false, false) { } - - public DbMemberAttribute(bool allowNull, long size) - : this(allowNull, size, false, false) { } - - public DbMemberAttribute(bool allowNull, bool isIdentity) - : this(allowNull, -1, isIdentity, false) { } - - public DbMemberAttribute(bool allowNull, bool isIdentity, bool autoIncrement) - : this(allowNull, -1, isIdentity, autoIncrement) { } - - public DbMemberAttribute(bool allowNull, long size, bool isIdentity) - : this(allowNull, size, isIdentity, false) { } - - public DbMemberAttribute(bool allowNull, long size, bool isIdentity, bool autoIncrement) - { - AllowNull = allowNull; - AutoIncrement = autoIncrement; - IsIdentity = isIdentity; - Size = size; - } - #endregion - } -} diff --git a/ZeroLevel.SqlServer/Contracts/IDbField.cs b/ZeroLevel.SqlServer/Contracts/IDbField.cs deleted file mode 100644 index f8d41cf..0000000 --- a/ZeroLevel.SqlServer/Contracts/IDbField.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Data; -using ZeroLevel.Services.ObjectMapping; - -namespace ZeroLevel.SqlServer -{ - public interface IDbField: - IMemberInfo - { - bool AutoIncrement { get; } - bool IsIdentity { get; } - bool IsIndexed { get; } - bool AllowNull { get; } - long Size { get; } - DbType DbType { get; } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/IDbMapper.cs b/ZeroLevel.SqlServer/Contracts/IDbMapper.cs deleted file mode 100644 index b9206e0..0000000 --- a/ZeroLevel.SqlServer/Contracts/IDbMapper.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Data; -using System.Data.Common; - -namespace ZeroLevel.SqlServer -{ - public interface IDbMapper - { - IDbField this[string name] { get; } - IDbField IdentityField { get; } - Type EntityType { get; } - object Id(object entity); - void TraversalFields(Action callback); - void TraversalFields(Func callback); - void SetTypeConverter(Func converter); - bool Exists(string name); - - #region Serialization - object Deserialize(DataRow row); - object Deserialize(DbDataReader reader); - #endregion - } - - public interface IDbMapper : IDbMapper - { - new T Deserialize(DataRow row); - new T Deserialize(DbDataReader reader); - } -} diff --git a/ZeroLevel.SqlServer/Contracts/IDbProvider.cs b/ZeroLevel.SqlServer/Contracts/IDbProvider.cs deleted file mode 100644 index df72029..0000000 --- a/ZeroLevel.SqlServer/Contracts/IDbProvider.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; - -namespace ZeroLevel.SqlServer -{ - public interface IDbProvider - { - bool ExistsTable(string tableName); - DataTable ExecuteQueryDataTable(string query); - DataTable ExecuteQueryDataTable(string query, DbParameter[] par); - DataSet ExecuteQuerySqlDataSet(string query); - DataSet ExecuteQuerySqlDataSet(string query, DbParameter[] par); - object ExecuteScalar(string query); - object ExecuteScalar(string query, DbParameter[] par); - void ExecuteNonResult(IEnumerable commands); - int ExecuteNonResult(string query); - int ExecuteNonResult(string query, DbParameter[] par); - void LazySelect(string query, DbParameter[] par, Func readHandler, int timeout); - void LazySelectWithParameters(string query, IEnumerable> par, Func readHandler, int timeout); - } -} diff --git a/ZeroLevel.SqlServer/Contracts/IEntity.cs b/ZeroLevel.SqlServer/Contracts/IEntity.cs deleted file mode 100644 index ef188d7..0000000 --- a/ZeroLevel.SqlServer/Contracts/IEntity.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public interface IEntity : ICloneable - { - Guid Id { get; } - } - - public interface IEntity : ICloneable - { - TKey Id { get; } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/IVersionedEntity.cs b/ZeroLevel.SqlServer/Contracts/IVersionedEntity.cs deleted file mode 100644 index c69b174..0000000 --- a/ZeroLevel.SqlServer/Contracts/IVersionedEntity.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZeroLevel.SqlServer -{ - public interface IVersionedEntity : IEntity - { - long Version { get; } - } -} diff --git a/ZeroLevel.SqlServer/Contracts/ZSqlCommand.cs b/ZeroLevel.SqlServer/Contracts/ZSqlCommand.cs deleted file mode 100644 index 98f8012..0000000 --- a/ZeroLevel.SqlServer/Contracts/ZSqlCommand.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Data.Common; - -namespace ZeroLevel.SqlServer -{ - public class ZSqlCommand - { - public string Query; - public DbParameter[] Parameters; - } -} \ No newline at end of file diff --git a/ZeroLevel.SqlServer/DDD/IdentitySpecification.cs b/ZeroLevel.SqlServer/DDD/IdentitySpecification.cs deleted file mode 100644 index 999a0d6..0000000 --- a/ZeroLevel.SqlServer/DDD/IdentitySpecification.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Runtime.Serialization; -using ZeroLevel.Specification; - -namespace ZeroLevel.SqlServer -{ - [DataContract] - [Serializable] - public class IdentitySpecification : BaseSpecification - where T : IEntity - { - [DataMember] - protected Guid _id; - - public IdentitySpecification(Guid id) - { - _id = id; - } - - public override bool IsSatisfiedBy(T o) - { - return o.Id == _id; - } - - public static ISpecification Create(Guid id) { return new IdentitySpecification(id); } - public static ISpecification Create(IEntity entity) { return new IdentitySpecification(entity.Id); } - } - - [DataContract] - [Serializable] - public class IdentitySpecification : BaseSpecification - { - [DataMember] - private TKey _id; - private readonly IDbMapper _mapper; - - public IdentitySpecification(TKey id, bool poco) - { - _id = id; - _mapper = DbMapperFactory.Create(poco); - } - - public override bool IsSatisfiedBy(T o) - { - return _mapper.Id(o).Equals(_id); - } - - public static ISpecification Create(TKey id, bool poco) { return new IdentitySpecification(id, poco); } - } -} diff --git a/ZeroLevel.SqlServer/DDD/SqlIdentitySpecification.cs b/ZeroLevel.SqlServer/DDD/SqlIdentitySpecification.cs deleted file mode 100644 index 98495a7..0000000 --- a/ZeroLevel.SqlServer/DDD/SqlIdentitySpecification.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Data.SqlClient; -using ZeroLevel.SqlServer; -using ZeroLevel.Specification; - -namespace ZeroLevel.SqlServer -{ - public class SqlIdentitySpecification : IdentitySpecification, ISqlServerSpecification - where T : IEntity - { - public SqlIdentitySpecification(Guid id) : base(id) - { - } - - public SqlParameter[] Parameters - { - get - { - return new SqlParameter[] - { - new SqlParameter(DbMapperFactory.Create().IdentityField.Name, _id) - }; - } - } - - public string Query - { - get - { - return string.Empty; - } - } - - public static ISpecification Create(Guid id) where Te: IEntity - { return new SqlIdentitySpecification(id); } - } -} diff --git a/ZeroLevel.SqlServer/DbField.cs b/ZeroLevel.SqlServer/DbField.cs deleted file mode 100644 index bf6f780..0000000 --- a/ZeroLevel.SqlServer/DbField.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Data; -using System.Reflection; -using ZeroLevel.Services.ObjectMapping; -using ZeroLevel.Services.Reflection; - -namespace ZeroLevel.SqlServer -{ - public class DbField : MapMemberInfo, IDbField - { - public bool AutoIncrement { get; internal set; } - public bool IsIdentity { get; internal set; } - public bool IsIndexed { get; internal set; } - public bool AllowNull { get; internal set; } - public long Size { get; internal set; } - public DbType DbType { get; internal set; } - - private DbField(Action setter, Func getter) - :base(setter, getter) - { - } - - private static bool IsNullable(Type type) - { - if (!type.IsValueType) return true; // ref-type - if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable - return false; // value-type - } - - public static DbField FromField(FieldInfo fieldInfo) - { - var meta = ((DbMemberAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DbMemberAttribute))); - var index = ((DbIndexAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DbIndexAttribute))); - var field = new DbField(TypeGetterSetterBuilder.BuildSetter(fieldInfo), TypeGetterSetterBuilder.BuildGetter(fieldInfo)) - { - Name = fieldInfo.Name, - IsIdentity = meta?.IsIdentity ?? false, - AllowNull = meta?.AllowNull ?? true, - AutoIncrement = meta?.AutoIncrement ?? false, - Size = meta?.Size ?? -1, - IsIndexed = index != null - }; - field.IsField = true; - var type = fieldInfo.FieldType; - field.ClrType = type; - field.DbType = type.ToDbType(); - return field; - } - - public static DbField FromProperty(PropertyInfo propertyInfo) - { - var meta = ((DbMemberAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DbMemberAttribute))); - var index = ((DbIndexAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DbIndexAttribute))); - var field = new DbField(TypeGetterSetterBuilder.BuildSetter(propertyInfo), TypeGetterSetterBuilder.BuildGetter(propertyInfo)) - { - Name = propertyInfo.Name, - IsIdentity = meta?.IsIdentity ?? false, - AllowNull = meta?.AllowNull ?? true, - AutoIncrement = meta?.AutoIncrement ?? false, - Size = meta?.Size ?? -1, - IsIndexed = index != null - }; - field.IsField = false; - var type = propertyInfo.PropertyType; - field.ClrType = type; - field.DbType = type.ToDbType(); - return field; - } - - public new static DbField FromMember(MemberInfo memberInfo) - { - switch (memberInfo.MemberType) - { - case MemberTypes.Field: - return FromField(memberInfo as FieldInfo); - case MemberTypes.Property: - return FromProperty(memberInfo as PropertyInfo); - } - return null; - } - - public void SetValue(object instance, object dbvalue, Func converter = null) - { - var value = (null == dbvalue || DBNull.Value == dbvalue) ? null : dbvalue; - if (null != converter) - { - value = converter(this, value); - } - if (null == value && false == IsNullable(ClrType)) - Setter(instance, TypeExtensions.GetDefault(ClrType)); - else - Setter(instance, value); - } - - } -} diff --git a/ZeroLevel.SqlServer/DbMapper.cs b/ZeroLevel.SqlServer/DbMapper.cs deleted file mode 100644 index 238b9ac..0000000 --- a/ZeroLevel.SqlServer/DbMapper.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Linq; -using System.Reflection; - -namespace ZeroLevel.SqlServer -{ - public class DbMapper: IDbMapper - { - protected readonly Dictionary _fields = new Dictionary(); - private string _identityFieldName; - private readonly Type _entityType; - /// - /// В случае задания в true, все поля класса считаются данными модели, в т.ч. не отвеченные аттрибутом DbMember - /// - private readonly bool _analizeAsPoco; - protected Func typeConverter; - - public void SetTypeConverter(Func converter) - { - typeConverter = converter; - } - - public IDbField IdentityField - { - get - { - if (false == string.IsNullOrWhiteSpace(_identityFieldName)) - { - return _fields[_identityFieldName]; - } - return null; - } - } - - public Type EntityType - { - get - { - return _entityType; - } - } - - public IDbField this[string name] - { - get - { - return _fields[name]; - } - } - - public object Id(object entity) - { - return IdentityField?.Getter(entity); - } - - internal DbMapper(Type entityType, bool as_poco) - { - _analizeAsPoco = as_poco; - _entityType = entityType; - BuildMapping(); - } - - private void BuildMapping() - { - _entityType.GetMembers( - BindingFlags.Public | - BindingFlags.FlattenHierarchy | - BindingFlags.GetField | - BindingFlags.GetProperty | - BindingFlags.Instance). - Do(members => - { - IEnumerable memberList; - if (false == _analizeAsPoco) - { - memberList = members.Where(m => null != Attribute.GetCustomAttribute(m, typeof(DbMemberAttribute))); - } - else - { - memberList = members; - } - foreach (var member in memberList) - { - if (member.MemberType != MemberTypes.Field && member.MemberType != MemberTypes.Property) - continue; - var field = DbField.FromMember(member); - if (field.IsIdentity) - { - _identityFieldName = member.Name; - } - _fields.Add(field.Name, field); - } - if (true == string.IsNullOrWhiteSpace(_identityFieldName)) - { - _identityFieldName = _fields.Keys.FirstOrDefault(f => f.Equals("id", StringComparison.OrdinalIgnoreCase)); - if (true == string.IsNullOrWhiteSpace(_identityFieldName)) - { - _identityFieldName = _fields.Keys.FirstOrDefault(f => - f.IndexOf("id", StringComparison.OrdinalIgnoreCase) >= 0 && - f.IndexOf(_entityType.Name, StringComparison.OrdinalIgnoreCase) >= 0); - } - } - if (false == string.IsNullOrWhiteSpace(_identityFieldName)) - { - _fields[_identityFieldName].IsIdentity = true; - _fields[_identityFieldName].AllowNull = false; - } - }); - } - - public void TraversalFields(Action callback) - { - foreach (var f in _fields) callback(f.Value); - } - - public void TraversalFields(Func callback) - { - foreach (var f in _fields) if (false == callback(f.Value)) return; - } - - public bool Exists(string name) - { - return _fields.ContainsKey(name); - } - - #region Serialization - public object Deserialize(DataRow row) - { - if (null == row) throw new ArgumentNullException(nameof(row)); - var result = Activator.CreateInstance(_entityType); - foreach (var field in _fields) - { - var value = (null == row[field.Key] || DBNull.Value == row[field.Key]) ? null : row[field.Key]; - if (null != typeConverter) - { - field.Value.Setter(result, typeConverter(field.Value, value)); - } - else - { - field.Value.Setter(result, value); - } - } - return result; - } - - public object Deserialize(DbDataReader reader) - { - if (null == reader) throw new ArgumentNullException(nameof(reader)); - var result = Activator.CreateInstance(_entityType); - foreach (var field in _fields) - { - var value = (null == reader[field.Key] || DBNull.Value == reader[field.Key]) ? null : reader[field.Key]; - if (null != typeConverter) - { - field.Value.Setter(result, typeConverter(field.Value, value)); - } - else - { - field.Value.Setter(result, value); - } - } - return result; - } - #endregion - } -} diff --git a/ZeroLevel.SqlServer/DbMapperFactory.cs b/ZeroLevel.SqlServer/DbMapperFactory.cs deleted file mode 100644 index 5e103af..0000000 --- a/ZeroLevel.SqlServer/DbMapperFactory.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace ZeroLevel.SqlServer -{ - public static class DbMapperFactory - { - private static readonly Dictionary _mapperPool = new Dictionary(); - private static readonly object _poolLocker = new object(); - /// - /// Создание маппера - /// - /// Тип представляющий модель данных - /// В случае задания в true, все поля класса считаются данными модели, в т.ч. не отвеченные аттрибутом DbMember - /// Маппер - public static IDbMapper Create(Type entityType, bool asPoco = false) - { - if (null == entityType) - throw new ArgumentNullException(nameof(entityType)); - lock (_poolLocker) - { - if (false == _mapperPool.ContainsKey(entityType)) - { - var gt = typeof(IDbMapper<>); - var rt = gt.MakeGenericType(new Type[] { entityType }); - - _mapperPool.Add(entityType, new DbMapper(rt, asPoco)); - } - } - return _mapperPool[entityType]; - } - /// - /// Создание маппера - /// - /// В случае задания в true, все поля класса считаются данными модели, в т.ч. не отвеченные аттрибутом DbMember - /// Маппер - public static IDbMapper Create(bool asPoco = false) - { - var entityType = typeof(T); - lock (_poolLocker) - { - if (false == _mapperPool.ContainsKey(entityType)) - { - _mapperPool.Add(entityType, new DbMapper(asPoco)); - } - } - return (IDbMapper)_mapperPool[entityType]; - } - } -} diff --git a/ZeroLevel.SqlServer/DbTypeMapper.cs b/ZeroLevel.SqlServer/DbTypeMapper.cs deleted file mode 100644 index e6787aa..0000000 --- a/ZeroLevel.SqlServer/DbTypeMapper.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; - -namespace ZeroLevel.SqlServer -{ - public static class DbTypeMapper - { - static Dictionary typeMap; - - static DbTypeMapper() - { - typeMap = new Dictionary - { - [typeof(byte)] = DbType.Byte, - [typeof(sbyte)] = DbType.SByte, - [typeof(short)] = DbType.Int16, - [typeof(ushort)] = DbType.UInt16, - [typeof(int)] = DbType.Int32, - [typeof(uint)] = DbType.UInt32, - [typeof(long)] = DbType.Int64, - [typeof(ulong)] = DbType.UInt64, - [typeof(float)] = DbType.Single, - [typeof(double)] = DbType.Double, - [typeof(decimal)] = DbType.Decimal, - [typeof(bool)] = DbType.Boolean, - [typeof(string)] = DbType.String, - [typeof(char)] = DbType.StringFixedLength, - [typeof(Guid)] = DbType.Guid, - [typeof(DateTime)] = DbType.DateTime, - [typeof(DateTimeOffset)] = DbType.DateTimeOffset, - [typeof(TimeSpan)] = DbType.Time, - [typeof(byte[])] = DbType.Binary, - [typeof(byte?)] = DbType.Byte, - [typeof(sbyte?)] = DbType.SByte, - [typeof(short?)] = DbType.Int16, - [typeof(ushort?)] = DbType.UInt16, - [typeof(int?)] = DbType.Int32, - [typeof(uint?)] = DbType.UInt32, - [typeof(long?)] = DbType.Int64, - [typeof(ulong?)] = DbType.UInt64, - [typeof(float?)] = DbType.Single, - [typeof(double?)] = DbType.Double, - [typeof(decimal?)] = DbType.Decimal, - [typeof(bool?)] = DbType.Boolean, - [typeof(char?)] = DbType.StringFixedLength, - [typeof(Guid?)] = DbType.Guid, - [typeof(DateTime?)] = DbType.DateTime, - [typeof(DateTimeOffset?)] = DbType.DateTimeOffset, - [typeof(TimeSpan?)] = DbType.Time, - [typeof(object)] = DbType.Object - }; - } - - /// - /// Для value типов помеченных как Nullable вытаскивает оригинальный value тип - /// Не value и не nullable типы не преобразуются - /// - private static Type GetNonNullableType(Type t) - { - if (t.IsValueType) - { - // Detect Nullable - if (Nullable.GetUnderlyingType(t) != null) - { - return t.GenericTypeArguments.Length > 0 ? t.GenericTypeArguments[0] : t; - } - } - return t; - } - - public static DbType ToDbType(this Type type) - { - DbType dbType; - var theType = GetNonNullableType(type); - if (theType.IsEnum && !typeMap.ContainsKey(type)) - { - theType = Enum.GetUnderlyingType(theType); - } - if (typeMap.TryGetValue(theType, out dbType)) - { - return dbType; - } - return DbType.Object; - } - - public static SqlDbType ToSqlDbType(this Type testType) - { - var theType = GetNonNullableType(testType); - if (theType.IsEnum) - { - return Enum.GetUnderlyingType(theType).ToSqlDbType(); - } - if (theType == typeof(Byte[]) || theType == typeof(byte[])) return SqlDbType.Image; - if (theType == typeof(UInt16) || theType == typeof(ushort)) return SqlDbType.Int; - if (theType == typeof(UInt32) || theType == typeof(uint)) return SqlDbType.BigInt; - if (theType == typeof(UInt64) || theType == typeof(ulong)) return SqlDbType.Decimal; - if (theType == typeof(TimeSpan)) return SqlDbType.Time; - return new SqlParameter() { DbType = (DbType)Enum.Parse(typeof(DbType), theType.Name) }.SqlDbType; - } - - public static Type ToClrType(string sqlType) - { - switch (sqlType.Trim().ToLowerInvariant()) - { - case "bigint": - return typeof(long); - - case "binary": - case "image": - case "timestamp": - case "varbinary": - return typeof(byte[]); - - case "bit": - return typeof(bool); - - case "char": - case "nchar": - case "ntext": - case "nvarchar": - case "text": - case "varchar": - case "xml": - return typeof(string); - - case "datetime": - case "smalldatetime": - case "date": - case "datetime2": - return typeof(DateTime); - - case "time": - return typeof(TimeSpan); - - case "decimal": - case "money": - case "smallmoney": - return typeof(decimal); - - case "float": - return typeof(double); - - case "int": - return typeof(int); - - case "real": - return typeof(float); - - case "uniqueidentifier": - return typeof(Guid); - - case "smallint": - return typeof(short); - - case "tinyint": - return typeof(byte); - - case "variant": - case "udt": - return typeof(object); - - case "structured": - return typeof(DataTable); - - case "datetimeoffset": - return typeof(DateTimeOffset); - - default: - throw new ArgumentOutOfRangeException(sqlType); - } - } - } -} diff --git a/ZeroLevel.SqlServer/GenericDbMapper.cs b/ZeroLevel.SqlServer/GenericDbMapper.cs deleted file mode 100644 index 431f9b3..0000000 --- a/ZeroLevel.SqlServer/GenericDbMapper.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Data; -using System.Data.Common; - -namespace ZeroLevel.SqlServer -{ - public class DbMapper : DbMapper, IDbMapper - { - public DbMapper(bool as_poco) : base(typeof(T), as_poco) - { - } - - public new T Deserialize(DataRow row) - { - if (null == row) throw new ArgumentNullException(nameof(row)); - var result = Activator.CreateInstance(); - foreach (var field in _fields) - { - field.Value.SetValue(result, row[field.Key], typeConverter); - } - return result; - } - - public new T Deserialize(DbDataReader reader) - { - if (null == reader) throw new ArgumentNullException(nameof(reader)); - var result = Activator.CreateInstance(); - foreach (var field in _fields) - { - field.Value.SetValue(result, reader[field.Key], typeConverter); - } - return result; - } - } -} diff --git a/ZeroLevel.SqlServer/GenericSqlDbMapper.cs b/ZeroLevel.SqlServer/GenericSqlDbMapper.cs deleted file mode 100644 index a2c4be8..0000000 --- a/ZeroLevel.SqlServer/GenericSqlDbMapper.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Data; -using System.Data.Common; - -namespace ZeroLevel.SqlServer -{ - public class SqlDbMapper : BaseSqlDbMapper - { - protected readonly IDbMapper _mapper; - - protected override IDbMapper Mapper - { - get - { - return _mapper; - } - } - - public IDbField IdentityField - { - get - { - return _mapper.IdentityField; - } - } - - public SqlDbMapper(bool entity_is_poco) : base(typeof(T).Name) - { - _mapper = DbMapperFactory.Create(entity_is_poco); - } - - public T Deserialize(DataRow row) - { - return _mapper.Deserialize(row); - } - - public T Deserialize(DbDataReader reader) - { - return _mapper.Deserialize(reader); - } - - public void TraversalFields(Action callback) - { - _mapper.TraversalFields(callback); - } - } -} diff --git a/ZeroLevel.SqlServer/ISqlServerSpecification.cs b/ZeroLevel.SqlServer/ISqlServerSpecification.cs deleted file mode 100644 index f09a5e5..0000000 --- a/ZeroLevel.SqlServer/ISqlServerSpecification.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Data.SqlClient; - -namespace ZeroLevel.SqlServer -{ - public interface ISqlServerSpecification - { - string Query { get; } - SqlParameter[] Parameters { get; } - } -} diff --git a/ZeroLevel.SqlServer/Properties/AssemblyInfo.cs b/ZeroLevel.SqlServer/Properties/AssemblyInfo.cs deleted file mode 100644 index de34fc6..0000000 --- a/ZeroLevel.SqlServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ZeroLevel.SqlServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ZeroLevel.SqlServer")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a8ad956f-1559-45ec-a7db-42290494e2c5")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ZeroLevel.SqlServer/SqlDbConnectionFactory.cs b/ZeroLevel.SqlServer/SqlDbConnectionFactory.cs deleted file mode 100644 index 667956d..0000000 --- a/ZeroLevel.SqlServer/SqlDbConnectionFactory.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.Globalization; -using System.Security.Permissions; - -namespace ZeroLevel.SqlServer -{ - public sealed class SqlDbConnectionFactory - { - public string ConnectionString - { - get { return dbConnectionString.ConnectionString; } - } - - public string Server - { - get { return dbConnectionString.DataSource; } - } - - public string Base - { - get { return dbConnectionString.InitialCatalog; } - } - - #region Поля - private SqlConnectionStringBuilder dbConnectionString; - /// - /// Текущая строка подключения - /// - private readonly string _currentConnectionString = String.Empty; - #endregion - - public SqlDbConnectionFactory(SqlConnectionStringBuilder builder) - { - _currentConnectionString = builder.ConnectionString; - Initialize(); - } - - public SqlDbConnectionFactory(string connectionString) - { - _currentConnectionString = connectionString; - Initialize(); - } - - public SqlDbConnectionFactory(string server, string database, string login, string password) - { - _currentConnectionString = BuildConnectionString(server, database, login, password); - Initialize(); - } - - private void Initialize() - { - try - { - var perm = new SqlClientPermission(PermissionState.Unrestricted); - perm.Demand(); - perm = null; - } - catch - { - throw new ApplicationException("No permission for access to SqlClient"); - } - dbConnectionString = new SqlConnectionStringBuilder(_currentConnectionString); - dbConnectionString.Pooling = true; - dbConnectionString.MaxPoolSize = 50; - } - - public SqlConnection CreateConnection() - { - var connection = new SqlConnection(ConnectionString); - connection.Open(); - return connection; - } - - #region Helpers - - #region Строки подключения - /// - /// Стандартное подключение - /// - private const string StandartConnectionString = "Server={0};Database={1};User ID={2};Password=\"{3}\";"; - /// - /// Доверенное подключение - /// - private const string TrustedConnectionString = "Data Source={0};Initial Catalog={1};Integrated Security=SSPI;"; - #endregion - - internal static string BuildConnectionString(string server, string dataBase, string user, string pwd) - { - if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(pwd)) - { - return String.Format(CultureInfo.CurrentCulture, TrustedConnectionString, server, dataBase); - } - else - { - return String.Format(CultureInfo.CurrentCulture, StandartConnectionString, server, dataBase, user, pwd); - } - } - #endregion - - public override int GetHashCode() - { - return this.ConnectionString.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlDbInfo.cs b/ZeroLevel.SqlServer/SqlDbInfo.cs deleted file mode 100644 index 3354c86..0000000 --- a/ZeroLevel.SqlServer/SqlDbInfo.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Globalization; - -namespace ZeroLevel.SqlServer -{ - public sealed class SqlDbInfo - { - #region Ctor - public SqlDbInfo(SqlDbProvider provider) - { - _provider = provider; - } - #endregion - - private static string FixTableName(string tableName) - { - return tableName.Trim().ToLower(); - } - - public void CollectDatabaseInfo(bool tables, bool views, bool storedProcedures) - { - if (tables) - CollectTableInformation(); - } - - public SqlDbTableInfo this[string tableName] - { - get - { - tableName = FixTableName(tableName); - if (_tables.ContainsKey(tableName)) - { - return _tables[tableName]; - } - throw new KeyNotFoundException("Таблица " + tableName + " отсутствует в базе " + _provider.Server + "\\" + _provider.Base); - } - } - - #region Private Fields - private readonly SqlDbProvider _provider; - private readonly Dictionary _tables = new Dictionary(); - private readonly List _foreignKeys = new List(); - private readonly List _primaryKeys = new List(); - private readonly List _storedProcedures = new List(); - private readonly List _views = new List(); - #endregion - - #region Public database info - public IEnumerable Tables - { - get - { - return _tables.Keys; - } - } - - public IEnumerable TablesInfo - { - get - { - return _tables.Values; - } - } - - public IEnumerable PrimaryKeys - { - get - { - return _primaryKeys; - } - } - - public IEnumerable ForeignKeys - { - get - { - return _foreignKeys; - } - } - - public IEnumerable StoredProcedures - { - get - { - return _storedProcedures; - } - } - - public IEnumerable Views - { - get - { - return _views; - } - } - #endregion - - #region Public methods - public bool ContainTable(string tableName) - { - tableName = FixTableName(tableName); - return _tables.ContainsKey(tableName); - } - - public bool ContainPrimaryKey(SqlDbPrimaryKeyInfo pk) - { - return _primaryKeys.Contains(pk); - } - - public bool ContainForeignKey(SqlDbForeignKeyInfo fk) - { - return _foreignKeys.Contains(fk); - } - - public SqlDbTableInfo TableInfo(string tableName) - { - tableName = FixTableName(tableName); - if (ContainTable(tableName)) - { - return _tables[tableName]; - } - return null; - } - #endregion - - #region Helpers - /// - /// Сбор информации о таблицах, перчиных и внешних ключах - /// - private void CollectTableInformation() - { - // Таблицы - foreach (string table in GetTables()) - { - SqlDbTableInfo info = GetTableInfo(table); - if (info != null) - { - string tableName = FixTableName(info.Name); - _tables.Add(tableName, info); - if (info.PrimaryKey != null) - { - _primaryKeys.Add(new SqlDbPrimaryKeyInfo { PrimaryKeyTable = tableName, PrimaryKeyColumn = info.PrimaryKey.Name }); - } - } - } - // Внешние ключи - DataSet fkSet = _provider.ExecuteQuerySqlDataSet(SqlDbForeignKeyInfo.ForeignKeySelectQuery); - if (fkSet != null && fkSet.Tables.Count > 0) - { - foreach (DataRow row in fkSet.Tables[0].Rows) - { - _foreignKeys.Add(new SqlDbForeignKeyInfo - { - ForeignKeyName = Convert.ToString(row["Constraint_Name"], CultureInfo.CurrentCulture), - ForeignKeyTable = FixTableName(Convert.ToString(row["K_Table"], CultureInfo.CurrentCulture)), - ForeignKeyColumn = Convert.ToString(row["FK_Column"], CultureInfo.CurrentCulture), - PrimaryKeyTable = FixTableName(Convert.ToString(row["PK_Table"], CultureInfo.CurrentCulture)), - PrimaryKeyColumn = Convert.ToString(row["PK_Column"], CultureInfo.CurrentCulture) - }); - } - } - } - #region Private - /// - /// Получение списка таблиц из базы данных - /// - private List GetTables() - { - var tables = new List(); - using (DataSet ds = _provider.ExecuteQuerySqlDataSet("exec sp_tables")) - { - if (ds != null && ds.Tables.Count > 0) - { - foreach (DataRow row in ds.Tables[0].Rows) - { - if (String.Equals(row.ItemArray[3].ToString(), "TABLE", StringComparison.OrdinalIgnoreCase) && - (false == String.Equals(row.ItemArray[1].ToString(), "sys", StringComparison.OrdinalIgnoreCase))) - tables.Add(FixTableName(row.ItemArray[2].ToString())); - } - } - } - return tables; - } - /// - /// Получение информации о таблице по ее имени - /// - public SqlDbTableInfo GetTableInfo(string table) - { - if (String.IsNullOrEmpty(table)) - { - throw new ArgumentNullException("table"); - } - var info = new SqlDbTableInfo(FixTableName(table)); - info.FillTableInfo(_provider); - return info; - } - #endregion - - #endregion - } -} diff --git a/ZeroLevel.SqlServer/SqlDbMapper.cs b/ZeroLevel.SqlServer/SqlDbMapper.cs deleted file mode 100644 index 477c9cb..0000000 --- a/ZeroLevel.SqlServer/SqlDbMapper.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Data; - -namespace ZeroLevel.SqlServer -{ - public class SqlDbMapper : BaseSqlDbMapper - { - protected readonly IDbMapper _mapper; - - protected override IDbMapper Mapper - { - get - { - return _mapper; - } - } - - public SqlDbMapper(Type entityType, bool as_poco = false) : base(entityType.Name) - { - _mapper = DbMapperFactory.Create(entityType, as_poco); - } - - public object Deserialize(DataRow row) - { - return _mapper.Deserialize(row); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlDbProvider.cs b/ZeroLevel.SqlServer/SqlDbProvider.cs deleted file mode 100644 index a7924ba..0000000 --- a/ZeroLevel.SqlServer/SqlDbProvider.cs +++ /dev/null @@ -1,408 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Data.SqlClient; -using System.Linq; - -namespace ZeroLevel.SqlServer -{ - public class SqlDbProvider : - IDbProvider - { - #region Fields - private readonly SqlDbConnectionFactory _factory; - private const int Timeout = 60000; - - public string ConnectionString - { - get { return _factory.ConnectionString; } - } - - public string Server - { - get { return _factory.Server; } - } - - public string Base - { - get { return _factory.Base; } - } - #endregion - - #region .Ctor - /// - /// Конструктор. - /// - public SqlDbProvider(SqlDbConnectionFactory factory) - { - _factory = factory; - } - #endregion - - #region ExecuteNonResult - public void ExecuteNonResult(IEnumerable commands) - { - using (DbConnection connection = _factory.CreateConnection()) - { - foreach (var zcmd in commands) - { - using (var cmd = CreateCommand(connection, zcmd.Query, zcmd.Parameters, Timeout)) - { - cmd.ExecuteNonQuery(); - } - } - } - } - - public int ExecuteNonResult(string query) - { - return ExecuteNonResult(query, null); - } - - public int ExecuteNonResult(string query, DbParameter[] par) - { - using (DbConnection connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, par, Timeout)) - { - return cmd.ExecuteNonQuery(); - } - } - } - - public T Insert(string insert_query, SqlParameter[] par) - { - DbConnection connection = _factory.CreateConnection(); - try - { - using (var cmd = CreateCommand(connection, insert_query, par, Timeout)) - { - var result = cmd.ExecuteScalar(); - return (T)result; - } - } - finally - { - connection.Dispose(); - } - } - #endregion - - #region ExecuteQueryDataTable - public DataTable ExecuteQueryDataTable(string query) - { - var ds = ExecuteQuerySqlDataSet(query); - if (ds != null && ds.Tables.Count > 0) - { - return ds.Tables[0]; - } - return null; - } - - public DataTable ExecuteQueryDataTable(string query, DbParameter[] par) - { - var ds = ExecuteQuerySqlDataSet(query, par); - if (ds != null && ds.Tables.Count > 0) - { - return ds.Tables[0]; - } - return null; - } - #endregion - - #region ExecuteQuerySqlDataSet - public DataSet ExecuteQuerySqlDataSet(string query) - { - var ds = new DataSet("DataSet"); - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, null, Timeout)) - { - using (var da = new SqlDataAdapter(cmd)) - { - da.Fill(ds); - } - } - } - return ds; - } - - public DataSet ExecuteQuerySqlDataSet(string query, DbParameter[] par) - { - var ds = new DataSet("DataSet"); - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, par, Timeout)) - { - using (var da = new SqlDataAdapter(cmd)) - { - da.Fill(ds); - } - } - } - return ds; - } - #endregion - - #region ExecuteScalar - public object ExecuteScalar(string query) - { - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, null, Timeout)) - { - return cmd.ExecuteScalar(); - } - } - } - - public object ExecuteScalar(string query, DbParameter[] par) - { - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, par, Timeout)) - { - return cmd.ExecuteScalar(); - } - } - } - #endregion - - #region ExecuteStoredProcedure - public int ExecProcedure(string name) - { - using (var connection = _factory.CreateConnection()) - { - using (var command = new SqlCommand(name, connection) - { - CommandType = CommandType.StoredProcedure - }) - { - command.CommandTimeout = 300000; - return command.ExecuteNonQuery(); - } - } - } - #endregion - - #region LazySelect - public void LazySelect(string query, DbParameter[] par, Func readHandler, int timeout = Timeout) - { - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, par, Timeout)) - { - using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) - { - try - { - while (reader.Read()) - { - if (false == readHandler(reader)) - break; - } - } - catch (Exception ex) - { - Log.Error(ex, "Error executing query {0}.", cmd.CommandText); - } - finally - { - // Always call Close when done reading. - reader.Close(); - } - } - } - } - } - - public void LazySelectWithParameters(string query, IEnumerable> par, Func readHandler, int timeout = Timeout) - { - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, query, null, Timeout)) - { - if (par != null && par.Any()) - { - foreach (var p in par) - { - cmd.Parameters.AddWithValue(p.Key, p.Value); - } - } - using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) - { - try - { - while (reader.Read()) - { - if (false == readHandler(reader)) - break; - } - } - catch (Exception ex) - { - Log.Error(ex, "Error executing query {0}.", cmd.CommandText); - } - finally - { - // Always call Close when done reading. - reader.Close(); - } - } - } - } - } - #endregion - - #region ExistsTable - private const string QueryExistsTable = @"IF OBJECT_ID (N'[{0}]', N'U') IS NOT NULL SELECT 1 AS res ELSE SELECT 0 AS res"; - public bool ExistsTable(string tableName) - { - return Convert.ToInt32(ExecuteScalar(String.Format(QueryExistsTable, tableName))) == 1; - } - #endregion - - #region Commands - private static SqlParameter[] ProcessParameters(DbParameter[] par) - { - if (par != null) - { - var result = new SqlParameter[par.Length]; - for (int i = 0; i < par.Length; i++) - { - if (par[i] is SqlParameter) - { - result[i] = (SqlParameter)par[i]; - } - else - { - result[i] = new SqlParameter(par[i].ParameterName, - par[i].Value ?? DBNull.Value); - result[i].Size = par[i].Size; - } - } - return result; - } - return new SqlParameter[0]; - } - - private static SqlCommand CreateCommand(DbConnection connection, string query, DbParameter[] parameters, int timeout) - { - var command = connection.CreateCommand(); - command.CommandText = query; - command.CommandType = CommandType.Text; - if (timeout > 0) - command.CommandTimeout = timeout; - if (parameters != null && parameters.Length > 0) - command.Parameters.AddRange(ProcessParameters(parameters)); - return (SqlCommand)command; - - } - #endregion - - #region SQL Server execute plan reset - private const string CLEAN_PLAN_CACHEE_QUERY = "DBCC FREEPROCCACHE WITH NO_INFOMSGS;"; - /// - /// Выполняет удаление всех элементов из кэша планов. - /// Применимо для ускорения работы SQL Server, при очистке кэша создаются новые планы - /// исполнения для новых значений запросов. - /// - public void CleanPlanCachee() - { - using (var connection = _factory.CreateConnection()) - { - using (var cmd = CreateCommand(connection, CLEAN_PLAN_CACHEE_QUERY, - null, Timeout)) - { - cmd.ExecuteNonQuery(); - } - } - } - #endregion - - #region Static methods - /// - /// Создает базу данных - /// - /// Сервер - /// Название базы данных - public static void CreateDatabase(string server, string database, string login, string password) - { - if (string.IsNullOrEmpty(server)) - { - throw new ArgumentException("Не указано имя сервера"); - } - if (string.IsNullOrEmpty(database)) - { - throw new ArgumentException("Не указано имя базы данных"); - } - using (var connection = new SqlConnection(SqlDbConnectionFactory.BuildConnectionString(server, "master", login, password))) - { - connection.Open(); - using (var command = connection.CreateCommand()) - { - command.CommandText = String.Format("CREATE DATABASE {0}", database); - command.ExecuteNonQuery(); - } - } - } - /// - /// Выполняет проверку существования базы данных с указанным именем - /// - public static bool CheckDatabaseExists(string serverName, string databaseName) - { - string sqlExistsDBQuery; - bool result = false; - try - { - using (var tmpConn = new SqlConnection(String.Format("server={0};Trusted_Connection=yes", serverName))) - { - tmpConn.Open(); - sqlExistsDBQuery = string.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", databaseName); - using (SqlCommand sqlCmd = new SqlCommand(sqlExistsDBQuery, tmpConn)) - { - object resultObj = sqlCmd.ExecuteScalar(); - int databaseID = 0; - if (resultObj != null) - { - int.TryParse(resultObj.ToString(), out databaseID); - } - result = (databaseID > 0); - } - } - } - catch (Exception ex) - { - Log.Error(ex, "Сбой при попытке подключения к серверу {0} и проверке наличия базы данных {1}", - serverName, databaseName); - result = false; - } - return result; - } - /// - /// Удаляет базу данных - /// - public static void DropDatabase(string server, string database, string login, string password) - { - if (string.IsNullOrEmpty(server)) - { - throw new ArgumentException("Не указано имя сервера"); - } - if (string.IsNullOrEmpty(database)) - { - throw new ArgumentException("Не указано имя базы данных"); - } - using (var connection = new SqlConnection(SqlDbConnectionFactory.BuildConnectionString(server, "master", login, password))) - { - connection.Open(); - using (var command = connection.CreateCommand()) - { - command.CommandText = String.Format("ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;\r\nDROP DATABASE [{1}]", database, database); - command.ExecuteNonQuery(); - } - } - } - #endregion - } -} diff --git a/ZeroLevel.SqlServer/SqlDbRepository.cs b/ZeroLevel.SqlServer/SqlDbRepository.cs deleted file mode 100644 index 567049c..0000000 --- a/ZeroLevel.SqlServer/SqlDbRepository.cs +++ /dev/null @@ -1,510 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading; -using ZeroLevel.Specification; - -namespace ZeroLevel.SqlServer -{ - public class SqlDbRepository - { - #region Fields - private readonly SqlDbMapper _mapper; - private readonly SqlDbProvider _dbProvider; - #endregion - - #region Ctors - public SqlDbRepository(SqlDbConnectionFactory connectionFactory, bool entity_is_poco = false) - { - _mapper = new SqlDbMapper(entity_is_poco); - _dbProvider = new SqlDbProvider(connectionFactory); - if (false == SqlDbProvider.CheckDatabaseExists(connectionFactory.Server, connectionFactory.Base)) - { - SqlDbProvider.CreateDatabase(connectionFactory.Server, connectionFactory.Base, null, null); - Thread.Sleep(5000); - } - VerifyDb(); - Prebuilt(); - } - - public SqlDbRepository(string connectionString) - : this(new SqlDbConnectionFactory(connectionString)) - { - } - - public SqlDbRepository(string server, string database) - : this(new SqlDbConnectionFactory(server, database, null, null)) - { - } - #endregion - - #region Simple queries - public IEnumerable Get() - { - using (var table = _dbProvider.ExecuteQueryDataTable(_getAllQuery)) - { - return ConvertToEntitySet(table); - } - } - - public T GetById(TId id) - { - if (null == id) - throw new ArgumentNullException(nameof(id)); - using (var table = _dbProvider.ExecuteQueryDataTable(_getByIdQuery, new SqlParameter[] - { - new SqlParameter(_mapper.IdentityName, id) - })) - { - if (null != table && table.Rows.Count > 0) - { - return _mapper.Deserialize(table.Rows[0]); - } - } - throw new KeyNotFoundException(string.Format("Not found db record by identity field '{0}' with value {1}", - _mapper.IdentityName, id)); - } - - public IEnumerable Get(string fieldName, TField value) - { - if (null == value) - throw new ArgumentNullException(nameof(value)); - if (string.IsNullOrWhiteSpace(fieldName)) - throw new ArgumentNullException(nameof(fieldName)); - var query = string.Format(_getByFieldNameQuery, fieldName, fieldName); - using (var table = _dbProvider.ExecuteQueryDataTable(query, new SqlParameter[] - { - new SqlParameter(fieldName, value) - })) - { - return ConvertToEntitySet(table); - } - } - - public long Count() - { - object count = _dbProvider.ExecuteScalar(_countQuery); - if (null == count) - throw new InvalidOperationException(String.Format("Fault execute count query {0}", _countQuery)); - return Convert.ToInt64(count); - } - - public long Count(string fieldName, TField value) - { - if (null == value) - throw new ArgumentNullException(nameof(value)); - if (string.IsNullOrWhiteSpace(fieldName)) - throw new ArgumentNullException(nameof(fieldName)); - var query = string.Format(_countByFieldNameQuery, fieldName, fieldName); - object count = _dbProvider.ExecuteScalar(query, new SqlParameter[] - { - new SqlParameter(fieldName, value) - }); - if (null == count) throw new InvalidOperationException(String.Format("Fault execute count query {0}", _countQuery)); - return Convert.ToInt64(count); - } - - public bool Contains(T entity) - { - if (null == entity) - { - throw new ArgumentNullException(nameof(entity)); - } - var count = _dbProvider.ExecuteScalar(_containsQuery, _mapper.CreateSqlDbParameters(entity)); - if (null == count) throw new InvalidOperationException(String.Format("Fault execute query {0}", _containsQuery)); - return Convert.ToInt64(count) > 0; - } - - public bool ContainsId(TId id) - { - return Count(_mapper.IdentityName, id) > 0; - } - - public bool Contains(string fieldName, TField value) - { - return Count(fieldName, value) > 0; - } - - public void Update(T entity) - { - if (null == entity) - throw new ArgumentNullException(nameof(entity)); - _dbProvider.ExecuteNonResult(_updateQuery, _mapper.CreateSqlDbParameters(entity)); - } - - public void Insert(T entity) - { - if (null == entity) - throw new ArgumentNullException(nameof(entity)); - _dbProvider.ExecuteNonResult(_insertQuery, _mapper.CreateSqlDbParameters(entity)); - } - - public void Insert(IEnumerable entities) - { - if (null == entities) - throw new ArgumentNullException(nameof(entities)); - var commandList = - entities. - Select(e => new ZSqlCommand { Query = _insertQuery, Parameters = _mapper.CreateSqlDbParameters(e) }); - _dbProvider.ExecuteNonResult(commandList); - } - - public void Update(IEnumerable entities) - { - if (null == entities) - throw new ArgumentNullException(nameof(entities)); - var commandList = - entities. - Select(e => new ZSqlCommand { Query = _updateQuery, Parameters = _mapper.CreateSqlDbParameters(e) }); - _dbProvider.ExecuteNonResult(commandList); - } - - public void Remove(T entity) - { - if (null == entity) - throw new ArgumentNullException(nameof(entity)); - _dbProvider.ExecuteNonResult(_removeByIdQuery, new SqlParameter[] - { - new SqlParameter(_mapper.IdentityName, _mapper.GetIdentity(entity)) - }); - } - - public void RemoveById(TId id) - { - if (null == id) - throw new ArgumentNullException(nameof(id)); - _dbProvider.ExecuteNonResult(_removeByIdQuery, new SqlParameter[] - { - new SqlParameter(_mapper.IdentityName, id) - }); - } - - public void Remove(string fieldName, TField value) - { - if (string.IsNullOrWhiteSpace(fieldName)) - throw new ArgumentNullException(nameof(fieldName)); - if (null == value) - throw new ArgumentNullException(nameof(value)); - var query = string.Format(_removeByFieldQuery, fieldName, fieldName); - _dbProvider.ExecuteNonResult(query, new SqlParameter[] - { - new SqlParameter(fieldName, value) - }); - } - #endregion - - #region Specification queries - public T SingleOrDefault(ISpecification specification) - { - if (null == specification) - throw new ArgumentNullException(nameof(specification)); - ISqlServerSpecification sqlSpecification; - if (true == TryGetWhere(specification, out sqlSpecification)) - { - string query = null; - var where = BuildWherePart(sqlSpecification); - if (false == string.IsNullOrWhiteSpace(where)) - { - query = _getTopOneQuery + " WHERE " + where; - using (var table = _dbProvider.ExecuteQueryDataTable(query, sqlSpecification.Parameters)) - { - if (null != table && table.Rows.Count > 0) - { - return _mapper.Deserialize(table.Rows[0]); - } - return default(T); - } - } - } - // No sql specification - T result = default(T); - _dbProvider.LazySelect(_getAllQuery, null, reader => - { - var entity = _mapper.Deserialize(reader); - if (specification.IsSatisfiedBy(entity)) - { - result = entity; - return false; - } - return true; - }); - return result; - } - - public IEnumerable Get(ISpecification specification) - { - if (null == specification) - throw new ArgumentNullException(nameof(specification)); - ISqlServerSpecification sqlSpecification; - if (true == TryGetWhere(specification, out sqlSpecification)) - { - string query = null; - var where = BuildWherePart(sqlSpecification); - if (false == string.IsNullOrWhiteSpace(where)) - { - query = _getAllQuery + " WHERE " + where; - using (var ds = _dbProvider.ExecuteQuerySqlDataSet(query, sqlSpecification.Parameters)) - { - return ConvertToEntitySet(ds.Tables[0]); - } - } - } - // No sql specification - var result = new List(); - _dbProvider.LazySelect(_getAllQuery, null, reader => - { - var entity = _mapper.Deserialize(reader); - if (specification.IsSatisfiedBy(entity)) - { - result.Add(entity); - } - return true; - }); - return result; - } - - public bool Contains(ISpecification specification) - { - if (null == specification) - throw new ArgumentNullException(nameof(specification)); - ISqlServerSpecification sqlSpecification; - if (true == TryGetWhere(specification, out sqlSpecification)) - { - var where = BuildWherePart(sqlSpecification); - if (false == string.IsNullOrWhiteSpace(where)) - { - string query = String.Format("SELECT COUNT(*) FROM [{0}] WHERE {1}", _mapper.TableName, where); - object count = _dbProvider.ExecuteScalar(query, sqlSpecification.Parameters); - if (null == count) throw new InvalidOperationException(String.Format("Fault execute query {0}", query)); - return Convert.ToInt64(count) > 0; - } - } - bool result = false; - _dbProvider.LazySelect(_getAllQuery, null, reader => - { - var entity = _mapper.Deserialize(reader); - if (specification.IsSatisfiedBy(entity)) - { - result = true; - return false; - } - return true; - }); - return result; - } - - public long Count(ISpecification specification) - { - if (null == specification) - throw new ArgumentNullException(nameof(specification)); - ISqlServerSpecification sqlSpecification; - if (true == TryGetWhere(specification, out sqlSpecification)) - { - var where = BuildWherePart(sqlSpecification); - object count = null; - if (false == string.IsNullOrWhiteSpace(where)) - { - count = _dbProvider.ExecuteScalar(String.Format("{0} WHERE {1}", _countQuery, where), sqlSpecification.Parameters); - } - if (null == count) throw new InvalidOperationException("Fault execute query"); - if (DBNull.Value == count) return 0; - return Convert.ToInt64(count); - } - long result = 0; - _dbProvider.LazySelect(_getAllQuery, null, reader => - { - var entity = _mapper.Deserialize(reader); - if (specification.IsSatisfiedBy(entity)) - { - result++; - } - return true; - }); - return result; - } - - public void Remove(ISpecification specification) - { - if (null == specification) - throw new ArgumentNullException(nameof(specification)); - ISqlServerSpecification sqlSpecification; - if (true == TryGetWhere(specification, out sqlSpecification)) - { - var where = BuildWherePart(sqlSpecification); - if (false == string.IsNullOrWhiteSpace(where)) - { - string query = string.Format("DELETE FROM [{0}] WHERE {1}", _mapper.TableName, where); - _dbProvider.ExecuteNonResult(query, sqlSpecification.Parameters); - return; - } - } - _dbProvider.LazySelect(_getAllQuery, null, reader => - { - var entity = _mapper.Deserialize(reader); - if (specification.IsSatisfiedBy(entity)) - { - Remove(entity); - } - return true; - }); - } - #endregion - - #region Helpers - private void VerifyDb() - { - if (false == _dbProvider.ExistsTable(_mapper.TableName)) - { - _dbProvider.ExecuteNonResult(_mapper.GetCreateQuery()); - } - _mapper.TraversalFields(f => - { - if (f.IsIndexed) - { - var existsQuery = _mapper.GetIndexExistsQuery(f); - if ((int)_dbProvider.ExecuteScalar(existsQuery) == 0) - { - var createQuery = _mapper.GetCreateIndexQuery(f); - _dbProvider.ExecuteNonResult(createQuery); - } - } - }); - } - - private IEnumerable ConvertToEntitySet(DataTable _dt) - { - var result = new List(); - _dt.Do(dt => - { - foreach (DataRow row in dt.Rows) - { - try - { - result.Add(_mapper.Deserialize(row)); - } - catch (Exception ex) - { - throw new InvalidCastException("Repository convert entity from db record to object fault", ex); - } - } - }); - return result; - } - - private bool TryGetWhere(ISpecification originalSpecifiaction, out ISqlServerSpecification sqlSpecification) - { - sqlSpecification = (originalSpecifiaction as ISqlServerSpecification); - return sqlSpecification != null; - } - - private string BuildWherePart(ISqlServerSpecification specification) - { - if (false == string.IsNullOrWhiteSpace(specification.Query)) - return specification.Query; - else if (specification.Parameters != null) - return string.Join(" AND ", specification.Parameters. - Select(p => string.Format("[{0}] = @{1}", p.ParameterName, p.ParameterName))); - return null; - } - #endregion - - #region Prebuild queries - private string _insertQuery; - private string _updateQuery; - - private string _getTopOneQuery; - private string _getAllQuery; - private string _getByIdQuery; - private string _getByFieldNameQuery; - - private string _countQuery; - private string _countByFieldNameQuery; - - private string _containsQuery; - - private string _removeByFieldQuery; - private string _removeByIdQuery; - - private void Prebuilt() - { - _insertQuery = BuildInsertQuery(); - _updateQuery = BuildUpdateQuery(); - - _getAllQuery = string.Format("SELECT * FROM [{0}]", _mapper.TableName); - _getTopOneQuery = string.Format("SELECT TOP (1) * FROM [{0}]", _mapper.TableName); - _getByIdQuery = string.Format("SELECT * FROM [{0}] WHERE {1}=@{2}", - _mapper.TableName, _mapper.IdentityName, _mapper.IdentityName); - _getByFieldNameQuery = _getAllQuery + " WHERE {0}=@{1}"; - _countQuery = string.Format("SELECT COUNT(*) FROM [{0}]", _mapper.TableName); - _countByFieldNameQuery = _countQuery + " WHERE {0}=@{1}"; - _containsQuery = BuildContainsQuery(); - _removeByIdQuery = String.Format("DELETE FROM [{0}] WHERE [{1}] = @{2}", - _mapper.TableName, _mapper.IdentityName, _mapper.IdentityName); - _removeByFieldQuery = String.Format("DELETE FROM [{0}] WHERE ", _mapper.TableName) + " [{0}] = @{1}"; - } - - private string BuildContainsQuery() - { - var query = new StringBuilder(_countQuery); - query.Append(" WHERE "); - _mapper.TraversalFields(f => - { - query.AppendFormat("[{0}] = @{1} AND ", f.Name, f.Name); - }); - if (StringExtensions.EndsWith(query, "AND ")) query.Remove(query.Length - 4, 4); - if (StringExtensions.EndsWith(query, "WHERE ")) query.Remove(query.Length - 6, 6); - return query.ToString(); - } - - private string BuildInsertQuery() - { - var query = new StringBuilder(); - query.AppendFormat("INSERT INTO [{0}](", _mapper.TableName); - var values = new StringBuilder(" VALUES("); - _mapper.TraversalFields(f => - { - if (f.AutoIncrement == false) - { - query.Append("[" + f.Name + "],"); - values.Append("@" + f.Name + ","); - } - }); - query.Remove(query.Length - 1, 1); - query.Append(")"); - query.AppendFormat(" OUTPUT INSERTED.{0} ", _mapper.IdentityName); - values.Remove(values.Length - 1, 1); - values.Append(")"); - query.Append(values); - return query.ToString(); - } - - private string BuildUpdateQuery() - { - var query = new StringBuilder(); - query.AppendFormat("UPDATE[{0}] SET ", _mapper.TableName); - _mapper.TraversalFields(f => - { - if (f.IsIdentity == false && f.AutoIncrement == false) - query.Append("[" + f.Name + "] = @" + f.Name + ","); - }); - query.Remove(query.Length - 1, 1); - query.AppendFormat(" OUTPUT INSERTED.{0} WHERE [{1}] = @{2}", _mapper.IdentityName, _mapper.IdentityName, _mapper.IdentityName); - return query.ToString(); - } - #endregion - - #region IDisposable - public void Dispose() - { - } - #endregion - - public void Execute(string query) - { - _dbProvider.ExecuteNonResult(query); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/ColumnInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/ColumnInfo.cs deleted file mode 100644 index f47bc9f..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/ColumnInfo.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public class ColumnInfo: IEquatable - { - /// - /// Наименование поля - /// - public string Name { get; set; } - /// - /// Тип поля в рамках базы данных - /// - public string DbType; - /// - /// Тип поля в рамках .NET - /// - public Type DotNetType; - /// - /// Указывает что поле является ключом таблицы - /// - public bool IsPrimaryKey; - /// - /// Указывает, разрешены ли значения NULL в поле - /// - public bool AllowNull; - /// - /// Размер в байтах (если применимо) - /// - public long Size; - /// - /// Указывает что поле является автоинкрементируемым - /// - public bool AutoInc; - - public ColumnInfo() { } - - public ColumnInfo(ColumnInfo other) - { - Name = other.Name; - DbType = other.DbType; - DotNetType = other.DotNetType; - IsPrimaryKey = other.IsPrimaryKey; - AllowNull = other.AllowNull; - Size = other.Size; - AutoInc = other.AutoInc; - } - - public bool Equals(ColumnInfo other) - { - bool eq = true; - eq &= AutoInc == other.AutoInc; - eq &= Size == other.Size; - eq &= AllowNull == other.AllowNull; - eq &= IsPrimaryKey == other.IsPrimaryKey; - eq &= String.Compare(DbType, other.DbType, StringComparison.OrdinalIgnoreCase) == 0; - eq &= String.Compare(Name, other.Name, StringComparison.OrdinalIgnoreCase) == 0; - eq &= DotNetType.Equals(other.DotNetType); - return eq; - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/IndexInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/IndexInfo.cs deleted file mode 100644 index b86cb2b..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/IndexInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using ZeroLevel.Services.Collections; - -namespace ZeroLevel.SqlServer -{ - public class IndexInfo : IEquatable - { - public string Name; - public List Columns = new List(); - public bool IsUnique; - public bool IsPrimaryKey; - - public bool Equals(IndexInfo other) - { - bool eq = true; - eq &= String.Compare(Name, other.Name, StringComparison.Ordinal) == 0; - eq &= Columns.NoOrderingEquals(other.Columns); - eq &= IsUnique == other.IsUnique; - eq &= IsPrimaryKey == other.IsPrimaryKey; - return eq; - } - - public override int GetHashCode() - { - return Name.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbForeignKeyInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/SqlDbForeignKeyInfo.cs deleted file mode 100644 index 3f2ae35..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbForeignKeyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public sealed class SqlDbForeignKeyInfo : IEquatable - { - public const string ForeignKeySelectQuery = "SELECT K_Table = FK.TABLE_NAME, FK_Column = CU.COLUMN_NAME, PK_Table = PK.TABLE_NAME, PK_Column = PT.COLUMN_NAME, Constraint_Name = C.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME INNER JOIN ( SELECT i1.TABLE_NAME, i2.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1 INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY' ) PT ON PT.TABLE_NAME = PK.TABLE_NAME"; - - public string ForeignKeyName; - public string ForeignKeyTable; - public string PrimaryKeyTable; - public string ForeignKeyColumn; - public string PrimaryKeyColumn; - - public bool Equals(SqlDbForeignKeyInfo other) - { - return String.Compare(ForeignKeyName, other.ForeignKeyName, StringComparison.OrdinalIgnoreCase) == 0 && - String.Compare(ForeignKeyTable, other.ForeignKeyTable, StringComparison.OrdinalIgnoreCase) == 0 && - String.Compare(PrimaryKeyTable, other.PrimaryKeyTable, StringComparison.OrdinalIgnoreCase) == 0 && - String.Compare(ForeignKeyColumn, other.ForeignKeyColumn, StringComparison.OrdinalIgnoreCase) == 0 && - String.Compare(PrimaryKeyColumn, other.PrimaryKeyColumn, StringComparison.OrdinalIgnoreCase) == 0; - } - - public override int GetHashCode() - { - return ForeignKeyName.GetHashCode() ^ - ForeignKeyTable.GetHashCode() ^ - PrimaryKeyTable.GetHashCode() ^ - ForeignKeyColumn.GetHashCode() ^ - PrimaryKeyColumn.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbObjectInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/SqlDbObjectInfo.cs deleted file mode 100644 index 04f2e4f..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbObjectInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace ZeroLevel.SqlServer -{ - public struct SqlDbObjectInfo - { - public string Name; - public string Header; - public string Text; - - public static bool operator ==(SqlDbObjectInfo first, SqlDbObjectInfo second) - { - return first.Equals(second); - } - - public static bool operator !=(SqlDbObjectInfo first, SqlDbObjectInfo second) - { - return !first.Equals(second); - } - - public bool Equals(SqlDbObjectInfo other) - { - bool eq = true; - eq &= string.Compare(Name, other.Name, System.StringComparison.Ordinal) == 0; - eq &= string.Compare(Header, other.Header, System.StringComparison.Ordinal) == 0; - eq &= string.Compare(Text, other.Text, System.StringComparison.Ordinal) == 0; - return eq; - } - - public override bool Equals(object obj) - { - return Equals((SqlDbObjectInfo)obj); - } - - public override int GetHashCode() - { - return Name.GetHashCode() ^ Header.GetHashCode() ^ Text.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbPrimaryKeyInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/SqlDbPrimaryKeyInfo.cs deleted file mode 100644 index 7d3d294..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbPrimaryKeyInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace ZeroLevel.SqlServer -{ - public sealed class SqlDbPrimaryKeyInfo : IEquatable - { - public string PrimaryKeyTable; - public string PrimaryKeyColumn; - - public bool Equals(SqlDbPrimaryKeyInfo other) - { - return String.Compare(PrimaryKeyTable, other.PrimaryKeyTable, StringComparison.OrdinalIgnoreCase) == 0 && - String.Compare(PrimaryKeyColumn, other.PrimaryKeyColumn, StringComparison.OrdinalIgnoreCase) == 0; - } - - public override int GetHashCode() - { - return PrimaryKeyTable.GetHashCode() ^ PrimaryKeyColumn.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbTableInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/SqlDbTableInfo.cs deleted file mode 100644 index 577b311..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/SqlDbTableInfo.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; - -namespace ZeroLevel.SqlServer -{ - /// - /// Описание таблицы в БД - /// - public sealed class SqlDbTableInfo : TableInfo, IEquatable - { - #region Ctor - /// - /// Конструктор по-умолчанию - /// - /// - public SqlDbTableInfo(string name) : base(name) - { - } - /// - /// Конструктор по-умолчанию - /// - /// - public SqlDbTableInfo(SqlDbTableInfo other) : base(other) - { - } - #endregion - - #region IEquatable - /// - /// Сравнение с другой таблицей - /// - public bool Equals(SqlDbTableInfo other) - { - return base.Equals(other); - } - #endregion - - #region Fill table info - protected override IEnumerable GetIndexes(IDbProvider db) - { - var indexes = new List(); - string select = "exec sp_indexes_rowset [{0}]"; - using (var ds = db.ExecuteQuerySqlDataSet(string.Format(select, _name))) - { - using (var indexInfo = ds.Tables[0]) - { - foreach (DataRow row in indexInfo.Rows) - { - var i = new IndexInfo - { - Name = (string)row["INDEX_NAME"], - IsPrimaryKey = (bool)row["PRIMARY_KEY"], - IsUnique = (bool)row["UNIQUE"] - }; - i.Columns.Add((string)row["COLUMN_NAME"]); - indexes.Add(i); - } - } - } - return indexes; - } - - protected override IEnumerable GetColumns(IDbProvider db) - { - // Для уменьшения количества обращения к базе все данные по таблице в одном запросе - var columns = new List(); - string select = @"exec sp_columns [{0}] -SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_NAME='{0}' -exec sp_pkeys @table_name = [{0}]"; - using (var ds = db.ExecuteQuerySqlDataSet(string.Format(select, _name))) - { - if (ds.Tables.Count != 3) - { - throw new InvalidOperationException("Не удалось получить данные по таблице " + _name); - } - var columnTypes = new Dictionary(); - var columnSize = new Dictionary(); - using (var dataTypeInfo = ds.Tables[1]) - { - foreach (DataRow row in dataTypeInfo.Rows) - { - columnTypes.Add((string)row["COLUMN_NAME"], (string)row["DATA_TYPE"]); - var maximum = row["CHARACTER_MAXIMUM_LENGTH"]; - columnSize.Add((string)row["COLUMN_NAME"], (maximum != DBNull.Value) ? Convert.ToInt64(row["CHARACTER_MAXIMUM_LENGTH"]) : 0); - } - } - using (var tableInfo = ds.Tables[0]) - { - foreach (DataRow row in tableInfo.Rows) - { - var column = new ColumnInfo(); - column.Name = (string)row["COLUMN_NAME"]; - column.Size = columnSize[column.Name]; - column.DbType = columnTypes[column.Name]; - column.AllowNull = (short)row["NULLABLE"] == 1; - column.DotNetType = DbTypeMapper.ToClrType(columnTypes[column.Name]); - column.AutoInc = ((string)row["TYPE_NAME"]).Contains("identity"); - columns.Add(column); - } - } - using (var pkInfo = ds.Tables[2]) - { - if (pkInfo.Rows.Count > 0 && pkInfo.Rows[0].ItemArray.Length > 3) - { - var primaryKeyName = pkInfo.Rows[0][3].ToString(); - var pc = columns.First(c => c.Name.Equals(primaryKeyName, StringComparison.OrdinalIgnoreCase)); - pc.IsPrimaryKey = true; - } - } - } - return columns; - } - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/SqlServerEntities/TableInfo.cs b/ZeroLevel.SqlServer/SqlServerEntities/TableInfo.cs deleted file mode 100644 index 22c1767..0000000 --- a/ZeroLevel.SqlServer/SqlServerEntities/TableInfo.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace ZeroLevel.SqlServer -{ - public abstract class TableInfo : IEquatable - { - #region Private fields - /// - /// Имя таблицы - /// - protected readonly string _name; - /// - /// Поле-идентификатор - /// - private ColumnInfo _primaryKey; - /// - /// Все поля таблицы - /// - private readonly Dictionary _columns = new Dictionary(); - /// - /// Индексы - /// - private readonly List _indexes = new List(); - #endregion - - #region Properties - public ColumnInfo this[string columnName] - { - get - { - if (_columns.ContainsKey(columnName)) - { - return _columns[columnName]; - } - return null; - } - } - /// - /// Первичный ключ - /// - public ColumnInfo PrimaryKey - { - get { return _primaryKey; } - } - /// - /// Имя таблицы - /// - public string Name - { - get - { - return _name; - } - } - /// - /// Индексы - /// - public List Indexes - { - get - { - return _indexes; - } - } - /// - /// Поля таблицы - /// - public IEnumerable Columns - { - get - { - return _columns.Values; - } - } - #endregion - - #region Ctor - /// - /// Конструктор по-умолчанию - /// - /// - public TableInfo(string name) - { - _name = name; - } - - /// - /// Конструктор по-умолчанию - /// - /// - public TableInfo(TableInfo other) - { - _name = other._name; - _columns = new Dictionary(other._columns); - _indexes = new List(other._indexes); - _primaryKey = other._primaryKey; - } - #endregion - - #region IEquatable - public override bool Equals(object obj) - { - return this.Equals(obj as TableInfo); - } - /// - /// Сравнение с другой таблицей - /// - public bool Equals(TableInfo other) - { - if (other == null || _name.Equals(other._name, StringComparison.OrdinalIgnoreCase) == false) - return false; - if (false == Columns.NoOrderingEquals(other.Columns)) - { - return false; - } - return true; - } - #endregion - - #region Abstract - protected abstract IEnumerable GetIndexes(IDbProvider db); - protected abstract IEnumerable GetColumns(IDbProvider db); - #endregion - - #region Fill table info - public void AppendNewColumn(ColumnInfo column) - { - _columns.Add(column.Name, column); - if (column.IsPrimaryKey) - _primaryKey = column; - } - /// - /// Заполнение данных о таблице - /// - /// Подключение к базе данных - public void FillTableInfo(IDbProvider db) - { - foreach (var column in GetColumns(db)) - { - _columns.Add(column.Name, column); - if (column.IsPrimaryKey) - { - _primaryKey = column; - } - } - foreach (var index in GetIndexes(db)) - { - _indexes.Add(index); - } - } - #endregion - - /// - /// Проверка наличия поля - /// - public bool ContainsColumns(ColumnInfo column) - { - return Columns.Any(r => r.Equals(column)); - } - /// - /// Проверка наличия поля - /// - public bool ContainsColumns(string columnName) - { - return Columns.Any(r => r.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase)); - } - - public override int GetHashCode() - { - return _name.GetHashCode(); - } - } -} diff --git a/ZeroLevel.SqlServer/ZeroLevel.SqlServer.csproj b/ZeroLevel.SqlServer/ZeroLevel.SqlServer.csproj deleted file mode 100644 index 4be0b46..0000000 --- a/ZeroLevel.SqlServer/ZeroLevel.SqlServer.csproj +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Debug - AnyCPU - {A8AD956F-1559-45EC-A7DB-42290494E2C5} - Library - Properties - ZeroLevel.SqlServer - ZeroLevel.SqlServer - v4.7.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - prompt - MinimumRecommendedRules.ruleset - - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {06c9e60e-d449-41a7-9bf0-a829aaf5d214} - ZeroLevel - - - - - \ No newline at end of file diff --git a/ZeroLevel.SqlServer/packages.config b/ZeroLevel.SqlServer/packages.config deleted file mode 100644 index 38f5c89..0000000 --- a/ZeroLevel.SqlServer/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/ZeroLevel.UnitTests/ConfigurationTest.cs b/ZeroLevel.UnitTests/ConfigurationTest.cs new file mode 100644 index 0000000..14da601 --- /dev/null +++ b/ZeroLevel.UnitTests/ConfigurationTest.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using Xunit; + +namespace ZeroLevel.UnitTests +{ + public class AppConfig + { + public string Url; + public int BatchSize; + public IEnumerable Sheme; + public int[] Port; + public ServiceConfig Service; + public IEnumerable List; + } + + public class ServiceConfig + { + public string AppName; + public string AppKey; + public string ServiceGroup; + public string ServiceType; + } + + public class ConfigurationTest + { + [Fact] + public void BindConfigurationTest() + { + // Arrange + var set = Configuration.CreateSet(); + set.Default.Append("url", "https://habr.ru"); + set.Default.Append("batchSize", "1000"); + set.Default.Append("sheme", "socks"); + set.Default.Append("sheme", "http"); + set.Default.Append("sheme", "https"); + set.Default.Append("port", "80"); + set.Default.Append("port", "90"); + set.Default.Append("port", "8800"); + set.Default.Append("list", "1-5,7,9"); + var section = set.CreateSection("service"); + section.Append("AppName", "TestApp"); + section.Append("AppKey", "test.app"); + section.Append("ServiceGroup", "System"); + section.Append("ServiceType", "service"); + + // Act + var config = set.Bind(); + + // Assert + Assert.Equal("https://habr.ru", config.Url); + Assert.Equal(1000, config.BatchSize); + Assert.Contains(config.Sheme, t=>t.Equals("socks")); + Assert.Contains(config.Sheme, t => t.Equals("http")); + Assert.Contains(config.Sheme, t => t.Equals("https")); + + Assert.Contains(config.Port, t => t == 80); + Assert.Contains(config.Port, t => t == 90); + Assert.Contains(config.Port, t => t == 8800); + + Assert.Contains(config.List, i => i == 1); + Assert.Contains(config.List, i => i == 2); + Assert.Contains(config.List, i => i == 3); + Assert.Contains(config.List, i => i == 4); + Assert.Contains(config.List, i => i == 5); + Assert.Contains(config.List, i => i == 7); + Assert.Contains(config.List, i => i == 9); + + Assert.DoesNotContain(config.List, i => i == 8); + Assert.DoesNotContain(config.List, i => i == 6); + + Assert.Equal("test.app", config.Service.AppKey); + Assert.Equal("TestApp", config.Service.AppName); + Assert.Equal("System", config.Service.ServiceGroup); + Assert.Equal("service", config.Service.ServiceType); + } + } +} diff --git a/ZeroLevel.UnitTests/DSAUnitTest.cs b/ZeroLevel.UnitTests/DSAUnitTest.cs new file mode 100644 index 0000000..8a09943 --- /dev/null +++ b/ZeroLevel.UnitTests/DSAUnitTest.cs @@ -0,0 +1,78 @@ +using System; +using System.Linq; +using Xunit; +using ZeroLevel.Services.Serialization; +using ZeroLevel.Services.Trees; + +namespace ZeroLevel.UnitTests +{ + public class DSAUnitTest + { + [Fact] + public void DSATest() + { + // Arrange + var words_in = new[] { "физика", "атомного", "ядра", "и", "элементарных", "частиц" }; + var words_out = new[] { "полгода", "после", "переезда" }; + var dsa = new DSA(); + + // Act&Assert + foreach (var w in words_in) + { + Assert.True(dsa.AppendWord(w)); + } + + //Count + Assert.Equal(dsa.Count, words_in.Length); + + // Contains + foreach (var w in words_in) + { + Assert.True(dsa.Contains(w)); + } + foreach (var w in words_out) + { + Assert.False(dsa.Contains(w)); + } + // Iterator + var saved = dsa.Iterator().ToList(); + Assert.Equal(saved.Count, words_in.Length); + foreach (var w in words_in) + { + Assert.True(saved.IndexOf(w) >= 0); + } + foreach (var w in words_out) + { + Assert.True(saved.IndexOf(w) == -1); + } + + // Serialization + var bf = MessageSerializer.Serialize(dsa); + var restored = MessageSerializer.Deserialize(bf); + + //Count + Assert.Equal(restored.Count, words_in.Length); + + // Contains + foreach (var w in words_in) + { + Assert.True(restored.Contains(w)); + } + foreach (var w in words_out) + { + Assert.False(restored.Contains(w)); + } + // Iterator + saved = restored.Iterator().ToList(); + Assert.Equal(saved.Count, words_in.Length); + foreach (var w in words_in) + { + Assert.True(saved.IndexOf(w) >= 0); + } + foreach (var w in words_out) + { + Assert.True(saved.IndexOf(w) == -1); + } + } + } +} diff --git a/DependencyInjectionTests/Program.cs b/ZeroLevel.UnitTests/DependencyInjectionTests.cs similarity index 75% rename from DependencyInjectionTests/Program.cs rename to ZeroLevel.UnitTests/DependencyInjectionTests.cs index 8b741ab..899636c 100644 --- a/DependencyInjectionTests/Program.cs +++ b/ZeroLevel.UnitTests/DependencyInjectionTests.cs @@ -1,9 +1,10 @@ using System; -using ZeroLevel; -using ZeroLevel.Patterns.DependencyInjection; -using ZeroLevel.Services.Reflection; +using System.Collections.Generic; +using System.Text; +using Xunit; +using ZeroLevel.DependencyInjection; -namespace DependencyInjectionTests +namespace ZeroLevel.UnitTests { public interface IDependencyContract { @@ -34,24 +35,26 @@ namespace DependencyInjectionTests public string Run() => $"{_config.First("var")}{_delimeter}{_dependency.Invoke()}"; } - - class Program + public class DependencyInjectionTests { - static void Main(string[] args) + [Fact] + public void ComposeTest() { - - + // Arrange var config = Configuration.Create(); config.Append("var", "bool isWorking"); Injector.Default.Register(); Injector.Default.Register(); Injector.Default.Register(config); Injector.Default.Save("delimeter", " = "); - var instance = new MyImplementation(); + + // Act Injector.Default.Compose(instance); - Console.WriteLine(instance.Run()); - Console.ReadKey(); + + // Assert + var result = instance.Run(); + Assert.Equal("bool isWorking = True", result); Injector.Dispose(); } diff --git a/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj b/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj index 2efb601..827d099 100644 --- a/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj +++ b/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj @@ -1,9 +1,11 @@  - netcoreapp2.2 + netcoreapp3.1 false + + AnyCPU;x64 diff --git a/ZeroLevel.WPF/ZeroLevel.WPF.csproj b/ZeroLevel.WPF/ZeroLevel.WPF.csproj deleted file mode 100644 index 110fc90..0000000 --- a/ZeroLevel.WPF/ZeroLevel.WPF.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - netstandard2.1 - AnyCPU;x64 - - - - - - - - - - ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll - - - ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationFramework.dll - - - ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Xaml.dll - - - - diff --git a/ZeroLevel.sln b/ZeroLevel.sln index 8b3c521..7301095 100644 --- a/ZeroLevel.sln +++ b/ZeroLevel.sln @@ -13,10 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Discovery", "Zero EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileTransferTest", "FileTransferTest", "{FC074553-5D9F-4DF1-9130-7092E37DE768}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTransferClient", "FileTransferClient\FileTransferClient.csproj", "{F8B727E1-340D-4096-A784-E570AE13FABC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTransferServer", "FileTransferServer\FileTransferServer.csproj", "{9BF859EE-EF90-4B5B-8576-E26770F2F792}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestPipeLine", "TestPipeLine", "{03ACF314-93FC-46FE-9FB8-3F46A01A5A15}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Watcher", "TestPipeLine\Watcher\Watcher.csproj", "{6E04F32A-FB90-41D2-9059-F37311F813B3}" @@ -31,17 +27,29 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.SQL", "ZeroLevel. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroNetworkMonitor", "ZeroNetworkMonitor\ZeroNetworkMonitor.csproj", "{EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigurationTests", "ConfigurationTests\ConfigurationTests.csproj", "{E37785CE-E75A-49FB-B17F-16A0F2C6D656}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Logger", "ZeroLevel.Logger\ZeroLevel.Logger.csproj", "{D1C061DB-3565-43C3-B8F3-628DE4908750}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjectionTests", "DependencyInjectionTests\DependencyInjectionTests.csproj", "{665B38E3-A5F2-4AD0-946B-209D80C1AA40}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.SqLite", "ZeroLevel.SqLite\ZeroLevel.SqLite.csproj", "{5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Logger", "ZeroLevel.Logger\ZeroLevel.Logger.csproj", "{D1C061DB-3565-43C3-B8F3-628DE4908750}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.EventsServer", "ZeroLevel.EventsServer\ZeroLevel.EventsServer.csproj", "{04219F58-4D3A-4707-82A8-4DDDC9882969}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.WPF", "ZeroLevel.WPF\ZeroLevel.WPF.csproj", "{0D70D688-1E21-4E9D-AA49-4D255DF27D8D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WPFExamples", "WPFExamples", "{7CCA0125-7A96-48FA-9F0D-BCF7EAD8FF9D}" + ProjectSection(SolutionItems) = preProject + WPFExamples\Controls\AlignableWrapPanel.cs = WPFExamples\Controls\AlignableWrapPanel.cs + WPFExamples\Convertors\BaseConvertor.cs = WPFExamples\Convertors\BaseConvertor.cs + WPFExamples\BaseViewModel.cs = WPFExamples\BaseViewModel.cs + WPFExamples\Helpers\BitmapSourceHelper.cs = WPFExamples\Helpers\BitmapSourceHelper.cs + WPFExamples\Convertors\BooleanAndConverter.cs = WPFExamples\Convertors\BooleanAndConverter.cs + WPFExamples\Convertors\BoolToVisibilityConverter.cs = WPFExamples\Convertors\BoolToVisibilityConverter.cs + WPFExamples\Controls\ControlUnlocker.cs = WPFExamples\Controls\ControlUnlocker.cs + WPFExamples\Behaviours\ListBoxAutoScrollBehavior.cs = WPFExamples\Behaviours\ListBoxAutoScrollBehavior.cs + WPFExamples\RelayCommand.cs = WPFExamples\RelayCommand.cs + WPFExamples\Controls\VirtualToggleButton.cs = WPFExamples\Controls\VirtualToggleButton.cs + EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.SqLite", "ZeroLevel.SqLite\ZeroLevel.SqLite.csproj", "{5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTransferClient", "FileTransferTest\FileTransferClient\FileTransferClient.csproj", "{F8B727E1-340D-4096-A784-E570AE13FABC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.EventServer", "ZeroLevel.EventServer\ZeroLevel.EventServer.csproj", "{F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTransferServer", "FileTransferTest\FileTransferServer\FileTransferServer.csproj", "{9BF859EE-EF90-4B5B-8576-E26770F2F792}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -61,8 +69,8 @@ Global {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Debug|x86.Build.0 = Debug|Any CPU {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|Any CPU.ActiveCfg = Release|Any CPU {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|Any CPU.Build.0 = Release|Any CPU - {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x64.ActiveCfg = Release|Any CPU - {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x64.Build.0 = Release|Any CPU + {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x64.ActiveCfg = Release|x64 + {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x64.Build.0 = Release|x64 {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x86.ActiveCfg = Release|Any CPU {06C9E60E-D449-41A7-9BF0-A829AAF5D214}.Release|x86.Build.0 = Release|Any CPU {E5595DE0-B177-4078-AD10-8D3135014838}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -73,8 +81,8 @@ Global {E5595DE0-B177-4078-AD10-8D3135014838}.Debug|x86.Build.0 = Debug|Any CPU {E5595DE0-B177-4078-AD10-8D3135014838}.Release|Any CPU.ActiveCfg = Release|Any CPU {E5595DE0-B177-4078-AD10-8D3135014838}.Release|Any CPU.Build.0 = Release|Any CPU - {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x64.ActiveCfg = Release|Any CPU - {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x64.Build.0 = Release|Any CPU + {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x64.ActiveCfg = Release|x64 + {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x64.Build.0 = Release|x64 {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x86.ActiveCfg = Release|Any CPU {E5595DE0-B177-4078-AD10-8D3135014838}.Release|x86.Build.0 = Release|Any CPU {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -85,8 +93,8 @@ Global {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Debug|x86.Build.0 = Debug|Any CPU {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|Any CPU.ActiveCfg = Release|Any CPU {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|Any CPU.Build.0 = Release|Any CPU - {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x64.ActiveCfg = Release|Any CPU - {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x64.Build.0 = Release|Any CPU + {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x64.ActiveCfg = Release|x64 + {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x64.Build.0 = Release|x64 {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x86.ActiveCfg = Release|Any CPU {674561F2-A3E2-40E6-8E5B-AD94276AD856}.Release|x86.Build.0 = Release|Any CPU {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -97,34 +105,10 @@ Global {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|x86.Build.0 = Debug|Any CPU {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|Any CPU.ActiveCfg = Release|Any CPU {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|Any CPU.Build.0 = Release|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.ActiveCfg = Release|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.Build.0 = Release|Any CPU + {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.ActiveCfg = Release|x64 + {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.Build.0 = Release|x64 {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x86.ActiveCfg = Release|Any CPU {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x86.Build.0 = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x64.ActiveCfg = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x64.Build.0 = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x86.ActiveCfg = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x86.Build.0 = Debug|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|Any CPU.Build.0 = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x64.ActiveCfg = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x64.Build.0 = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x86.ActiveCfg = Release|Any CPU - {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x86.Build.0 = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x64.ActiveCfg = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x64.Build.0 = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x86.ActiveCfg = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x86.Build.0 = Debug|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|Any CPU.Build.0 = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x64.ActiveCfg = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x64.Build.0 = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x86.ActiveCfg = Release|Any CPU - {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x86.Build.0 = Release|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Debug|Any CPU.Build.0 = Debug|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -133,8 +117,8 @@ Global {6E04F32A-FB90-41D2-9059-F37311F813B3}.Debug|x86.Build.0 = Debug|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|Any CPU.ActiveCfg = Release|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|Any CPU.Build.0 = Release|Any CPU - {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x64.ActiveCfg = Release|Any CPU - {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x64.Build.0 = Release|Any CPU + {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x64.ActiveCfg = Release|x64 + {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x64.Build.0 = Release|x64 {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x86.ActiveCfg = Release|Any CPU {6E04F32A-FB90-41D2-9059-F37311F813B3}.Release|x86.Build.0 = Release|Any CPU {A1D60994-5744-47D1-B684-C1C0B782998B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -145,8 +129,8 @@ Global {A1D60994-5744-47D1-B684-C1C0B782998B}.Debug|x86.Build.0 = Debug|Any CPU {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|Any CPU.ActiveCfg = Release|Any CPU {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|Any CPU.Build.0 = Release|Any CPU - {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x64.ActiveCfg = Release|Any CPU - {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x64.Build.0 = Release|Any CPU + {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x64.ActiveCfg = Release|x64 + {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x64.Build.0 = Release|x64 {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x86.ActiveCfg = Release|Any CPU {A1D60994-5744-47D1-B684-C1C0B782998B}.Release|x86.Build.0 = Release|Any CPU {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -157,8 +141,8 @@ Global {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Debug|x86.Build.0 = Debug|Any CPU {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|Any CPU.ActiveCfg = Release|Any CPU {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|Any CPU.Build.0 = Release|Any CPU - {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x64.ActiveCfg = Release|Any CPU - {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x64.Build.0 = Release|Any CPU + {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x64.ActiveCfg = Release|x64 + {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x64.Build.0 = Release|x64 {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x86.ActiveCfg = Release|Any CPU {806D0160-A4BF-4881-AF33-308F4FEF8E15}.Release|x86.Build.0 = Release|Any CPU {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -169,8 +153,8 @@ Global {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Debug|x86.Build.0 = Debug|Any CPU {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|Any CPU.Build.0 = Release|Any CPU - {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x64.ActiveCfg = Release|Any CPU - {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x64.Build.0 = Release|Any CPU + {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x64.ActiveCfg = Release|x64 + {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x64.Build.0 = Release|x64 {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x86.ActiveCfg = Release|Any CPU {931DEA89-42D1-4C06-9CB8-A3A0412093D6}.Release|x86.Build.0 = Release|Any CPU {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -181,8 +165,8 @@ Global {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Debug|x86.Build.0 = Debug|Any CPU {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|Any CPU.ActiveCfg = Release|Any CPU {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|Any CPU.Build.0 = Release|Any CPU - {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x64.ActiveCfg = Release|Any CPU - {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x64.Build.0 = Release|Any CPU + {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x64.ActiveCfg = Release|x64 + {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x64.Build.0 = Release|x64 {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x86.ActiveCfg = Release|Any CPU {D25EC1F0-3BD2-409C-8A01-8C8339D5835C}.Release|x86.Build.0 = Release|Any CPU {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -193,34 +177,10 @@ Global {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Debug|x86.Build.0 = Debug|Any CPU {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|Any CPU.ActiveCfg = Release|Any CPU {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|Any CPU.Build.0 = Release|Any CPU - {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x64.ActiveCfg = Release|Any CPU - {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x64.Build.0 = Release|Any CPU + {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x64.ActiveCfg = Release|x64 + {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x64.Build.0 = Release|x64 {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x86.ActiveCfg = Release|Any CPU {EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x86.Build.0 = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x64.ActiveCfg = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x64.Build.0 = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x86.ActiveCfg = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x86.Build.0 = Debug|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|Any CPU.Build.0 = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x64.ActiveCfg = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x64.Build.0 = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x86.ActiveCfg = Release|Any CPU - {E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x86.Build.0 = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|Any CPU.Build.0 = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|x64.ActiveCfg = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|x64.Build.0 = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|x86.ActiveCfg = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Debug|x86.Build.0 = Debug|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|Any CPU.ActiveCfg = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|Any CPU.Build.0 = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|x64.ActiveCfg = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|x64.Build.0 = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|x86.ActiveCfg = Release|Any CPU - {665B38E3-A5F2-4AD0-946B-209D80C1AA40}.Release|x86.Build.0 = Release|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|Any CPU.Build.0 = Debug|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -229,22 +189,10 @@ Global {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x86.Build.0 = Debug|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|Any CPU.Build.0 = Release|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.ActiveCfg = Release|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.Build.0 = Release|Any CPU + {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.ActiveCfg = Release|x64 + {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.Build.0 = Release|x64 {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x86.ActiveCfg = Release|Any CPU {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x86.Build.0 = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|x64.ActiveCfg = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|x64.Build.0 = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|x86.ActiveCfg = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Debug|x86.Build.0 = Debug|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|Any CPU.Build.0 = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|x64.ActiveCfg = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|x64.Build.0 = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|x86.ActiveCfg = Release|Any CPU - {0D70D688-1E21-4E9D-AA49-4D255DF27D8D}.Release|x86.Build.0 = Release|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Debug|Any CPU.Build.0 = Debug|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -253,33 +201,57 @@ Global {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Debug|x86.Build.0 = Debug|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|Any CPU.ActiveCfg = Release|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|Any CPU.Build.0 = Release|Any CPU - {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x64.ActiveCfg = Release|Any CPU - {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x64.Build.0 = Release|Any CPU + {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x64.ActiveCfg = Release|x64 + {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x64.Build.0 = Release|x64 {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x86.ActiveCfg = Release|Any CPU {5B545DD6-8573-4CDD-B32D-9B0AA2AC2F9A}.Release|x86.Build.0 = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|x64.ActiveCfg = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|x64.Build.0 = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|x86.ActiveCfg = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Debug|x86.Build.0 = Debug|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|Any CPU.Build.0 = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|x64.ActiveCfg = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|x64.Build.0 = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|x86.ActiveCfg = Release|Any CPU - {F8116106-48FD-4F1B-A1D2-63FE81DAFD8E}.Release|x86.Build.0 = Release|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|x64.ActiveCfg = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|x64.Build.0 = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|x86.ActiveCfg = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Debug|x86.Build.0 = Debug|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|Any CPU.Build.0 = Release|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|x64.ActiveCfg = Release|x64 + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|x64.Build.0 = Release|x64 + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|x86.ActiveCfg = Release|Any CPU + {04219F58-4D3A-4707-82A8-4DDDC9882969}.Release|x86.Build.0 = Release|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x64.ActiveCfg = Debug|x64 + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x64.Build.0 = Debug|x64 + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x86.ActiveCfg = Debug|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Debug|x86.Build.0 = Debug|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|Any CPU.Build.0 = Release|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x64.ActiveCfg = Release|x64 + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x64.Build.0 = Release|x64 + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x86.ActiveCfg = Release|Any CPU + {F8B727E1-340D-4096-A784-E570AE13FABC}.Release|x86.Build.0 = Release|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x64.ActiveCfg = Debug|x64 + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x64.Build.0 = Debug|x64 + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x86.ActiveCfg = Debug|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Debug|x86.Build.0 = Debug|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|Any CPU.Build.0 = Release|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x64.ActiveCfg = Release|x64 + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x64.Build.0 = Release|x64 + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x86.ActiveCfg = Release|Any CPU + {9BF859EE-EF90-4B5B-8576-E26770F2F792}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {F8B727E1-340D-4096-A784-E570AE13FABC} = {FC074553-5D9F-4DF1-9130-7092E37DE768} - {9BF859EE-EF90-4B5B-8576-E26770F2F792} = {FC074553-5D9F-4DF1-9130-7092E37DE768} {6E04F32A-FB90-41D2-9059-F37311F813B3} = {03ACF314-93FC-46FE-9FB8-3F46A01A5A15} {A1D60994-5744-47D1-B684-C1C0B782998B} = {03ACF314-93FC-46FE-9FB8-3F46A01A5A15} {806D0160-A4BF-4881-AF33-308F4FEF8E15} = {03ACF314-93FC-46FE-9FB8-3F46A01A5A15} {931DEA89-42D1-4C06-9CB8-A3A0412093D6} = {03ACF314-93FC-46FE-9FB8-3F46A01A5A15} + {F8B727E1-340D-4096-A784-E570AE13FABC} = {FC074553-5D9F-4DF1-9130-7092E37DE768} + {9BF859EE-EF90-4B5B-8576-E26770F2F792} = {FC074553-5D9F-4DF1-9130-7092E37DE768} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A65DB16F-877D-4586-A9F3-8BBBFBAF5CEB} diff --git a/ZeroLevel/DataStructures/BloomFilter.cs b/ZeroLevel/DataStructures/BloomFilter.cs index f33989e..e73bfb2 100644 --- a/ZeroLevel/DataStructures/BloomFilter.cs +++ b/ZeroLevel/DataStructures/BloomFilter.cs @@ -16,19 +16,15 @@ namespace ZeroLevel.DataStructures { public ulong PrimiryDirect; public uint SecondDirect; - public uint ThirdDirect; public ulong PrimiryReverse; public uint SecondReverse; - public uint ThirdReverse; } private readonly BitArray _primary; private readonly BitArray _second; - private readonly BitArray _third; private readonly BitArray _r_primary; private readonly BitArray _r_second; - private readonly BitArray _r_third; private readonly bool _use_reverse = false; #endregion @@ -39,13 +35,11 @@ namespace ZeroLevel.DataStructures _primary = new BitArray(bit_size); _second = new BitArray(bit_size); - _third = new BitArray(bit_size); if (_use_reverse) { _r_primary = new BitArray(bit_size); _r_second = new BitArray(bit_size); - _r_third = new BitArray(bit_size); } } @@ -81,16 +75,14 @@ namespace ZeroLevel.DataStructures { var hind = new HIND { - PrimiryDirect = HashUL(line), + PrimiryDirect = HashMM(line), SecondDirect = HashXX(line), - ThirdDirect = HashMM(line) }; if(_use_reverse) { var r = Reverse(line); - hind.PrimiryReverse = HashUL(r); + hind.PrimiryReverse = HashMM(r); hind.SecondReverse = HashXX(r); - hind.ThirdReverse = HashMM(r); } return hind; } @@ -111,9 +103,6 @@ namespace ZeroLevel.DataStructures int si = (int)(hind.SecondDirect % (uint)_second.Length); _second[si] = true; - int ti = (int)(hind.ThirdDirect % (uint)_third.Length); - _third[ti] = true; - if (_use_reverse) { int rpi = (int)(hind.PrimiryReverse % (ulong)_primary.Length); @@ -121,9 +110,6 @@ namespace ZeroLevel.DataStructures int rsi = (int)(hind.SecondReverse % (uint)_second.Length); _r_second[rsi] = true; - - int rti = (int)(hind.ThirdReverse % (uint)_third.Length); - _r_third[rti] = true; } } @@ -136,9 +122,6 @@ namespace ZeroLevel.DataStructures int si = (int)(hind.SecondDirect % (uint)_second.Length); if (!_second[si]) return false; - int ti = (int)(hind.ThirdDirect % (uint)_third.Length); - if (!_third[ti]) return false; - if (_use_reverse) { int rpi = (int)(hind.PrimiryReverse % (ulong)_primary.Length); @@ -146,19 +129,10 @@ namespace ZeroLevel.DataStructures int rsi = (int)(hind.SecondReverse % (uint)_second.Length); if (!_r_second[rsi]) return false; - - int rti = (int)(hind.ThirdReverse % (uint)_third.Length); - if (!_r_third[rti]) return false; } return true; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ulong HashUL(string line) - { - return XXH3_64.Hash(line); - } - private readonly XXHashUnsafe _hash_xx_32 = new XXHashUnsafe(); [MethodImpl(MethodImplOptions.AggressiveInlining)] private uint HashXX(string line) diff --git a/ZeroLevel/Services/Async/AnyResult.cs b/ZeroLevel/Services/Async/AnyResult.cs deleted file mode 100644 index 9dd7240..0000000 --- a/ZeroLevel/Services/Async/AnyResult.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents an item retrieved from one of the asynchronous collections. - /// - public struct AnyResult - : IEquatable> - { - public AnyResult(T value, int collectionIndex) - { - Value = value; - CollectionIndex = collectionIndex; - } - - /// - /// Gets the item retrieved from a collection. - /// - public T Value { get; } - - /// - /// Gets the index of the collection the item was retrieved from. - /// - public int CollectionIndex { get; } - - public override int GetHashCode() - { - unchecked - { - const int prime = -1521134295; - int hash = 12345701; - hash = hash * prime + EqualityComparer.Default.GetHashCode(Value); - hash = hash * prime + EqualityComparer.Default.GetHashCode(CollectionIndex); - return hash; - } - } - - public bool Equals(AnyResult other) => EqualityComparer.Default.Equals(Value, other.Value) && EqualityComparer.Default.Equals(CollectionIndex, other.CollectionIndex); - public override bool Equals(object obj) => obj is AnyResult && Equals((AnyResult)obj); - - public static bool operator ==(AnyResult x, AnyResult y) => x.Equals(y); - public static bool operator !=(AnyResult x, AnyResult y) => !x.Equals(y); - } -} diff --git a/ZeroLevel/Services/Async/AsyncBatchQueue.cs b/ZeroLevel/Services/Async/AsyncBatchQueue.cs deleted file mode 100644 index 335989f..0000000 --- a/ZeroLevel/Services/Async/AsyncBatchQueue.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents a thread-safe collection that groups the items added to it into batches and allows consuming them asynchronously. - /// - /// The type of the items contained in the collection. - public class AsyncBatchQueue : IAsyncBatchCollection - { - private volatile Batch _currentBatch; - private readonly AsyncQueue> _batchQueue = new AsyncQueue>(); - - /// - /// Initializes a new instance of that produces batches of a specified size. - /// - /// Amount of the items contained in an output batch. - public AsyncBatchQueue(int batchSize) - { - if (batchSize <= 0) - throw new ArgumentOutOfRangeException("batchSize", batchSize, "Batch size must be a positive integer."); - - BatchSize = batchSize; - _currentBatch = new Batch(this); - } - - /// - /// Gets amount of items contained in an output batch. - /// - public int BatchSize { get; } - - /// - /// Gets the number of flushed batches currently available for consuming. - /// - public int Count => _batchQueue.Count; - - /// - /// Adds an item to the collection. Flushes the new batch to be available for consuming if amount of the pending items has reached . - /// - /// - public void Add(T item) - { - SpinWait spin = new SpinWait(); - - while (!_currentBatch.TryAdd(item)) - spin.SpinOnce(); - } - - /// - /// Removes and returns a batch from the collection in an asynchronous manner. - /// - public ValueTask> TakeAsync() => TakeAsync(CancellationToken.None); - - /// - /// Removes and returns a batch from the collection in an asynchronous manner. - /// - public ValueTask> TakeAsync(CancellationToken cancellationToken) => _batchQueue.TakeAsync(cancellationToken); - - /// - /// Forces a new batch to be created and made available for consuming even if amount of the pending items has not reached yet. - /// Does nothing if there are no pending items to flush. - /// - public void Flush() - { - SpinWait spin = new SpinWait(); - while (!_currentBatch.TryFlush()) - spin.SpinOnce(); - } - - public IEnumerator> GetEnumerator() => _batchQueue.GetEnumerator(); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - - private class Batch : IReadOnlyList - { - private readonly AsyncBatchQueue _queue; - private readonly T[] _items; - private readonly bool[] _finalizationFlags; - private int _lastReservationIndex = -1; - private int _count = -1; - - public Batch(AsyncBatchQueue queue) - { - _queue = queue; - _items = new T[_queue.BatchSize]; - _finalizationFlags = new bool[_queue.BatchSize]; - } - - public bool TryAdd(T item) - { - int index = Interlocked.Increment(ref _lastReservationIndex); - - // The following is true if someone has beaten us to the last slot and we have to wait until the next batch comes along. - if (index >= _queue.BatchSize) - return false; - - // The following is true if we've taken the last slot, which means we're obligated to flush the current batch and create a new one. - if (index == _queue.BatchSize - 1) - FlushInternal(_queue.BatchSize); - - // The full fence prevents setting finalization flag before the actual item value is written. - _items[index] = item; - Interlocked.MemoryBarrier(); - _finalizationFlags[index] = true; - - return true; - } - - public bool TryFlush() - { - int expectedPreviousReservation = Volatile.Read(ref _lastReservationIndex); - - // We don't flush if the batch doesn't have any items or if another thread is about to flush it. - // However, we report success to avoid unnecessary spinning. - if (expectedPreviousReservation < 0 || expectedPreviousReservation >= _queue.BatchSize - 1) - return true; - - int previousReservation = Interlocked.CompareExchange(ref _lastReservationIndex, _queue.BatchSize, expectedPreviousReservation); - - // Flush reservation has succeeded. - if (expectedPreviousReservation == previousReservation) - { - FlushInternal(previousReservation + 1); - return true; - } - - // The following is true if someone has completed the batch by the time we tried to flush it. - // Therefore the batch will be flushed anyway even if we don't do anything. - // The opposite means someone has slipped in an update and we have to spin. - return previousReservation >= _queue.BatchSize; - } - - private void FlushInternal(int count) - { - _count = count; - _queue._currentBatch = new Batch(_queue); - - // The full fence ensures that the current batch will never be added to the queue before _count is set. - Interlocked.MemoryBarrier(); - - _queue._batchQueue.Add(this); - } - - private T GetItemWithoutValidation(int index) - { - SpinWait spin = new SpinWait(); - while (!_finalizationFlags[index]) - { - spin.SpinOnce(); - - // The full fence prevents caching any part of _finalizationFlags[ index ] expression. - Interlocked.MemoryBarrier(); - } - - // The full fence prevents reading item value before finalization flag is set. - Interlocked.MemoryBarrier(); - return _items[index]; - } - - public T this[int index] - { - get - { - if (index >= Count) - throw new IndexOutOfRangeException(); - - return GetItemWithoutValidation(index); - } - } - - public int Count => _count; - - public IEnumerator GetEnumerator() - { - for (int i = 0; i < Count; i++) - yield return GetItemWithoutValidation(i); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - } - } -} diff --git a/ZeroLevel/Services/Async/AsyncCollection.cs b/ZeroLevel/Services/Async/AsyncCollection.cs deleted file mode 100644 index fb15957..0000000 --- a/ZeroLevel/Services/Async/AsyncCollection.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using ZeroLevel.Services.Async.Internal; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents a thread-safe collection that allows asynchronous consuming. - /// - /// The type of the items contained in the collection. - public class AsyncCollection : IAsyncCollection - { - private readonly IProducerConsumerCollection _itemQueue; - private readonly ConcurrentQueue> _awaiterQueue = new ConcurrentQueue>(); - - // _queueBalance < 0 means there are free awaiters and not enough items. - // _queueBalance > 0 means the opposite is true. - private long _queueBalance = 0; - - /// - /// Initializes a new instance of with a specified as an underlying item storage. - /// - /// The collection to use as an underlying item storage. MUST NOT be accessed elsewhere. - public AsyncCollection(IProducerConsumerCollection itemQueue) - { - _itemQueue = itemQueue; - _queueBalance = _itemQueue.Count; - } - - public int Count => _itemQueue.Count; - - /// - /// Gets an amount of pending item requests. - /// - public int AwaiterCount => _awaiterQueue.Count; - - /// - /// Adds an item to the collection. - /// - /// The item to add to the collection. - public void Add(T item) - { - while (!TryAdd(item)) ; - } - - /// - /// Tries to add an item to the collection. - /// May fail if an awaiter that's supposed to receive the item is cancelled. If this is the case, the TryAdd() method must be called again. - /// - /// The item to add to the collection. - /// True if the item was added to the collection; false if the awaiter was cancelled and the operation must be retried. - private bool TryAdd(T item) - { - long balanceAfterCurrentItem = Interlocked.Increment(ref _queueBalance); - SpinWait spin = new SpinWait(); - - if (balanceAfterCurrentItem > 0) - { - // Items are dominating, so we can safely add a new item to the queue. - while (!_itemQueue.TryAdd(item)) - spin.SpinOnce(); - - return true; - } - else - { - // There's at least one awaiter available or being added as we're speaking, so we're giving the item to it. - - IAwaiter awaiter; - - while (!_awaiterQueue.TryDequeue(out awaiter)) - spin.SpinOnce(); - - // Returns false if the cancellation occurred earlier. - return awaiter.TrySetResult(item); - } - } - - /// - /// Removes and returns an item from the collection in an asynchronous manner. - /// - public ValueTask TakeAsync(CancellationToken cancellationToken) - => cancellationToken.IsCancellationRequested - ? CanceledValueTask.Value - : TakeAsync(new CompletionSourceAwaiterFactory(cancellationToken)); - - private ValueTask TakeAsync(TAwaiterFactory awaiterFactory) where TAwaiterFactory : IAwaiterFactory - { - long balanceAfterCurrentAwaiter = Interlocked.Decrement(ref _queueBalance); - - if (balanceAfterCurrentAwaiter < 0) - { - // Awaiters are dominating, so we can safely add a new awaiter to the queue. - IAwaiter awaiter = awaiterFactory.CreateAwaiter(); - _awaiterQueue.Enqueue(awaiter); - return awaiter.Task; - } - else - { - // There's at least one item available or being added, so we're returning it directly. - - T item; - SpinWait spin = new SpinWait(); - - while (!_itemQueue.TryTake(out item)) - spin.SpinOnce(); - - return new ValueTask(item); - } - } - - public override string ToString() => $"Count = {Count}, Awaiters = {AwaiterCount}"; - - public IEnumerator GetEnumerator() => _itemQueue.GetEnumerator(); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => _itemQueue.GetEnumerator(); - - #region Static - - internal const int TakeFromAnyMaxCollections = BitArray32.BitCapacity; - - /// - /// Removes and returns an item from one of the specified collections in an asynchronous manner. - /// - public static ValueTask> TakeFromAnyAsync(AsyncCollection[] collections) => TakeFromAnyAsync(collections, CancellationToken.None); - - /// - /// Removes and returns an item from one of the specified collections in an asynchronous manner. - /// - public static ValueTask> TakeFromAnyAsync(AsyncCollection[] collections, CancellationToken cancellationToken) - { - if (collections == null) - throw new ArgumentNullException("collections"); - - if (collections.Length <= 0 || collections.Length > TakeFromAnyMaxCollections) - throw new ArgumentException(String.Format("The collection array can't contain less than 1 or more than {0} collections.", TakeFromAnyMaxCollections), "collections"); - - if (cancellationToken.IsCancellationRequested) - return CanceledValueTask>.Value; - - ExclusiveCompletionSourceGroup exclusiveSources = new ExclusiveCompletionSourceGroup(); - - // Fast route: we attempt to take from the top-priority queues that have any items. - // If the fast route succeeds, we avoid allocating and queueing a bunch of awaiters. - for (int i = 0; i < collections.Length; i++) - { - if (collections[i].Count > 0) - { - AnyResult? result = TryTakeFast(exclusiveSources, collections[i], i); - if (result.HasValue) - return new ValueTask>(result.Value); - } - } - - // No luck during the fast route; just queue the rest of awaiters. - for (int i = 0; i < collections.Length; i++) - { - AnyResult? result = TryTakeFast(exclusiveSources, collections[i], i); - if (result.HasValue) - return new ValueTask>(result.Value); - } - - // None of the collections had any items. The order doesn't matter anymore, it's time to start the competition. - exclusiveSources.UnlockCompetition(cancellationToken); - return new ValueTask>(exclusiveSources.Task); - } - - private static AnyResult? TryTakeFast(ExclusiveCompletionSourceGroup exclusiveSources, AsyncCollection collection, int index) - { - // This can happen if the awaiter has already been created during the fast route. - if (exclusiveSources.IsAwaiterCreated(index)) - return null; - - ValueTask collectionTask = collection.TakeAsync(exclusiveSources.CreateAwaiterFactory(index)); - - // One of the collections already had an item and returned it directly - if (collectionTask != null && collectionTask.IsCompleted) - { - exclusiveSources.MarkAsResolved(); - return new AnyResult(collectionTask.Result, index); - } - else - return null; - } - - #endregion - } -} diff --git a/ZeroLevel/Services/Async/AsyncLock.cs b/ZeroLevel/Services/Async/AsyncLock.cs deleted file mode 100644 index 28f6e16..0000000 --- a/ZeroLevel/Services/Async/AsyncLock.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async -{ - public class AsyncLock - { - private object _reentrancy = new object(); - private int _reentrances = 0; - //We are using this SemaphoreSlim like a posix condition variable - //we only want to wake waiters, one or more of whom will try to obtain a different lock to do their thing - //so long as we can guarantee no wakes are missed, the number of awakees is not important - //ideally, this would be "friend" for access only from InnerLock, but whatever. - internal SemaphoreSlim _retry = new SemaphoreSlim(0, 1); - //We do not have System.Threading.Thread.* on .NET Standard without additional dependencies - //Work around is easy: create a new ThreadLocal with a random value and this is our thread id :) - private static readonly long UnlockedThreadId = 0; //"owning" thread id when unlocked - internal long _owningId = UnlockedThreadId; - private static int _globalThreadCounter; - private static readonly ThreadLocal _threadId = new ThreadLocal(() => Interlocked.Increment(ref _globalThreadCounter)); - //We generate a unique id from the thread ID combined with the task ID, if any - public static long ThreadId => (long)(((ulong)_threadId.Value) << 32) | ((uint)(Task.CurrentId ?? 0)); - - struct InnerLock : IDisposable - { - private readonly AsyncLock _parent; -#if DEBUG - private bool _disposed; -#endif - - internal InnerLock(AsyncLock parent) - { - _parent = parent; -#if DEBUG - _disposed = false; -#endif - } - - internal async Task ObtainLockAsync() - { - while (!TryEnter()) - { - //we need to wait for someone to leave the lock before trying again - await _parent._retry.WaitAsync(); - } - } - - internal async Task ObtainLockAsync(CancellationToken ct) - { - while (!TryEnter()) - { - //we need to wait for someone to leave the lock before trying again - await _parent._retry.WaitAsync(ct); - } - } - - internal void ObtainLock() - { - while (!TryEnter()) - { - //we need to wait for someone to leave the lock before trying again - _parent._retry.Wait(); - } - } - - private bool TryEnter() - { - lock (_parent._reentrancy) - { - Debug.Assert((_parent._owningId == UnlockedThreadId) == (_parent._reentrances == 0)); - if (_parent._owningId != UnlockedThreadId && _parent._owningId != AsyncLock.ThreadId) - { - //another thread currently owns the lock - return false; - } - //we can go in - Interlocked.Increment(ref _parent._reentrances); - _parent._owningId = AsyncLock.ThreadId; - return true; - } - } - - public void Dispose() - { -#if DEBUG - Debug.Assert(!_disposed); - _disposed = true; -#endif - lock (_parent._reentrancy) - { - Interlocked.Decrement(ref _parent._reentrances); - if (_parent._reentrances == 0) - { - //the owning thread is always the same so long as we are in a nested stack call - //we reset the owning id to null only when the lock is fully unlocked - _parent._owningId = UnlockedThreadId; - if (_parent._retry.CurrentCount == 0) - { - _parent._retry.Release(); - } - } - } - } - } - - public IDisposable Lock() - { - var @lock = new InnerLock(this); - @lock.ObtainLock(); - return @lock; - } - - public async Task LockAsync() - { - var @lock = new InnerLock(this); - await @lock.ObtainLockAsync(); - return @lock; - } - - public async Task LockAsync(CancellationToken ct) - { - var @lock = new InnerLock(this); - await @lock.ObtainLockAsync(ct); - return @lock; - } - } -} diff --git a/ZeroLevel/Services/Async/AsyncQueue.cs b/ZeroLevel/Services/Async/AsyncQueue.cs deleted file mode 100644 index b860cda..0000000 --- a/ZeroLevel/Services/Async/AsyncQueue.cs +++ /dev/null @@ -1,520 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using ZeroLevel.Services.Async.Internal; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents a thread-safe queue that allows asynchronous consuming. - /// - /// The type of the items contained in the queue. - public class AsyncQueue - : IAsyncCollection - { - internal const int SegmentSize = 32; - - private Segment _itemTail; - private Segment _awaiterTail; - - /// - /// This actually points to either or , depending on which one lags behind. - /// The only reason this field exists is to simplify enumerating segments for things like , or . - /// - private Segment _head; - - /// - /// The value is positive if there are any active enumerators and negative if any segments are being transferred to the pool. - /// - private int _enumerationPoolingBalance = 0; - - private Segment _segmentPoolHead = null; - - /// - /// Initializes a new empty instance of . - /// - public AsyncQueue() - { - Segment firstSegment = new Segment(this) { SegmentID = 0 }; - _itemTail = firstSegment; - _awaiterTail = firstSegment; - _head = firstSegment; - } - - /// - /// Initializes a new instance of that contains elements copied from a specified collection. - /// - /// The collection whose elements are copied to the new queue. - public AsyncQueue(IEnumerable collection) - : this() - { - foreach (T item in collection) - Add(item); - } - - public int AwaiterCount => ComputeCount(Volatile.Read(ref _awaiterTail), Volatile.Read(ref _itemTail), s => s.AwaiterCount); - public int Count => ComputeCount(Volatile.Read(ref _itemTail), Volatile.Read(ref _awaiterTail), s => s.ItemCount); - - private int ComputeCount(Segment myTail, Segment otherTail, Func countExtractor) - { - if (myTail.SegmentID < otherTail.SegmentID) - return 0; - - if (myTail.SegmentID == otherTail.SegmentID) - return countExtractor(myTail); - - int count = countExtractor(myTail) + countExtractor(otherTail); - long fullMiddleSegmentCount = myTail.SegmentID - otherTail.SegmentID - 1; - if (fullMiddleSegmentCount > 0) - count += SegmentSize * (int)fullMiddleSegmentCount; - - return count; - } - - public void Add(T item) - { - SpinWait spin = new SpinWait(); - while (!Volatile.Read(ref _itemTail).TryAdd(item)) - spin.SpinOnce(); - } - - public ValueTask TakeAsync(CancellationToken cancellationToken) - => cancellationToken.IsCancellationRequested - ? CanceledValueTask.Value - : TakeWithoutValidationAsync(cancellationToken); - - private ValueTask TakeWithoutValidationAsync(CancellationToken cancellationToken) - { - SpinWait spin = new SpinWait(); - - while (true) - { - ValueTask? result = Volatile.Read(ref _awaiterTail).TryTakeAsync(cancellationToken); - if (result != null) - return result.Value; - - spin.SpinOnce(); - } - } - - public Enumerator GetEnumerator() - { - SpinWait spin = new SpinWait(); - - while (true) - { - int oldBalance = Volatile.Read(ref _enumerationPoolingBalance); - if (oldBalance >= 0 && Interlocked.CompareExchange(ref _enumerationPoolingBalance, oldBalance + 1, oldBalance) == oldBalance) - break; - - spin.SpinOnce(); - } - - return new Enumerator(this); - } - - IEnumerator IEnumerable.GetEnumerator() => new BoxedEnumerator(GetEnumerator()); - IEnumerator IEnumerable.GetEnumerator() => (this as IEnumerable).GetEnumerator(); - - public struct Enumerator : IEnumerator - { - private SelectManyStructEnumererator _innerEnumerator; - private readonly AsyncQueue _queue; - - public Enumerator(AsyncQueue queue) - { - _queue = queue; - _innerEnumerator = new SelectManyStructEnumererator(new SegmentEnumerator(queue), segment => segment.GetEnumerator()); - } - - public T Current => _innerEnumerator.Current; - object IEnumerator.Current => Current; - - public bool MoveNext() => _innerEnumerator.MoveNext(); - public void Reset() => _innerEnumerator.Reset(); - - public void Dispose() - { - _innerEnumerator.Dispose(); - Interlocked.Decrement(ref _queue._enumerationPoolingBalance); - } - } - - private struct SegmentEnumerator : IEnumerator - { - private readonly AsyncQueue _queue; - private bool _readFirstSegment; - - public SegmentEnumerator(AsyncQueue queue) - { - _queue = queue; - Current = default(Segment); - _readFirstSegment = false; - } - - public Segment Current { get; private set; } - object IEnumerator.Current => Current; - - public bool MoveNext() - { - if (!_readFirstSegment) - { - Current = Volatile.Read(ref _queue._head); - _readFirstSegment = true; - return true; - } - - Current = Current.VolatileNext; - return Current != null; - } - - public void Dispose() - { - } - - public void Reset() - { - } - } - - private class Segment : IEnumerable - { - private readonly T[] _items = new T[SegmentSize]; - private readonly IAwaiter[] _awaiters = new IAwaiter[SegmentSize]; - private readonly int[] _slotStates = new int[SegmentSize]; - - private readonly AsyncQueue _queue; - private long _segmentID; - - private int _awaiterIndex = -1; - private int _itemIndex = -1; - private Segment _next = null; - - private Segment _nextPooledSegment = null; - - public Segment(AsyncQueue queue) - { - _queue = queue; - } - - public Segment VolatileNext => Volatile.Read(ref _next); - - public long SegmentID - { - get { return Volatile.Read(ref _segmentID); } - set { Volatile.Write(ref _segmentID, value); } - } - - public int ItemCount => Math.Max(0, ItemAwaiterBalance); - public int AwaiterCount => Math.Max(0, -ItemAwaiterBalance); - - private int ItemAwaiterBalance => SlotReferenceToCount(ref _itemIndex) - SlotReferenceToCount(ref _awaiterIndex); - private int SlotReferenceToCount(ref int slotReference) => Math.Min(SegmentSize, Volatile.Read(ref slotReference) + 1); - - public bool TryAdd(T item) - => TryAdd(item, Interlocked.Increment(ref _itemIndex)); - - private bool TryAdd(T item, int slot) - => slot < SegmentSize - && TryAddWithoutValidation(item, slot); - - private bool TryAddWithoutValidation(T item, int slot) - { - _items[slot] = item; - bool wonSlot = Interlocked.CompareExchange(ref _slotStates[slot], SlotState.HasItem, SlotState.None) == SlotState.None; - - /// 1. If we have won the slot, the item is considered successfully added. - /// 2. Otherwise, it's up to the result of . - /// Awaiter could have been canceled by now, and if it has, we should return false to insert item again into another slot. - /// We also can't blindly read awaiter from the slot, because captures slot *before* filling in the awaiter. - /// So we have to spin until it is available. - /// And regardless of the awaiter state, we mark the slot as finished because both item and awaiter have visited it. - bool success = wonSlot || TrySetAwaiterResultAndClearSlot(item, slot); - - HandleLastSlotCapture(slot, wonSlot, ref _queue._itemTail); - return success; - } - - private bool TrySetAwaiterResultAndClearSlot(T item, int slot) - { - bool success = SpinUntilAwaiterIsReady(slot).TrySetResult(item); - ClearSlot(slot); - return success; - } - - private IAwaiter SpinUntilAwaiterIsReady(int slot) - { - SpinWait spin = new SpinWait(); - while (true) - { - IAwaiter awaiter = Volatile.Read(ref _awaiters[slot]); - if (awaiter != null) - return awaiter; - - spin.SpinOnce(); - } - } - - public ValueTask? TryTakeAsync(CancellationToken cancellationToken) - => TryTakeAsync(cancellationToken, Interlocked.Increment(ref _awaiterIndex)); - - private ValueTask? TryTakeAsync(CancellationToken cancellationToken, int slot) - => slot < SegmentSize - ? TryTakeWithoutValidationAsync(cancellationToken, slot) - : (ValueTask?)null; - - private ValueTask TryTakeWithoutValidationAsync(CancellationToken cancellationToken, int slot) - { - ValueTask result; - - /// The order here differs from what does: we capture the slot *before* inserting an awaiter. - /// We do it to avoid allocating an awaiter / registering the cancellation that we're not gonna need in case we lose. - /// This means can see the default awaiter value, but it is easily solved by spinning until the awaiter is assigned. - bool wonSlot = Interlocked.CompareExchange(ref _slotStates[slot], SlotState.HasAwaiter, SlotState.None) == SlotState.None; - if (wonSlot) - { - IAwaiter awaiter = new CompletionSourceAwaiterFactory(cancellationToken).CreateAwaiter(); - Volatile.Write(ref _awaiters[slot], awaiter); - result = awaiter.Task; - } - else - { - result = new ValueTask(_items[slot]); - ClearSlot(slot); - } - - HandleLastSlotCapture(slot, wonSlot, ref _queue._awaiterTail); - return result; - } - - private void ClearSlot(int slot) - { - Volatile.Write(ref _slotStates[slot], SlotState.Cleared); - Volatile.Write(ref _awaiters[slot], null); - _items[slot] = default(T); - } - - /// - /// Here comes the tricky part. - /// 0. We only care if we've captured exactly the last slot, so only one thread performs the segment maintenance. - /// 1. Whether the slot is lost or won, the next time the same kind of item is inserted, there's no point in looking for a slot at the current segment. - /// So we have to advance or , depending on the kind of item we're working on right now. - /// 2. The last slot is captured twice: by an item and by an awaiter. We obviously should to grow a segment only once, so only the winner does it. - /// 3. If we've lost the last slot, it's still possible the next segment is not grown yet, so we have to spin. - /// 4. If we've lost the last slot, it means we're done with the current segment: all items and all awaiters have annihilated each other. - /// and are 0 now, so the segment can't contribute to or . - /// So we lose the reference to it by advancing . - /// 5. If we've lost the last slot, we pool it to be reused later. - /// - /// Either or , whichever we're working on right now. - private void HandleLastSlotCapture(int slot, bool wonSlot, ref Segment tailReference) - { - if (!IsLastSlot(slot)) - return; - - Segment nextSegment = wonSlot ? GrowSegment() : SpinUntilNextSegmentIsReady(); - Volatile.Write(ref tailReference, nextSegment); - - if (wonSlot) - return; - - Volatile.Write(ref _queue._head, nextSegment); - TryPoolSegment(); - } - - private void TryPoolSegment() - { - if (!TryDecreaseBalance()) - return; - - /// We reset so it could be GC-ed if it doesn't make it to the pool. - /// It's safe to do so because: - /// 1. guarantees that the whole queue is not being enumerated right now. - /// 2. By this time is already rewritten so future enumerators can't possibly reference the current segment. - /// The rest of the clean-up is *NOT* safe to do here, see for details. - Volatile.Write(ref _next, null); - PushToPool(); - Interlocked.Increment(ref _queue._enumerationPoolingBalance); - } - - private bool TryDecreaseBalance() - { - SpinWait spin = new SpinWait(); - while (true) - { - int enumeratorPoolBalance = Volatile.Read(ref _queue._enumerationPoolingBalance); - - // If the balance is positive, we have some active enumerators and it's dangerous to pool the segment right now. - // We can't spin until the balance is restored either, because we have no guarantee that enumerators will be disposed soon (or will be disposed at all). - // So we have no choice but to give up on pooling the segment. - if (enumeratorPoolBalance > 0) - return false; - - if (Interlocked.CompareExchange(ref _queue._enumerationPoolingBalance, enumeratorPoolBalance - 1, enumeratorPoolBalance) == enumeratorPoolBalance) - return true; - - spin.SpinOnce(); - } - } - - private void PushToPool() - { - SpinWait spin = new SpinWait(); - while (true) - { - Segment oldHead = Volatile.Read(ref _queue._segmentPoolHead); - Volatile.Write(ref _nextPooledSegment, oldHead); - - if (Interlocked.CompareExchange(ref _queue._segmentPoolHead, this, oldHead) == oldHead) - break; - - spin.SpinOnce(); - } - } - - private Segment TryPopSegmentFromPool() - { - SpinWait spin = new SpinWait(); - while (true) - { - Segment oldHead = Volatile.Read(ref _queue._segmentPoolHead); - if (oldHead == null) - return null; - - if (Interlocked.CompareExchange(ref _queue._segmentPoolHead, oldHead._nextPooledSegment, oldHead) == oldHead) - { - Volatile.Write(ref oldHead._nextPooledSegment, null); - return oldHead; - } - - spin.SpinOnce(); - } - } - - /// - /// It's possible for the appenders to read the tail reference before it's updated and to try appending to the segment while it's being pooled. - /// There's no cheap way to prevent it, so we have to be prepared that an append can succeed as fast as we reset or . - /// This means this method must *NOT* be called on putting the segment into the pool, because it could lead to items/awaiters being stored somewhere in the pool. - /// Since there's no guarantee that the segment will ever be reused, this effectively means losing data (or, in the best-case scenario, completely screwing up the item order). - /// We prevent this disaster by calling this method on taking segment from the pool, instead of putting it there. - /// This way even if such append happens, we're about the reattach the segment to the queue and the data won't be lost. - /// - private Segment ResetAfterTakingFromPool() - { - /// We must reset before and . - /// Otherwise appenders could successfully increment a pointer and mess with the slots before they are ready to be messed with. - for (int i = 0; i < SegmentSize; i++) - { - /// We can't simply overwrite the state, because it's possible that the slot loser has not finished yet. - SpinWait spin = new SpinWait(); - while (Interlocked.CompareExchange(ref _slotStates[i], SlotState.None, SlotState.Cleared) != SlotState.Cleared) - spin.SpinOnce(); - } - - Volatile.Write(ref _awaiterIndex, -1); - Volatile.Write(ref _itemIndex, -1); - - return this; - } - - private static bool IsLastSlot(int slot) => slot == SegmentSize - 1; - - private Segment SpinUntilNextSegmentIsReady() - { - SpinWait spin = new SpinWait(); - while (VolatileNext == null) - spin.SpinOnce(); - - return VolatileNext; - } - - private Segment GrowSegment() - { - Segment newTail = TryPopSegmentFromPool()?.ResetAfterTakingFromPool() ?? new Segment(_queue); - newTail.SegmentID = _segmentID + 1; - Volatile.Write(ref _next, newTail); - return newTail; - } - - private int SpinUntilStateIsResolvedAndReturnState(int slot) - { - SpinWait spin = new SpinWait(); - int slotState; - while (true) - { - slotState = Volatile.Read(ref _slotStates[slot]); - if (slotState != SlotState.None) - break; - - spin.SpinOnce(); - } - - return slotState; - } - - public Enumerator GetEnumerator() => new Enumerator(this); - IEnumerator IEnumerable.GetEnumerator() => new BoxedEnumerator(GetEnumerator()); - IEnumerator IEnumerable.GetEnumerator() => (this as IEnumerable).GetEnumerator(); - - private static class SlotState - { - public const int None = 0; - public const int HasItem = 1; - public const int HasAwaiter = 2; - public const int Cleared = 3; - } - - public struct Enumerator : IEnumerator - { - private readonly Segment _segment; - private int _currentSlot; - private int _effectiveLength; - - public Enumerator(Segment segment) - { - _segment = segment; - _currentSlot = Int32.MinValue; - _effectiveLength = Int32.MinValue; - Current = default(T); - } - - public T Current { get; private set; } - object IEnumerator.Current => Current; - - public bool MoveNext() - { - if (_currentSlot == Int32.MinValue) - { - /// Items in slots 0 .. are taken by awaiters, so they are no longer considered stored in the queue. - _currentSlot = _segment.SlotReferenceToCount(ref _segment._awaiterIndex); - - /// is the last slot an item actually exists at at the moment, so we shouldn't enumerate through the default values that are stored further. - _effectiveLength = _segment.SlotReferenceToCount(ref _segment._itemIndex); - } - - while (_currentSlot < _effectiveLength) - { - int slotState = _segment.SpinUntilStateIsResolvedAndReturnState(_currentSlot); - Current = _segment._items[_currentSlot]; - _currentSlot++; - - if (slotState == SlotState.HasItem) - return true; - } - - return false; - } - - public void Dispose() - { - } - - public void Reset() - { - } - } - } - } -} diff --git a/ZeroLevel/Services/Async/AsyncStack.cs b/ZeroLevel/Services/Async/AsyncStack.cs deleted file mode 100644 index 6deb45e..0000000 --- a/ZeroLevel/Services/Async/AsyncStack.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents a thread-safe stack that allows asynchronous consuming. - /// - /// The type of the items contained in the stack. - public class AsyncStack - : AsyncCollection - { - /// - /// Initializes a new empty instance of . - /// - public AsyncStack() : base(new ConcurrentStack()) { } - - /// - /// Initializes a new instance of that contains elements copied from a specified collection. - /// - /// The collection whose elements are copied to the new stack. - public AsyncStack(IEnumerable collection) : base(new ConcurrentStack(collection)) { } - } -} diff --git a/ZeroLevel/Services/Async/IAsyncBatchCollection.cs b/ZeroLevel/Services/Async/IAsyncBatchCollection.cs deleted file mode 100644 index b3bbe2b..0000000 --- a/ZeroLevel/Services/Async/IAsyncBatchCollection.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async -{ - public interface IAsyncBatchCollection : IReadOnlyCollection> - { - int BatchSize { get; } - - void Add(T item); - void Flush(); - ValueTask> TakeAsync(CancellationToken cancellationToken); - } - - public static class AsyncBatchCollectionExtensions - { - public static ValueTask> TakeAsync(this IAsyncBatchCollection collection) => collection.TakeAsync(CancellationToken.None); - public static TimerAsyncBatchQueue WithFlushEvery(this IAsyncBatchCollection collection, TimeSpan flushPeriod) => new TimerAsyncBatchQueue(collection, flushPeriod); - } -} diff --git a/ZeroLevel/Services/Async/IAsyncCollection.cs b/ZeroLevel/Services/Async/IAsyncCollection.cs deleted file mode 100644 index a9b798f..0000000 --- a/ZeroLevel/Services/Async/IAsyncCollection.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async -{ - /// - /// Represents a thread-safe collection that allows asynchronous consuming. - /// - /// The type of the items contained in the collection. - public interface IAsyncCollection - : IReadOnlyCollection - { - /// - /// Gets an amount of pending item requests. - /// - int AwaiterCount { get; } - - /// - /// Adds an item to the collection. - /// - /// The item to add to the collection. - void Add(T item); - - /// - /// Removes and returns an item from the collection in an asynchronous manner. - /// - ValueTask TakeAsync(CancellationToken cancellationToken); - } - - public static class AsyncCollectionExtensions - { - /// - /// Removes and returns an item from the collection in an asynchronous manner. - /// - public static ValueTask TakeAsync(this IAsyncCollection collection) - { - return collection.TakeAsync(CancellationToken.None); - } - } -} diff --git a/ZeroLevel/Services/Async/Internal/BoxedEnumerator.cs b/ZeroLevel/Services/Async/Internal/BoxedEnumerator.cs deleted file mode 100644 index 48b8b87..0000000 --- a/ZeroLevel/Services/Async/Internal/BoxedEnumerator.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace ZeroLevel.Services.Async.Internal -{ - /// Turns out iterating through manually boxed iterator is a bit faster than through automatically boxed one. - internal class BoxedEnumerator - : IEnumerator where TEnumerator : struct, IEnumerator - { - private TEnumerator _structEnumerator; - - public BoxedEnumerator(TEnumerator structEnumerator) - { - _structEnumerator = structEnumerator; - } - - public TItem Current => _structEnumerator.Current; - object IEnumerator.Current => Current; - public void Dispose() => _structEnumerator.Dispose(); - public bool MoveNext() => _structEnumerator.MoveNext(); - public void Reset() => _structEnumerator.Reset(); - } -} diff --git a/ZeroLevel/Services/Async/Internal/CanceledValueTask.cs b/ZeroLevel/Services/Async/Internal/CanceledValueTask.cs deleted file mode 100644 index 918d9db..0000000 --- a/ZeroLevel/Services/Async/Internal/CanceledValueTask.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async.Internal -{ - internal static class CanceledValueTask - { - public static readonly ValueTask Value = CreateCanceledTask(); - - private static ValueTask CreateCanceledTask() - { - TaskCompletionSource tcs = new TaskCompletionSource(); - tcs.SetCanceled(); - return new ValueTask(tcs.Task); - } - } -} diff --git a/ZeroLevel/Services/Async/Internal/CompletionSourceAwaiterFactory.cs b/ZeroLevel/Services/Async/Internal/CompletionSourceAwaiterFactory.cs deleted file mode 100644 index 54d0501..0000000 --- a/ZeroLevel/Services/Async/Internal/CompletionSourceAwaiterFactory.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async.Internal -{ - internal struct CompletionSourceAwaiterFactory - : IAwaiterFactory, IEquatable> - { - private readonly CancellationToken _cancellationToken; - - public CompletionSourceAwaiterFactory(CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - } - - public IAwaiter CreateAwaiter() => new CompletionSourceAwaiter(_cancellationToken); - - /// - /// A simple wrapper that implements . - /// - private class CompletionSourceAwaiter : IAwaiter - { - private readonly TaskCompletionSource _completionSource; - private readonly CancellationTokenRegistration _registration; - - public CompletionSourceAwaiter(CancellationToken cancellationToken) - { - _completionSource = new TaskCompletionSource(); - Task = new ValueTask(_completionSource.Task.WithYield()); - - _registration = cancellationToken.Register( - state => - { - TaskCompletionSource awaiter = state as TaskCompletionSource; - awaiter.TrySetCanceled(); - }, - _completionSource, - useSynchronizationContext: false); - } - - public bool TrySetResult(T result) - { - _registration.Dispose(); - return _completionSource.TrySetResult(result); - } - - public ValueTask Task { get; } - } - - #region IEquatable> - - public override int GetHashCode() => EqualityComparer.Default.GetHashCode(_cancellationToken); - public bool Equals(CompletionSourceAwaiterFactory other) => _cancellationToken == other._cancellationToken; - public override bool Equals(object obj) => obj is CompletionSourceAwaiterFactory && Equals((CompletionSourceAwaiterFactory)obj); - - public static bool operator ==(CompletionSourceAwaiterFactory x, CompletionSourceAwaiterFactory y) => x.Equals(y); - public static bool operator !=(CompletionSourceAwaiterFactory x, CompletionSourceAwaiterFactory y) => !x.Equals(y); - - #endregion - } -} diff --git a/ZeroLevel/Services/Async/Internal/ExclusiveCompletionSourceGroup.cs b/ZeroLevel/Services/Async/Internal/ExclusiveCompletionSourceGroup.cs deleted file mode 100644 index 9eba0c4..0000000 --- a/ZeroLevel/Services/Async/Internal/ExclusiveCompletionSourceGroup.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async.Internal -{ - /// - /// A set of exclusive awaiters that allows only one of the awaiters to be completed. - /// - internal class ExclusiveCompletionSourceGroup - { - private int _completedSource = State.Locked; - private readonly TaskCompletionSource> _realCompetionSource = new TaskCompletionSource>(); - private BitArray32 _awaitersCreated = BitArray32.Empty; - private CancellationRegistrationHolder _cancellationRegistrationHolder; - - public ExclusiveCompletionSourceGroup() - { - Task = _realCompetionSource.Task.WithYield(); - } - - public Task> Task { get; } - - public bool IsAwaiterCreated(int index) => _awaitersCreated.IsBitSet(index); - public Factory CreateAwaiterFactory(int index) => new Factory(this, index); - - private IAwaiter CreateAwaiter(int index) - { - _awaitersCreated = _awaitersCreated.WithBitSet(index); - return new ExclusiveCompletionSource(this, index); - } - - public void MarkAsResolved() => Interlocked.CompareExchange(ref _completedSource, State.Canceled, State.Unlocked); - - public void UnlockCompetition(CancellationToken cancellationToken) - { - CancellationTokenRegistration registration = cancellationToken - .Register - ( - state => - { - ExclusiveCompletionSourceGroup group = state as ExclusiveCompletionSourceGroup; - - /// There are 2 cases here. - /// - /// #1: The token is canceled before is called, but after the token is validated higher up the stack. - /// Is this is the case, the cancellation callbak will be called synchronously while is still set to . - /// So the competition will never progress to and we have to check for this explicitly. - /// - /// #2: We're canceled after the competition has been unlocked. - /// If this is the case, we have a simple race against the awaiters to progress from to . - if (group.TryTransitionToCanceledIfStateIs(State.Locked) || group.TryTransitionToCanceledIfStateIs(State.Unlocked)) - group._realCompetionSource.SetCanceled(); - }, - this, - useSynchronizationContext: false - ); - - // We can't do volatile reads/writes on a custom value type field, so we have to wrap the registration into a holder instance. - // But there's no point in allocating the wrapper if the token can never be canceled. - if (cancellationToken.CanBeCanceled) - Volatile.Write(ref _cancellationRegistrationHolder, new CancellationRegistrationHolder(registration)); - - // If the cancellation was processed synchronously, the state will already be set to Canceled and we must *NOT* unlock the competition. - Interlocked.CompareExchange(ref _completedSource, State.Unlocked, State.Locked); - } - - private bool TryTransitionToCanceledIfStateIs(int requiredState) => Interlocked.CompareExchange(ref _completedSource, State.Canceled, requiredState) == requiredState; - - private static class State - { - public const int Locked = -1; - public const int Unlocked = -2; - public const int Canceled = Int32.MinValue; - } - - private class CancellationRegistrationHolder - { - public CancellationRegistrationHolder(CancellationTokenRegistration registration) - { - Registration = registration; - } - - public CancellationTokenRegistration Registration { get; } - } - - private class ExclusiveCompletionSource : IAwaiter - { - private static readonly ValueTask _neverEndingTask = new ValueTask(new TaskCompletionSource().Task); - private readonly ExclusiveCompletionSourceGroup _group; - private readonly int _id; - - public ExclusiveCompletionSource(ExclusiveCompletionSourceGroup group, int id) - { - _group = group; - _id = id; - } - - public bool TrySetResult(T result) - { - SpinWait spin = new SpinWait(); - - while (true) - { - int completedSource = Interlocked.CompareExchange(ref _group._completedSource, _id, State.Unlocked); - - if (completedSource == State.Unlocked) - { - // We are the champions! - _group._realCompetionSource.SetResult(new AnyResult(result, _id)); - - // This also means we're the ones responsible for disposing the cancellation registration. - // It's important to remember the holder can be null if the token is non-cancellable. - Volatile.Read(ref _group._cancellationRegistrationHolder)?.Registration.Dispose(); - return true; - } - - if (completedSource == State.Locked) - { - // The competition has not started yet. - spin.SpinOnce(); - continue; - } - - // Everything else means we've lost the competition and another completion source has got the result - return false; - } - } - - // The value will never be actually used. - public ValueTask Task => _neverEndingTask; - } - - public struct Factory : IAwaiterFactory, IEquatable - { - private readonly ExclusiveCompletionSourceGroup _group; - private readonly int _index; - - public Factory(ExclusiveCompletionSourceGroup group, int index) - { - _group = group; - _index = index; - } - - public IAwaiter CreateAwaiter() => _group.CreateAwaiter(_index); - - #region IEquatable - - public override int GetHashCode() - { - unchecked - { - const int prime = -1521134295; - int hash = 12345701; - hash = hash * prime + EqualityComparer>.Default.GetHashCode(_group); - hash = hash * prime + EqualityComparer.Default.GetHashCode(_index); - return hash; - } - } - - public bool Equals(Factory other) => EqualityComparer>.Default.Equals(_group, other._group) && EqualityComparer.Default.Equals(_index, other._index); - public override bool Equals(object obj) => obj is Factory && Equals((Factory)obj); - - public static bool operator ==(Factory x, Factory y) => x.Equals(y); - public static bool operator !=(Factory x, Factory y) => !x.Equals(y); - - #endregion - } - } -} diff --git a/ZeroLevel/Services/Async/Internal/IAwaiter.cs b/ZeroLevel/Services/Async/Internal/IAwaiter.cs deleted file mode 100644 index e52a4c8..0000000 --- a/ZeroLevel/Services/Async/Internal/IAwaiter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async.Internal -{ - /// - /// Represents an abstract item awaiter. - /// - internal interface IAwaiter - { - /// - /// Attempts to complete the awaiter with a specified result. - /// Returns false if the awaiter has been canceled. - /// - bool TrySetResult(T result); - - /// - /// The task that's completed when the awaiter gets the result. - /// - ValueTask Task { get; } - } -} diff --git a/ZeroLevel/Services/Async/Internal/IAwaiterFactory.cs b/ZeroLevel/Services/Async/Internal/IAwaiterFactory.cs deleted file mode 100644 index 2ae73f5..0000000 --- a/ZeroLevel/Services/Async/Internal/IAwaiterFactory.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZeroLevel.Services.Async.Internal -{ - internal interface IAwaiterFactory - { - IAwaiter CreateAwaiter(); - } -} diff --git a/ZeroLevel/Services/Async/Internal/SelectManyStructEnumererator.cs b/ZeroLevel/Services/Async/Internal/SelectManyStructEnumererator.cs deleted file mode 100644 index eea19f6..0000000 --- a/ZeroLevel/Services/Async/Internal/SelectManyStructEnumererator.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace ZeroLevel.Services.Async.Internal -{ - internal struct SelectManyStructEnumererator : IEnumerator - where TSourceEnumerator : struct, IEnumerator - where TTargetEnumerator : struct, IEnumerator - { - private readonly Func _selector; - private TSourceEnumerator _sourceEnumerator; - - private TTargetEnumerator _currentTargetEnumerator; - private bool _hasCurrentTarget; - - public SelectManyStructEnumererator(TSourceEnumerator sourceEnumerator, Func selector) - { - _sourceEnumerator = sourceEnumerator; - _selector = selector; - - _hasCurrentTarget = false; - _currentTargetEnumerator = default(TTargetEnumerator); - Current = default(TTarget); - } - - public TTarget Current { get; private set; } - object IEnumerator.Current => Current; - - public bool MoveNext() - { - do - { - if (!_hasCurrentTarget && !TryMoveToNextTarget()) - return false; - - if (_currentTargetEnumerator.MoveNext()) - { - Current = _currentTargetEnumerator.Current; - return true; - } - } - while (TryMoveToNextTarget()); - - return false; - } - - private bool TryMoveToNextTarget() - { - TryDisposeCurrentTarget(); - - _hasCurrentTarget = _sourceEnumerator.MoveNext(); - if (_hasCurrentTarget) - _currentTargetEnumerator = _selector(_sourceEnumerator.Current); - - return _hasCurrentTarget; - } - - private void TryDisposeCurrentTarget() - { - if (_hasCurrentTarget) - _currentTargetEnumerator.Dispose(); - } - - public void Dispose() => TryDisposeCurrentTarget(); - - public void Reset() - { - } - } -} diff --git a/ZeroLevel/Services/Async/Internal/TaskExtensions.cs b/ZeroLevel/Services/Async/Internal/TaskExtensions.cs deleted file mode 100644 index e62555b..0000000 --- a/ZeroLevel/Services/Async/Internal/TaskExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async.Internal -{ - internal static class TaskExtensions - { - public static async Task WithYield(this Task task) - { - var result = await task.ConfigureAwait(false); - await Task.Yield(); - return result; - } - } -} diff --git a/ZeroLevel/Services/Async/TimerAsyncBatchQueue.cs b/ZeroLevel/Services/Async/TimerAsyncBatchQueue.cs deleted file mode 100644 index c880d61..0000000 --- a/ZeroLevel/Services/Async/TimerAsyncBatchQueue.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Async -{ - public class TimerAsyncBatchQueue - : IAsyncBatchCollection, IDisposable - { - private readonly Timer _flushTimer; - private readonly IAsyncBatchCollection _innerCollection; - - public TimerAsyncBatchQueue(IAsyncBatchCollection innerCollection, TimeSpan flushPeriod) - { - _innerCollection = innerCollection; - _flushTimer = new Timer(_ => Flush(), null, flushPeriod, flushPeriod); - } - - public int BatchSize => _innerCollection.BatchSize; - public int Count => _innerCollection.Count; - public void Add(T item) => _innerCollection.Add(item); - public ValueTask> TakeAsync(CancellationToken cancellationToken) => _innerCollection.TakeAsync(cancellationToken); - public void Flush() => _innerCollection.Flush(); - public IEnumerator> GetEnumerator() => _innerCollection.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => (_innerCollection as IEnumerable).GetEnumerator(); - - public void Dispose() => _flushTimer.Dispose(); - } -} diff --git a/ZeroLevel/Services/DependencyInjection/Container.cs b/ZeroLevel/Services/DependencyInjection/Container.cs index 38b1777..c6a1070 100644 --- a/ZeroLevel/Services/DependencyInjection/Container.cs +++ b/ZeroLevel/Services/DependencyInjection/Container.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Threading; using ZeroLevel.Services.Collections; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { internal sealed class Container : IContainer diff --git a/ZeroLevel/Services/DependencyInjection/ContainerFactory.cs b/ZeroLevel/Services/DependencyInjection/ContainerFactory.cs index be0c311..733ae4d 100644 --- a/ZeroLevel/Services/DependencyInjection/ContainerFactory.cs +++ b/ZeroLevel/Services/DependencyInjection/ContainerFactory.cs @@ -3,7 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { public sealed class ContainerFactory : IContainerFactory { diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/ICompositionProvider.cs b/ZeroLevel/Services/DependencyInjection/Contracts/ICompositionProvider.cs index dda72b8..ebf4d00 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/ICompositionProvider.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/ICompositionProvider.cs @@ -1,4 +1,4 @@ -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Provides object composition diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IContainer.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IContainer.cs index 0edda73..f974f80 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IContainer.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IContainer.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { public interface IContainer : IContainerRegister, diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerFactory.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerFactory.cs index 20b8128..605ac50 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerFactory.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerFactory.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { public interface IContainerFactory : IDisposable { diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerInstanceRegister.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerInstanceRegister.cs index 98a819e..37ef652 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerInstanceRegister.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerInstanceRegister.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Methods for register contact implementations diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerRegister.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerRegister.cs index 5dd8440..d5a271a 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IContainerRegister.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IContainerRegister.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Methods for register contact resolvings diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IParameterStorage.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IParameterStorage.cs index 4f1759f..4a72b27 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IParameterStorage.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IParameterStorage.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// DI parameters stogare (string key and anytype value) diff --git a/ZeroLevel/Services/DependencyInjection/Contracts/IResolver.cs b/ZeroLevel/Services/DependencyInjection/Contracts/IResolver.cs index 7945e65..aa339a5 100644 --- a/ZeroLevel/Services/DependencyInjection/Contracts/IResolver.cs +++ b/ZeroLevel/Services/DependencyInjection/Contracts/IResolver.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Dependency resolver diff --git a/ZeroLevel/Services/DependencyInjection/Injector.cs b/ZeroLevel/Services/DependencyInjection/Injector.cs index 2858223..c802b97 100644 --- a/ZeroLevel/Services/DependencyInjection/Injector.cs +++ b/ZeroLevel/Services/DependencyInjection/Injector.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using ZeroLevel.Patterns.DependencyInjection; +using ZeroLevel.DependencyInjection; namespace ZeroLevel { diff --git a/ZeroLevel/Services/DependencyInjection/Internal/ConstructorMetadata.cs b/ZeroLevel/Services/DependencyInjection/Internal/ConstructorMetadata.cs index d1c5fc4..74e7a48 100644 --- a/ZeroLevel/Services/DependencyInjection/Internal/ConstructorMetadata.cs +++ b/ZeroLevel/Services/DependencyInjection/Internal/ConstructorMetadata.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Constructor metadata diff --git a/ZeroLevel/Services/DependencyInjection/Internal/ConstructorParameter.cs b/ZeroLevel/Services/DependencyInjection/Internal/ConstructorParameter.cs index c583d9d..5b01681 100644 --- a/ZeroLevel/Services/DependencyInjection/Internal/ConstructorParameter.cs +++ b/ZeroLevel/Services/DependencyInjection/Internal/ConstructorParameter.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Constructor argument type diff --git a/ZeroLevel/Services/DependencyInjection/Internal/ResolveTypeInfo.cs b/ZeroLevel/Services/DependencyInjection/Internal/ResolveTypeInfo.cs index 963bcd8..69fa9e7 100644 --- a/ZeroLevel/Services/DependencyInjection/Internal/ResolveTypeInfo.cs +++ b/ZeroLevel/Services/DependencyInjection/Internal/ResolveTypeInfo.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { /// /// Dependency resolving metadata diff --git a/ZeroLevel/Services/DependencyInjection/ParameterAttribute.cs b/ZeroLevel/Services/DependencyInjection/ParameterAttribute.cs index a28bfc1..d7e1657 100644 --- a/ZeroLevel/Services/DependencyInjection/ParameterAttribute.cs +++ b/ZeroLevel/Services/DependencyInjection/ParameterAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { public sealed class ParameterAttribute : Attribute { diff --git a/ZeroLevel/Services/DependencyInjection/ResolveAttribute.cs b/ZeroLevel/Services/DependencyInjection/ResolveAttribute.cs index 910738b..8acb737 100644 --- a/ZeroLevel/Services/DependencyInjection/ResolveAttribute.cs +++ b/ZeroLevel/Services/DependencyInjection/ResolveAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace ZeroLevel.Patterns.DependencyInjection +namespace ZeroLevel.DependencyInjection { public sealed class ResolveAttribute : Attribute { diff --git a/ZeroLevel/Services/Async/Internal/BitArray32.cs b/ZeroLevel/Services/Extensions/BitArray32.cs similarity index 100% rename from ZeroLevel/Services/Async/Internal/BitArray32.cs rename to ZeroLevel/Services/Extensions/BitArray32.cs diff --git a/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs b/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs index 02e3c9f..0dccc52 100644 --- a/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs +++ b/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs @@ -1,8 +1,6 @@ using System; using System.Globalization; using System.IO; -using System.Security.Permissions; -using System.Threading.Tasks; namespace ZeroLevel.Services.FileSystem { @@ -13,9 +11,9 @@ namespace ZeroLevel.Services.FileSystem private readonly string _sourceFolder; private readonly string _temporaryFolder; private readonly TimeSpan _period; - private readonly Func _callback; + private readonly Action _callback; - public PeriodicFileSystemWatcher(TimeSpan period, string watch_folder, string temp_folder, Func callback) + public PeriodicFileSystemWatcher(TimeSpan period, string watch_folder, string temp_folder, Action callback) { if (string.IsNullOrWhiteSpace(watch_folder)) { @@ -41,15 +39,15 @@ namespace ZeroLevel.Services.FileSystem public void Start() { - _updateSourceTaskKey = Sheduller.RemindAsyncEvery(_period, CheckSourceFolder); + _updateSourceTaskKey = Sheduller.RemindEvery(_period, CheckSourceFolder); } public void Stop() { - Sheduller.RemoveAsync(_updateSourceTaskKey); + Sheduller.Remove(_updateSourceTaskKey); } - private async Task CheckSourceFolder() + private void CheckSourceFolder() { try { @@ -73,7 +71,7 @@ namespace ZeroLevel.Services.FileSystem continue; } Log.Debug($"[PeriodicFileSystemWatcher] Handle file {file}"); - await _callback(new FileMeta(Path.GetFileName(file), tempFile)); + _callback(new FileMeta(Path.GetFileName(file), tempFile)); File.Delete(tempFile); } catch (Exception ex) diff --git a/ZeroLevel/Services/HashFunctions/Utils.cs b/ZeroLevel/Services/HashFunctions/Utils.cs deleted file mode 100644 index 8c9268a..0000000 --- a/ZeroLevel/Services/HashFunctions/Utils.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace ZeroLevel.Services.HashFunctions -{ - internal static class Utils - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan PopAll(this ref ReadOnlySpan @this) where TTo : struct - { -#if NETCOREAPP3_0 - var totBytes = @this.Length; - var toLength = (totBytes / Unsafe.SizeOf()); - var sliceLength = toLength * Unsafe.SizeOf(); - ref var thisRef = ref MemoryMarshal.GetReference(@this); - @this = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref thisRef, sliceLength), totBytes - sliceLength); - return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref thisRef), toLength); -#else - return @this.PopAll(); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan PopAll(this ref ReadOnlySpan @this) where TFrom : struct where TTo : struct - { - var totBytes = @this.Length * Unsafe.SizeOf(); - var toLength = (totBytes / Unsafe.SizeOf()); - var sliceLength = toLength * Unsafe.SizeOf() / Unsafe.SizeOf(); - -#if NETSTANDARD2_0 - var result = MemoryMarshal.Cast(@this); -#else - var result = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref MemoryMarshal.GetReference(@this)), toLength); -#endif - @this = @this.Slice(sliceLength); - return result; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint AsLittleEndian(this uint @this) - { - if (BitConverter.IsLittleEndian) { return @this; } - return BinaryPrimitives.ReverseEndianness(@this); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong AsLittleEndian(this ulong @this) - { - if (BitConverter.IsLittleEndian) { return @this; } - return BinaryPrimitives.ReverseEndianness(@this); - } - - public static bool TryPop(this ref ReadOnlySpan @this, int count, out ReadOnlySpan popped) where TTo : struct - { - var byteCount = count * Unsafe.SizeOf(); - if (@this.Length >= byteCount) - { - popped = MemoryMarshal.Cast(@this.Slice(0, byteCount)); - @this = @this.Slice(byteCount); - return true; - } - popped = default; - return false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref readonly TTo First(this ReadOnlySpan @this) where TTo : struct - { - return ref MemoryMarshal.Cast(@this)[0]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref readonly TTo Last(this ReadOnlySpan @this) where TTo : struct - { - return ref MemoryMarshal.Cast(@this.Slice(@this.Length - Unsafe.SizeOf()))[0]; - } - - public static ref readonly TTo First(this ReadOnlySpan @this) where TTo : struct where TFrom : struct - { -#if NETSTANDARD2_0 - return ref MemoryMarshal.Cast(@this)[0]; -#else - //TODO: is this version actually any faster/better at all? - return ref MemoryMarshal.AsRef(MemoryMarshal.AsBytes(@this)); -#endif - } - } - - public static class Safeish - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref readonly TTo As(in TFrom from) where TTo : struct where TFrom : struct - { - if (Unsafe.SizeOf() < Unsafe.SizeOf()) { throw new InvalidCastException(); } - return ref Unsafe.As(ref Unsafe.AsRef(from)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref TTo AsMut(ref TFrom from) where TTo : struct where TFrom : struct - { - if (Unsafe.SizeOf() < Unsafe.SizeOf()) { throw new InvalidCastException(); } - return ref Unsafe.As(ref from); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan AsSpan(in TFrom from) where TTo : struct where TFrom : struct - { -#if NETSTANDARD2_0 - var asSpan = CreateReadOnlySpan(ref Unsafe.AsRef(from)); -#else - var asSpan = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(from), 1); -#endif - return MemoryMarshal.Cast(asSpan); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span AsMutableSpan(ref TFrom from) where TTo : struct where TFrom : struct - { -#if NETSTANDARD2_0 - var asSpan = CreateSpan(ref Unsafe.AsRef(from)); -#else - var asSpan = MemoryMarshal.CreateSpan(ref from, 1); -#endif - return MemoryMarshal.Cast(asSpan); - } - -#if NETSTANDARD2_0 - private static unsafe Span CreateSpan(ref T from) where T : struct - { - void* ptr = Unsafe.AsPointer(ref from); - return new Span(ptr, 1); - } - - private static unsafe ReadOnlySpan CreateReadOnlySpan(ref T from) where T : struct - { - void* ptr = Unsafe.AsPointer(ref from); - return new ReadOnlySpan(ptr, 1); - } -#endif - } -} diff --git a/ZeroLevel/Services/HashFunctions/XXH3_64.cs b/ZeroLevel/Services/HashFunctions/XXH3_64.cs deleted file mode 100644 index ef11770..0000000 --- a/ZeroLevel/Services/HashFunctions/XXH3_64.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace ZeroLevel.Services.HashFunctions -{ - public static class XXH3_64 - { - private const ulong PRIME64_1 = 11400714785074694791UL; - private const ulong PRIME64_2 = 14029467366897019727UL; - private const ulong PRIME64_3 = 1609587929392839161UL; - private const ulong PRIME64_4 = 9650029242287828579UL; - private const ulong PRIME64_5 = 2870177450012600261UL; - - [StructLayout(LayoutKind.Sequential)] - private struct QuadUlong - { - public ulong v1; - public ulong v2; - public ulong v3; - public ulong v4; - } - - public static ulong Hash(string line) - { - return Hash(new ReadOnlySpan(Encoding.UTF8.GetBytes(line))); - } - - public static ulong Hash(in ReadOnlySpan buffer) - { - unchecked - { - var remainingBytes = buffer; - var bulkVals = remainingBytes.PopAll(); - - var h64 = !bulkVals.IsEmpty ? BulkStride(bulkVals) : PRIME64_5; - - h64 += (uint)buffer.Length; - - var ulongSpan = remainingBytes.PopAll(); - for (int i = 0; i < ulongSpan.Length; i++) - { - var val = ulongSpan[i] * PRIME64_2; - val = RotateLeft(val, 31); - val *= PRIME64_1; - h64 ^= val; - h64 = RotateLeft(h64, 27) * PRIME64_1; - h64 += PRIME64_4; - } - - ref byte remaining = ref MemoryMarshal.GetReference(remainingBytes); - if (remainingBytes.Length >= sizeof(uint)) - { - h64 ^= Unsafe.As(ref remaining) * PRIME64_1; - h64 = RotateLeft(h64, 23) * PRIME64_2; - h64 += PRIME64_3; - remaining = ref Unsafe.Add(ref remaining, sizeof(uint)); - } - - switch (remainingBytes.Length % sizeof(uint)) - { - case 3: - h64 = RotateLeft(h64 ^ remaining * PRIME64_5, 11) * PRIME64_1; - remaining = ref Unsafe.Add(ref remaining, 1); - goto case 2; - case 2: - h64 = RotateLeft(h64 ^ remaining * PRIME64_5, 11) * PRIME64_1; - remaining = ref Unsafe.Add(ref remaining, 1); - goto case 1; - case 1: - h64 = RotateLeft(h64 ^ remaining * PRIME64_5, 11) * PRIME64_1; - break; - } - - h64 ^= h64 >> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static ulong BulkStride(in ReadOnlySpan bulkVals) - { - unchecked - { - ulong acc1 = 0 + PRIME64_1 + PRIME64_2; - ulong acc2 = 0 + PRIME64_2; - ulong acc3 = 0 + 0; - ulong acc4 = 0 - PRIME64_1; - - for (int i = 0; i < bulkVals.Length; i++) - { - ref readonly QuadUlong val = ref bulkVals[i]; - - acc1 += val.v1 * PRIME64_2; - acc2 += val.v2 * PRIME64_2; - acc3 += val.v3 * PRIME64_2; - acc4 += val.v4 * PRIME64_2; - - acc1 = RotateLeft(acc1, 31); - acc2 = RotateLeft(acc2, 31); - acc3 = RotateLeft(acc3, 31); - acc4 = RotateLeft(acc4, 31); - - acc1 *= PRIME64_1; - acc2 *= PRIME64_1; - acc3 *= PRIME64_1; - acc4 *= PRIME64_1; - } - - return MergeValues(acc1, acc2, acc3, acc4); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong RotateLeft(ulong val, int bits) => (val << bits) | (val >> (64 - bits)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong MergeValues(ulong v1, ulong v2, ulong v3, ulong v4) - { - var acc = RotateLeft(v1, 1) + RotateLeft(v2, 7) + RotateLeft(v3, 12) + RotateLeft(v4, 18); - acc = MergeAccumulator(acc, v1); - acc = MergeAccumulator(acc, v2); - acc = MergeAccumulator(acc, v3); - acc = MergeAccumulator(acc, v4); - return acc; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong MergeAccumulator(ulong accMain, ulong accN) - { - accN = (accN * PRIME64_2); - accN = RotateLeft(accN, 31); - accN = accN * PRIME64_1; - accMain ^= accN; - accMain *= PRIME64_1; - return accMain + PRIME64_4; - } - } -} diff --git a/ZeroLevel/Services/Semantic/Helpers/TextAnalizer.cs b/ZeroLevel/Services/Semantic/Helpers/TextAnalizer.cs index cfefb13..a70f4b6 100644 --- a/ZeroLevel/Services/Semantic/Helpers/TextAnalizer.cs +++ b/ZeroLevel/Services/Semantic/Helpers/TextAnalizer.cs @@ -9,6 +9,8 @@ namespace ZeroLevel.Implementation.Semantic.Helpers { internal static readonly Regex ReWord = new Regex("\\b[\\wА-Яа-я-’]+\\b", RegexOptions.Compiled | RegexOptions.IgnoreCase); + internal static readonly Regex ReRuWord = new Regex("\\b[А-Яа-я-]+\\b", + RegexOptions.Compiled | RegexOptions.IgnoreCase); /// /// Highlighting words from text @@ -26,6 +28,17 @@ namespace ZeroLevel.Implementation.Semantic.Helpers return result; } + public static IEnumerable ExtractRuWords(string text) + { + var result = new List(); + foreach (Match match in ReRuWord.Matches(text)) + { + result.Add(match.Value); + } + + return result; + } + /// /// Highlighting unique words from text /// diff --git a/ZeroLevel/Services/Shedulling/AsyncShedullerImpl.cs b/ZeroLevel/Services/Shedulling/AsyncShedullerImpl.cs deleted file mode 100644 index d7475d2..0000000 --- a/ZeroLevel/Services/Shedulling/AsyncShedullerImpl.cs +++ /dev/null @@ -1,311 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Shedulling -{ - internal class AsyncShedullerImpl - : IAsyncSheduller - { - private readonly DateTimeAsyncSheduller _asyncSheduller; - - public AsyncShedullerImpl() - { - _asyncSheduller = new DateTimeAsyncSheduller(); - } - - #region One time events - - public long RemindAsyncAfter(TimeSpan timespan, Func callback) - { - return _asyncSheduller.Push(timespan, callback); - } - - public long RemindAsyncAt(DateTime date, Func callback) - { - return _asyncSheduller.Push(date, callback); - } - - #endregion One time events - - #region Repitable behaviour - - private readonly ConcurrentDictionary _repitableAsyncActions = new ConcurrentDictionary(); - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// Function to calculate the next period - /// Action - /// Task ID - public long RemindAsyncEveryNonlinearPeriod(Func nextEventPeriodCalcFunction, - Func callback, - bool breakWherError = false) - { - return RemindAsyncEveryNonlinearPeriod(nextEventPeriodCalcFunction, nextEventPeriodCalcFunction, callback, breakWherError); - } - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// The function to calculate the period to the first execution - /// The function for calculating the period until subsequent performances - /// Action - /// Task ID - public long RemindAsyncEveryNonlinearPeriod(Func firstEventPeriodCalcFunction, - Func nextEventPeriodCalcFunction, - Func callback, - bool breakWherError = false) - { - var obj = new ExpiredAsyncObject { ExpirationDate = DateTime.Now.AddMilliseconds(firstEventPeriodCalcFunction().TotalMilliseconds) }; - _repitableAsyncActions.TryAdd(obj.Key, obj); - obj.Callback = async (key) => - { - try - { - await callback(key); - } - catch (Exception ex) - { - Log.SystemError(ex, $"[Sheduller] Fault call async task '{key}' handler"); - if (breakWherError) - return; - } - ExpiredAsyncObject repObj; - if (_repitableAsyncActions.TryGetValue(obj.Key, out repObj)) - { - _asyncSheduller.Push(repObj.Reset(DateTime.Now.AddMilliseconds(nextEventPeriodCalcFunction().TotalMilliseconds))); - } - }; - return _asyncSheduller.Push(obj); - } - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the next date - /// Action - /// Task ID - public long RemindAsyncEveryNonlinearDate(Func nextEventDateCalcFunction, - Func callback, - bool breakWherError = false) - { - return RemindAsyncEveryNonlinearDate(nextEventDateCalcFunction, nextEventDateCalcFunction, callback, breakWherError); - } - - public long RemindAsyncEveryNonlinearDate(DateTime firstTime, - Func nextEventDateCalcFunction, - Func callback, - bool breakWherError = false) - { - var obj = new ExpiredAsyncObject { ExpirationDate = firstTime }; - _repitableAsyncActions.TryAdd(obj.Key, obj); - obj.Callback = async (key) => - { - try - { - await callback(key); - } - catch (Exception ex) - { - Log.SystemError(ex, $"[Sheduller] Fault call async task '{key}' handler"); - if (breakWherError) - return; - } - ExpiredAsyncObject repObj; - if (_repitableAsyncActions.TryGetValue(obj.Key, out repObj)) - { - var nextDate = nextEventDateCalcFunction(obj.ExpirationDate); - if (DateTime.Compare(nextDate, DateTime.MinValue) == 0) - { - Remove(repObj.Key); - } - else - { - _asyncSheduller.Push(repObj.Reset(nextDate)); - } - } - }; - return _asyncSheduller.Push(obj); - } - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the first run date - /// The function to calculate the next date - /// Action - /// Task ID - public long RemindAsyncEveryNonlinearDate(Func firstEventDateCalcFunction, - Func nextEventDateCalcFunction, - Func callback, - bool breakWherError = false) - { - var obj = new ExpiredAsyncObject { ExpirationDate = firstEventDateCalcFunction(DateTime.Now) }; - _repitableAsyncActions.TryAdd(obj.Key, obj); - obj.Callback = async (key) => - { - try - { - await callback(key); - } - catch (Exception ex) - { - Log.SystemError(ex, $"[Sheduller] Fault call async task '{key}' handler"); - if (breakWherError) - return; - } - ExpiredAsyncObject repObj; - if (_repitableAsyncActions.TryGetValue(obj.Key, out repObj)) - { - var nextDate = nextEventDateCalcFunction(obj.ExpirationDate); - if (DateTime.Compare(nextDate, DateTime.MinValue) == 0) - { - Remove(repObj.Key); - } - else - { - _asyncSheduller.Push(repObj.Reset(nextDate)); - } - } - }; - return _asyncSheduller.Push(obj); - } - - /// - /// Performs an action once in a specified period - /// - /// Period - /// Action - /// Task ID - public long RemindAsyncEvery(TimeSpan timespan, - Func callback, - bool breakWherError = false) - { - return RemindAsyncEvery(timespan, timespan, callback, breakWherError); - } - - /// - /// Performs an action once in a specified period - /// - /// Period to first run - /// Period - /// Action - /// Task ID - public long RemindAsyncEvery(TimeSpan first, - TimeSpan next, - Func callback, - bool breakWherError = false) - { - var obj = new ExpiredAsyncObject { ExpirationDate = DateTime.Now.AddMilliseconds(first.TotalMilliseconds) }; - _repitableAsyncActions.TryAdd(obj.Key, obj); - obj.Callback = async (key) => - { - try - { - await callback(key).ConfigureAwait(false); - } - catch (Exception ex) - { - Log.SystemError(ex, $"[Sheduller] Fault call async task '{key}' handler"); - if (breakWherError) - return; - } - ExpiredAsyncObject repObj; - if (_repitableAsyncActions.TryGetValue(obj.Key, out repObj)) - { - _asyncSheduller.Push(repObj.Reset(DateTime.Now.AddMilliseconds(next.TotalMilliseconds))); - } - }; - return _asyncSheduller.Push(obj); - } - - public long RemindAsyncWhile(TimeSpan period, - Func> callback, - Action continueWith = null, - bool breakWherError = false) - { - var obj = new ExpiredAsyncObject { ExpirationDate = DateTime.Now.AddMilliseconds(period.TotalMilliseconds) }; - _repitableAsyncActions.TryAdd(obj.Key, obj); - obj.Callback = async (key) => - { - bool success = false; - try - { - success = await callback(key); - } - catch (Exception ex) - { - Log.SystemError(ex, $"[Sheduller] Fault call async task '{key}' handler"); - if (breakWherError) - return; - } - if (success) - { - Remove(obj.Key); - if (continueWith != null) - continueWith(); - } - else - { - ExpiredAsyncObject repObj; - if (_repitableAsyncActions.TryGetValue(obj.Key, out repObj)) - { - _asyncSheduller.Push(repObj.Reset(DateTime.Now.AddMilliseconds(period.TotalMilliseconds))); - } - } - }; - return _asyncSheduller.Push(obj); - } - - #endregion Repitable behaviour - - #region Sheduller control - - public void Pause() - { - _asyncSheduller.Pause(); - } - - public void Resume() - { - _asyncSheduller.Resume(); - } - - public void Clean() - { - _asyncSheduller.Clean(); - } - - public bool Remove(long key) - { - var success = _asyncSheduller.Remove(key); - if (_repitableAsyncActions.ContainsKey(key)) - { - ExpiredAsyncObject rem; - return _repitableAsyncActions.TryRemove(key, out rem); - } - return success; - } - - #endregion Sheduller control - - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _asyncSheduller.Dispose(); - } - } - - #endregion IDisposable - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Shedulling/DateTimeAsyncSheduller.cs b/ZeroLevel/Services/Shedulling/DateTimeAsyncSheduller.cs deleted file mode 100644 index cd9e7d1..0000000 --- a/ZeroLevel/Services/Shedulling/DateTimeAsyncSheduller.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using ZeroLevel.Services.Async; - -namespace ZeroLevel.Services.Shedulling -{ - public class DateTimeAsyncSheduller - : IExpirationAsyncSheduller - { - private Timer _timer; - private ExpiredAsyncObject _head = null; - private AsyncLock _lock = new AsyncLock(); - private volatile bool _stopped = false; - - #region Ctor - - public DateTimeAsyncSheduller() - { - _timer = new Timer(TimerCallbackHandler, null, Timeout.Infinite, Timeout.Infinite); - } - - #endregion Ctor - - private void TimerCallbackHandler(object state) - { - // POP - ExpiredAsyncObject result = null; - if (null != _head) - { - if (DateTime.Compare(_head.ExpirationDate, DateTime.Now) > 0) - { - ResetTimer(); - return; - } - // SWAP - result = _head; - _head = _head.Next; - ResetTimer(); - } - if (result != null) - { - result.Callback(result.Key).ContinueWith(t => - { - if (t.IsFaulted) - { - Exception ex = t.Exception; - while (ex is AggregateException && ex.InnerException != null) - ex = ex.InnerException; - Log.SystemError(ex, "Fault task '{0}' on expiration date '{1:yyyy-MM-dd HH:mm:ss fff}'", result.Key, result.ExpirationDate); - } - }); - } - } - - internal long Push(ExpiredAsyncObject insert) - { - if (insert == null) - throw new ArgumentNullException(nameof(insert)); - using (_lock.Lock()) - { - if (null == _head) - { - _head = insert; - ResetTimer(); - } - else - { - var cursor = _head; - var reset = false; - if (cursor.Key == -1) // if system task for task with big interval (> 2^32 - 2 ms) - { - DisableTimer(); - _head = _head.Next; // remove system task from head - cursor = _head; - reset = true; - } - ExpiredAsyncObject prev = null; - do - { - if (DateTime.Compare(cursor.ExpirationDate, insert.ExpirationDate) > 0) - { - insert.Next = cursor; - if (null == prev) // insert to head - { - _head = insert; - ResetTimer(); - reset = false; - } - else - { - prev.Next = insert; - } - break; - } - prev = cursor; - cursor = cursor.Next; - if (cursor == null) - { - prev.Next = insert; - } - } while (cursor != null); - if (reset) - { - ResetTimer(); - } - } - } - return insert.Key; - } - - public bool Remove(long key) - { - using (_lock.Lock()) - { - if (_head != null) - { - ExpiredAsyncObject previous, current; - FindTaskByKeyWithPreviousTask(key, out previous, out current); - if (current != null) - { - if (_head.Key == current.Key) - { - _head = _head.Next; - ResetTimer(); - } - else - { - previous.Next = current.Next; - } - return true; - } - } - } - return false; - } - - #region API - - public long Push(TimeSpan timespan, Func callback) - { - return Push(new ExpiredAsyncObject { Callback = callback, ExpirationDate = DateTime.Now.AddMilliseconds(timespan.TotalMilliseconds) }); - } - - public long Push(DateTime date, Func callback) - { - return Push(new ExpiredAsyncObject { Callback = callback, ExpirationDate = date }); - } - - private void DisableTimer() - { - _timer.Change(Timeout.Infinite, Timeout.Infinite); - } - - public void Pause() - { - using (_lock.Lock()) - { - _stopped = true; - DisableTimer(); - } - } - - public void Resume() - { - using (_lock.Lock()) - { - _stopped = false; - ResetTimer(); - } - } - - public void Clean() - { - using (_lock.Lock()) - { - DisableTimer(); - _head = null; - } - } - - #endregion API - - #region Control - - private void FindTaskByKeyWithPreviousTask(long key, out ExpiredAsyncObject previous, out ExpiredAsyncObject current) - { - if (_head.Key == key) - { - previous = null; - current = _head; - return; - } - var cursor = _head.Next; - var prev = _head; - while (cursor != null) - { - if (cursor.Key == key) - { - previous = prev; - current = cursor; - return; - } - prev = cursor; - cursor = cursor.Next; - } - previous = null; - current = null; - return; - } - - private const uint _max_interval = 4294967294; - private static readonly TimeSpan _infinite = TimeSpan.FromMilliseconds(Timeout.Infinite); - - private void ResetTimer() - { - if (_timer != null) - { - if (null != _head && _stopped == false) - { - var diff = (_head.ExpirationDate - DateTime.Now); - if (diff.TotalMilliseconds > _max_interval) - { - var _big_interval_waiting_obj = new ExpiredAsyncObject(true) - { - ExpirationDate = DateTime.Now.AddMilliseconds(_max_interval), - Callback = (key) => - { - using (_lock.Lock()) - { - ResetTimer(); - _head = null; - } - return Task.CompletedTask; - }, - Next = _head - }; - _head = _big_interval_waiting_obj; - _timer.Change(_max_interval, Timeout.Infinite); - } - else - { - if (diff.Ticks < 0) - { - diff = TimeSpan.Zero; - } - _timer.Change(diff, _infinite); - } - } - else - { - DisableTimer(); - } - } - } - - #endregion Control - - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (_timer != null) - { - Clean(); - if (null != _timer) - { - _timer.Dispose(); - _timer = null; - } - } - } - } - - #endregion IDisposable - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Shedulling/ExpiredAsyncObject.cs b/ZeroLevel/Services/Shedulling/ExpiredAsyncObject.cs deleted file mode 100644 index 134d852..0000000 --- a/ZeroLevel/Services/Shedulling/ExpiredAsyncObject.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Shedulling -{ - internal class ExpiredAsyncObject - { - private static long _counter = 0; - - public ExpiredAsyncObject() - { - Key = Interlocked.Increment(ref _counter); - } - - public ExpiredAsyncObject(bool has_no_key) - { - if (has_no_key) - Key = -1; - else - Key = Interlocked.Increment(ref _counter); - } - - public ExpiredAsyncObject Reset(DateTime nextDate) - { - ExpirationDate = nextDate; - Next = null; - return this; - } - - /// - /// Action at the end of the wait - /// - public Func Callback; - - /// - /// Expiration Timeout - /// - public DateTime ExpirationDate; - - /// - /// Next object with the nearest waiting date - /// - public ExpiredAsyncObject Next; - - /// - /// Key to identify the pending event - /// - public long Key { get; } - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Shedulling/IAsyncSheduller.cs b/ZeroLevel/Services/Shedulling/IAsyncSheduller.cs deleted file mode 100644 index 69b84ba..0000000 --- a/ZeroLevel/Services/Shedulling/IAsyncSheduller.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Shedulling -{ - public interface IAsyncSheduller - : IDisposable - { - #region One time events - - long RemindAsyncAfter(TimeSpan timespan, Func callback); - - long RemindAsyncAt(DateTime date, Func callback); - - #endregion One time events - - #region Repitable behaviour - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// Function to calculate the next period - /// Action - /// Task ID - long RemindAsyncEveryNonlinearPeriod(Func nextEventPeriodCalcFunction, Func callback, - bool breakWherError = false); - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// The function to calculate the period to the first execution - /// The function for calculating the period until subsequent performances - /// Action - /// Task ID - long RemindAsyncEveryNonlinearPeriod(Func firstEventPeriodCalcFunction, - Func nextEventPeriodCalcFunction, Func callback, - bool breakWherError = false); - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the next date - /// Action - /// Task ID - long RemindAsyncEveryNonlinearDate(Func nextEventDateCalcFunction, Func callback, - bool breakWherError = false); - - long RemindAsyncEveryNonlinearDate(DateTime firstTime, Func nextEventDateCalcFunction, - Func callback, - bool breakWherError = false); - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the first run date - /// The function to calculate the next date - /// Action - /// Task ID - long RemindAsyncEveryNonlinearDate(Func firstEventDateCalcFunction, - Func nextEventDateCalcFunction, Func callback, - bool breakWherError = false); - - /// - /// Performs an action once in a specified period - /// - /// Period - /// Action - /// Task ID - long RemindAsyncEvery(TimeSpan timespan, Func callback, - bool breakWherError = false); - - /// - /// Performs an action once in a specified period - /// - /// Period to first run - /// Period - /// Action - /// Task ID - long RemindAsyncEvery(TimeSpan first, TimeSpan next, Func callback, - bool breakWherError = false); - - long RemindAsyncWhile(TimeSpan period, Func> callback, Action continueWith = null, - bool breakWherError = false); - - #endregion Repitable behaviour - - #region Sheduller control - - void Pause(); - - void Resume(); - - void Clean(); - - bool Remove(long key); - - #endregion Sheduller control - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Shedulling/IExpirationAsyncSheduller.cs b/ZeroLevel/Services/Shedulling/IExpirationAsyncSheduller.cs deleted file mode 100644 index e444c64..0000000 --- a/ZeroLevel/Services/Shedulling/IExpirationAsyncSheduller.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace ZeroLevel.Services.Shedulling -{ - public interface IExpirationAsyncSheduller : IDisposable - { - /// - /// Adding a task with the time after which it should be completed - /// - long Push(TimeSpan timespan, Func callback); - - /// - /// Adding a task with the date / time when it should be executed - /// - long Push(DateTime date, Func callback); - - /// - /// Delete task by ID - /// - /// Task ID - bool Remove(long key); - - /// - /// Cleaning the scheduler - /// - void Clean(); - - /// - /// Pausing the scheduler (does not prevent the addition of new tasks) - /// - void Pause(); - - /// - /// Resumption of work scheduler - /// - void Resume(); - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Shedulling/Sheduller.cs b/ZeroLevel/Services/Shedulling/Sheduller.cs index bcf9d78..76dc886 100644 --- a/ZeroLevel/Services/Shedulling/Sheduller.cs +++ b/ZeroLevel/Services/Shedulling/Sheduller.cs @@ -16,21 +16,11 @@ namespace ZeroLevel return new DateTimeSheduller(); } - public static IExpirationAsyncSheduller CreateAsyncExpirationSheduller() - { - return new DateTimeAsyncSheduller(); - } - public static ISheduller Create() { return new ShedullerImpl(); } - public static IAsyncSheduller CreateAsync() - { - return new AsyncShedullerImpl(); - } - #endregion Factory #region Singletones @@ -56,27 +46,6 @@ namespace ZeroLevel } } - private static IAsyncSheduller __async_instance; - private static readonly object _async_create_lock = new object(); - - private static IAsyncSheduller DefaultAsyncInstance - { - get - { - if (__async_instance == null) - { - lock (_async_create_lock) - { - if (__async_instance == null) - { - __async_instance = Sheduller.CreateAsync(); - } - } - } - return __async_instance; - } - } - #endregion Singletones #region Sync default instance api @@ -206,156 +175,25 @@ namespace ZeroLevel #endregion Sync default instance api - #region Async default instance api - - public static long RemindAsyncWhile(TimeSpan timespan, Func> callback, Action continueWith = null) - { - return DefaultAsyncInstance.RemindAsyncWhile(timespan, callback, continueWith); - } - - public static long RemindAsyncWhile(TimeSpan timespan, Func> callback, Action continueWith = null) - { - return DefaultAsyncInstance.RemindAsyncWhile(timespan, (k) => callback(), continueWith); - } - - public static long RemindAsyncAfter(TimeSpan timespan, Func callback) - { - return DefaultAsyncInstance.RemindAsyncAfter(timespan, callback); - } - - public static long RemindAsyncAfter(TimeSpan timespan, Func callback) - { - return DefaultAsyncInstance.RemindAsyncAfter(timespan, async k => await callback()); - } - - public static long RemindAsyncAt(DateTime date, Func callback) - { - return DefaultAsyncInstance.RemindAsyncAt(date, callback); - } - - public static long RemindAsyncAt(DateTime date, Func callback) - { - return DefaultAsyncInstance.RemindAsyncAt(date, async k => await callback()); - } - - public static long RemindAsyncEvery(TimeSpan first, TimeSpan next, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEvery(first, next, callback); - } - - public static long RemindAsyncEvery(TimeSpan first, TimeSpan next, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEvery(first, next, async k => await callback()); - } - - public static long RemindAsyncEvery(TimeSpan timespan, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEvery(timespan, callback); - } - - public static long RemindAsyncEvery(TimeSpan timespan, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEvery(timespan, async k => await callback()); - } - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// Function to calculate the next period - /// Action - /// Task ID - public static long RemindAsyncEveryNonlinearPeriod(Func nextEventPeriodCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearPeriod(nextEventPeriodCalcFunction, nextEventPeriodCalcFunction, callback); - } - - public static long RemindAsyncEveryNonlinearPeriod(Func nextEventPeriodCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearPeriod(nextEventPeriodCalcFunction, nextEventPeriodCalcFunction, async k => await callback()); - } - - /// - /// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task. - /// - /// The function to calculate the period to the first execution - /// The function for calculating the period until subsequent performances - /// Action - /// Task ID - public static long RemindAsyncEveryNonlinearPeriod(Func firstEventPeriodCalcFunction, Func nextEventPeriodCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearPeriod(firstEventPeriodCalcFunction, nextEventPeriodCalcFunction, callback); - } - - public static long RemindAsyncEveryNonlinearPeriod(Func firstEventPeriodCalcFunction, Func nextEventPeriodCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearPeriod(firstEventPeriodCalcFunction, nextEventPeriodCalcFunction, async k => await callback()); - } - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the next date - /// Action - /// Task ID - public static long RemindAsyncEveryNonlinearDate(Func nextEventDateCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearDate(nextEventDateCalcFunction, nextEventDateCalcFunction, callback); - } - - public static long RemindAsyncEveryNonlinearDate(Func nextEventDateCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearDate(nextEventDateCalcFunction, nextEventDateCalcFunction, async k => await callback()); - } - - /// - /// Performs an action once per period, while the date is recalculated from the function transferred each time the task is recreated. - /// - /// The function to calculate the first run date - /// The function to calculate the next date - /// Action - /// Task ID - public static long RemindAsyncEveryNonlinearDate(Func firstEventDateCalcFunction, - Func nextEventDateCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearDate(firstEventDateCalcFunction, nextEventDateCalcFunction, callback); - } - - public static long RemindAsyncEveryNonlinearDate(Func firstEventDateCalcFunction, - Func nextEventDateCalcFunction, Func callback) - { - return DefaultAsyncInstance.RemindAsyncEveryNonlinearDate(firstEventDateCalcFunction, nextEventDateCalcFunction, async k => await callback()); - } - - public static bool RemoveAsync(long key) - { - return DefaultAsyncInstance.Remove(key); - } - - #endregion Async default instance api - #region Default instances control public static void Pause() { DefaultInstance.Pause(); - DefaultAsyncInstance.Pause(); } public static void Resume() { DefaultInstance.Resume(); - DefaultAsyncInstance.Resume(); } public static void Clean() { DefaultInstance.Clean(); - DefaultAsyncInstance.Clean(); } public static void Dispose() { - DefaultAsyncInstance.Dispose(); DefaultInstance.Dispose(); } diff --git a/ZeroLevel/Services/Trees/DSA.cs b/ZeroLevel/Services/Trees/DSA.cs new file mode 100644 index 0000000..473689e --- /dev/null +++ b/ZeroLevel/Services/Trees/DSA.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using System.Text; +using System.Threading; +using ZeroLevel.Services.Serialization; + +namespace ZeroLevel.Services.Trees +{ + public class State + : IBinarySerializable + { + private bool _is_teminate; + private Dictionary _transtions; + + public State() + { + _is_teminate = false; + _transtions = new Dictionary(32); + } + + public bool Append(string word, int position) + { + if (word.Length == position) + { + if (_is_teminate) + { + return false; + } + _is_teminate = true; + return true; + } + State next; + if (_transtions.TryGetValue(word[position], out next) == false) + { + next = new State(); + _transtions[word[position]] = next; + } + return next.Append(word, position + 1); + } + + public bool Contains(string w, int position) + { + if (w.Length == position) return _is_teminate; + State next; + if (_transtions.TryGetValue(w[position], out next)) + { + return next.Contains(w, position + 1); + } + return false; + } + + public IEnumerable Iterator(StringBuilder sb) + { + if (_is_teminate) + { + yield return sb.ToString(); + } + foreach (var s in _transtions) + { + sb.Append(s.Key); + foreach (var t in s.Value.Iterator(sb)) + { + yield return t; + } + sb.Remove(sb.Length - 1, 1); + } + } + + public void Serialize(IBinaryWriter writer) + { + writer.WriteBoolean(this._is_teminate); + writer.WriteDictionary(this._transtions); + } + + public void Deserialize(IBinaryReader reader) + { + _transtions.Clear(); + this._is_teminate = reader.ReadBoolean(); + this._transtions = reader.ReadDictionary(); + } + } + + public class DSA + : IBinarySerializable + { + private State _initialState; + private long _count = 0; + + public long Count => _count; + + public DSA() + { + _initialState = new State(); + } + + public bool AppendWord(string word) + { + if (string.IsNullOrEmpty(word)) return false; + if (_initialState.Append(word, 0)) + { + Interlocked.Increment(ref _count); + return true; + } + return false; + } + + public bool Contains(string word) + { + return _initialState.Contains(word, 0); + } + + public void Deserialize(IBinaryReader reader) + { + this._count = reader.ReadLong(); + _initialState.Deserialize(reader); + } + + public void Serialize(IBinaryWriter writer) + { + writer.WriteLong(this._count); + _initialState.Serialize(writer); + } + + public IEnumerable Iterator() + { + return _initialState.Iterator(new StringBuilder()); + } + } +} diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj index 61cd51d..570bcfa 100644 --- a/ZeroLevel/ZeroLevel.csproj +++ b/ZeroLevel/ZeroLevel.csproj @@ -6,16 +6,16 @@ ogoun ogoun - 3.3.2.0 - BloomFilter, RabinKarp, KnuthMorrisPratt,BoyerMoore,LevenshteinDistance, DamerauLevenshteinDistance, XX3Hash + 3.3.3.0 + Refactoring https://github.com/ogoun/Zero/wiki Copyright Ogoun 2020 https://github.com/ogoun/Zero GitHub - 3.3.2 - 3.3.2.1 + 3.3.3 + 3.3.3.1 AnyCPU;x64 zero.png @@ -36,14 +36,6 @@ true - - - - - - - - True diff --git a/ZeroNetworkMonitor/App.config b/ZeroNetworkMonitor/App.config index 56efbc7..bae5d6d 100644 --- a/ZeroNetworkMonitor/App.config +++ b/ZeroNetworkMonitor/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/ZeroNetworkMonitor/Properties/Resources.Designer.cs b/ZeroNetworkMonitor/Properties/Resources.Designer.cs index 31e7cfb..54533d5 100644 --- a/ZeroNetworkMonitor/Properties/Resources.Designer.cs +++ b/ZeroNetworkMonitor/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace ZeroNetworkMonitor.Properties -{ - - +namespace ZeroNetworkMonitor.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace ZeroNetworkMonitor.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ZeroNetworkMonitor.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/ZeroNetworkMonitor/Properties/Settings.Designer.cs b/ZeroNetworkMonitor/Properties/Settings.Designer.cs index e24d018..400373f 100644 --- a/ZeroNetworkMonitor/Properties/Settings.Designer.cs +++ b/ZeroNetworkMonitor/Properties/Settings.Designer.cs @@ -8,21 +8,17 @@ // //------------------------------------------------------------------------------ -namespace ZeroNetworkMonitor.Properties -{ - - +namespace ZeroNetworkMonitor.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj b/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj index 959d837..ce8326f 100644 --- a/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj +++ b/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj @@ -8,12 +8,13 @@ WinExe ZeroNetworkMonitor ZeroNetworkMonitor - v4.7.2 + v4.6.1 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true true + AnyCPU @@ -34,6 +35,28 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true +