From 44b02d6d0f85b8ed9e500cb4bb5bf95d4b70a9f4 Mon Sep 17 00:00:00 2001 From: Rene Schwarzer Date: Sun, 7 Jul 2024 14:54:06 +0200 Subject: [PATCH 01/23] bug fixes --- README.md | 33 +++++++++---------- .../Storage/IndexStorageDocumentStore.cs | 5 +++ .../IndexDefaultSearchAttribute.cs | 12 +++++++ .../WebExpress.WebIndex.csproj | 6 ++-- 4 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 src/WebExpress.WebIndex/WebAttribute/IndexDefaultSearchAttribute.cs diff --git a/README.md b/README.md index ed7e1a6..077b2c1 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,40 @@ -![WebExpress](https://raw.githubusercontent.com/ReneSchwarzer/WebExpress.Doc/main/assets/banner.png) +![WebExpress](https://raw.githubusercontent.com/ReneSchwarzer/WebExpress/main/assets/banner.png) # WebExpress -WebExpress is a lightweight web server optimized for use in low-performance environments (e.g. Rasperry PI). By providing +`WebExpress` is a lightweight web server optimized for use in low-performance environments (e.g. Rasperry PI). By providing a powerful plugin system and a comprehensive API, web applications can be easily and quickly integrated into a .net -language (e.g. C#). Some advantages of WebExpress are: +language (e.g. C#). Some advantages of `WebExpress` are: - It is easy to use. - It offers a variety of features and tools that can help you build and manage your website. - It is fast and efficient and can help you save time and money. - It is flexible and can be customized to meet your specific requirements. -The WebExpress family includes the following projects: +The `WebExpress` family includes the following projects: -- [WebExpress](https://github.com/ReneSchwarzer/WebExpress#readme) - The web server for WebExpress applications and the documentation. -- [WebExpress.WebCore](https://github.com/ReneSchwarzer/WebExpress.WebCore#readme) - The core for WebExpress applications. -- [WebExpress.WebUI](https://github.com/ReneSchwarzer/WebExpress.WebUI#readme) - Common templates and controls for WebExpress applications. -- [WebExpress.WebIndex](https://github.com/ReneSchwarzer/WebExpress.WebIndex#readme) - Reverse index for WebExpress applications. -- [WebExpress.WebApp](https://github.com/ReneSchwarzer/WebExpress.WebApp#readme) - Business application template for WebExpress applications. +- [WebExpress](https://github.com/ReneSchwarzer/WebExpress#readme) - The web server for `WebExpress` applications and the documentation. +- [WebExpress.WebCore](https://github.com/ReneSchwarzer/WebExpress.WebCore#readme) - The core for `WebExpress` applications. +- [WebExpress.WebUI](https://github.com/ReneSchwarzer/WebExpress.WebUI#readme) - Common templates and controls for `WebExpress` applications. +- [WebExpress.WebIndex](https://github.com/ReneSchwarzer/WebExpress.WebIndex#readme) - Reverse index for `WebExpress` applications. +- [WebExpress.WebApp](https://github.com/ReneSchwarzer/WebExpress.WebApp#readme) - Business application template for `WebExpress` applications. # WebExpress.WebIndex -WebExpress.WebIndex is part of the WebExpress family. The project provides a reverse index -to enable a quick and efficient search for data. The index can be filtered using the -wql (webexpress query language). Even though the reverse index is part of the WebExpress -family, it can also be used in other projects (outside of WebExpress). -For detailed information about WebIndex, see [concept](https://github.com/ReneSchwarzer/WebExpress.WebIndex/blob/main/doc/concept.md). +`WebExpress.WebIndex` is part of the WebExpress family. The project provides a reverse index to enable a quick and efficient search for data. The index can be filtered using the wql (webexpress query language). Even though the reverse index is part of the `WebExpress` family, it can also be used in other projects (outside of `WebExpress`). For detailed information about `WebIndex`, see [concept](https://github.com/ReneSchwarzer/WebExpress.WebIndex/blob/main/doc/concept.md). # Download The current binaries are available for download [here](https://github.com/ReneSchwarzer/WebExpress/releases). # Start -To get started with WebExpress, use the following links and tutorials. +If you're looking to get started with `WebExpress`, we would recommend using the following documentation. It can help you understand the platform. - [installation guide](https://github.com/ReneSchwarzer/WebExpress/blob/main/doc/installation_guide.md) - [development guide](https://github.com/ReneSchwarzer/WebExpress/blob/main/doc/development_guide.md) -## Tutorials +# Learning +The following tutorials illustrate the essential techniques of `WebExpress`. These tutorials are designed to assist you, as a developer, in understanding the various aspects of `WebExpress`. Each tutorial provides a detailed, step-by-step guide that you can work through using an example. If youre interested in beginning the development of `WebExpress` components, we would recommend you to complete some of these tutorials. + - [HelloWorld](https://github.com/ReneSchwarzer/WebExpress.Tutorial.HelloWorld#readme) +- [WebApp](https://github.com/ReneSchwarzer/WebExpress.Tutorial.WebApp#readme) # Tags -#WebExpress #ReverseIndex \ No newline at end of file +#WebIndex #WebExpress #ReverseIndex #DotNet #NETCore \ No newline at end of file diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs index a00d516..bd7d786 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs @@ -236,6 +236,11 @@ public T GetItem(Guid id) /// The item. private T GetItem(IndexStorageSegmentItem segment) { + if (segment == null) + { + return default; + } + var bytes = new List(); var addr = segment.NextChunkAddr; diff --git a/src/WebExpress.WebIndex/WebAttribute/IndexDefaultSearchAttribute.cs b/src/WebExpress.WebIndex/WebAttribute/IndexDefaultSearchAttribute.cs new file mode 100644 index 0000000..a35c233 --- /dev/null +++ b/src/WebExpress.WebIndex/WebAttribute/IndexDefaultSearchAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace WebExpress.WebIndex.WebAttribute +{ + /// + /// Indicates that a property is the default search attribute. + /// + [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] + public class IndexDefaultSearchAttribute : Attribute, IIndexAttribute + { + } +} diff --git a/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj b/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj index c789e0d..2362d82 100644 --- a/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj +++ b/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj @@ -3,8 +3,8 @@ Library WebExpress.WebIndex - 0.0.7.0 - 0.0.7.0 + 0.0.8.0 + 0.0.8.0 net8.0 any https://github.com/ReneSchwarzer/WebExpress.WebIndex @@ -14,7 +14,7 @@ true True Provide a reverse index for the WebExpress web server. - 0.0.7-alpha + 0.0.8-alpha https://github.com/ReneSchwarzer/WebExpress icon.png README.md From 416e6aa379cd721a242df3cb4c1b0ad208c77a1a Mon Sep 17 00:00:00 2001 From: Rene Schwarzer Date: Tue, 9 Jul 2024 21:22:50 +0200 Subject: [PATCH 02/23] add filter for surrogate character --- .../UnitTestReverseIndexStorageA.cs | 31 ++++++++++- ...nitTestIndexPipeStageSurrogateCharacter.cs | 53 +++++++++++++++++++ .../Term/IndexTokenAnalyzer.cs | 3 +- .../IndexPipeStageFilterSurrogateCharacter.cs | 49 +++++++++++++++++ src/WebExpress.WebIndex/Wql/WqlParser.cs | 5 ++ 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs create mode 100644 src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageA.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageA.cs index fdefe6b..2674576 100644 --- a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageA.cs +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageA.cs @@ -1,6 +1,5 @@ using System.Globalization; using System.Reflection; -using WebExpress.WebIndex.Memory; using WebExpress.WebIndex.Storage; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Test.Fixture; @@ -62,6 +61,36 @@ public void Add() Postconditions(); } + /// + /// Adds items with surrogate character to a reverse index. + /// + [Fact] + public void AddSurrogate() + { + // preconditions + Preconditions(); + var reverseIndex = new IndexStorageReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + reverseIndex.Clear(); + + var chars = new char[] { '\uD800', '\uDC00' }; // this is a surrogate pair + + var item = new UnitTestIndexTestDocumentA() + { + Id = Guid.NewGuid(), + Text = $"abc{new string(chars)}def" + }; + + // test execution + reverseIndex.Add(item); + + Assert.Empty(reverseIndex.All); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + /// /// Adds a token to an existing entry in the reverse index. /// diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs new file mode 100644 index 0000000..0552540 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs @@ -0,0 +1,53 @@ +using System.Globalization; +using WebExpress.WebIndex.Term; +using WebExpress.WebIndex.Term.Pipeline; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.Token +{ + public class UnitTestIndexPipeStageSurrogateCharacter : IClassFixture + { + /// + /// Returns the log. + /// + public ITestOutputHelper Output { get; private set; } + + /// + /// Returns the test context. + /// + protected UnitTestIndexFixtureToken Fixture { get; set; } + + /// + /// Constructor + /// + /// The test context. + /// The log. + public UnitTestIndexPipeStageSurrogateCharacter(UnitTestIndexFixtureToken fixture, ITestOutputHelper output) + { + Fixture = fixture; + Output = output; + } + + /// + /// Tests the surrogate character method. This function is part of the stemming process and removes words with surrogate characters. + /// + [Fact] + public void Surrogate() + { + var culture = CultureInfo.GetCultureInfo("en"); + var pipeStage = new IndexPipeStageFilterSurrogateCharacter(Fixture.Context); + + var chars = new char[] { '\uD800', '\uDC00' }; // this is a surrogate pair + var token = IndexTermTokenizer.Tokenize($"a surrogate pair like this '{new string(chars)}' must be removed.", culture); + + var res = pipeStage.Process(token, culture) + .Select(x => x.Value) + .ToList(); + + Assert.DoesNotContain(new string(chars), res); + + Assert.True(token.Count() - 1 == res.Count); + } + } +} diff --git a/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs b/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs index e12074d..fe6269b 100644 --- a/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs +++ b/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs @@ -23,7 +23,7 @@ public sealed class IndexTokenAnalyzer : IDisposable /// specific task, such as stemming, lemmatization, or stopword filtering. The data is sequentially passed through each 'PipeStage', /// with each stage applying its specific processing to the data. /// - private List TextProcessingPipeline { get; } = new List(); + private List TextProcessingPipeline { get; } = []; /// /// Constructor @@ -89,6 +89,7 @@ private void Initialization() Register(new IndexPipeStageConverterSingular(Context)); Register(new IndexPipeStageConverterSynonym(Context)); Register(new IndexPipeStageFilterEmpty(Context)); + Register(new IndexPipeStageFilterSurrogateCharacter(Context)); Register(new IndexPipeStageFilterStopWord(Context)); } diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs new file mode 100644 index 0000000..cfdcd3c --- /dev/null +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace WebExpress.WebIndex.Term.Pipeline +{ + /// + /// Removes surrogate characters. + /// + public class IndexPipeStageFilterSurrogateCharacter : IIndexPipeStage + { + /// + /// Returns the name of the process state. + /// + public string Name => "SurrogateCharacter"; + + /// + /// Constructor + /// + /// The reference to the context. + public IndexPipeStageFilterSurrogateCharacter(IIndexContext context) + { + } + + /// + /// Filters specific elements on the term enumeration. + /// + /// The terms. + /// The culture. + /// The filtered term enumeration. + public IEnumerable Process(IEnumerable input, CultureInfo culture) + { + foreach (var token in input) + { + if (token.Value is string) + { + if (!token.Value.ToString().Where(x => char.IsSurrogate(x)).Any()) + { + yield return token; + } + } + else + { + yield return token; + } + } + } + } +} diff --git a/src/WebExpress.WebIndex/Wql/WqlParser.cs b/src/WebExpress.WebIndex/Wql/WqlParser.cs index ff786f2..6a3d770 100644 --- a/src/WebExpress.WebIndex/Wql/WqlParser.cs +++ b/src/WebExpress.WebIndex/Wql/WqlParser.cs @@ -123,6 +123,11 @@ public IWqlStatement Parse(string input) IndexDocument = IndexDocument }; + if (input == null) + { + return wql; + } + try { var tokens = Tokenize(input); From 85ab6f9ebbfc4377a8092db7fdef8e597bc5845b Mon Sep 17 00:00:00 2001 From: Rene Schwarzer Date: Tue, 7 Jan 2025 19:04:11 +0100 Subject: [PATCH 03/23] feat: migrate project to .NET 9.0 --- .../DocumentStore/UnitTestDocumentStoreMemoryA.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreMemoryB.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreMemoryC.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreMemoryD.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreMemoryE.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreStorageA.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreStorageB.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreStorageC.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreStorageD.cs | 2 +- .../DocumentStore/UnitTestDocumentStoreStorageE.cs | 2 +- .../Fixture/UnitTestIndexFixtureIndexA.cs | 2 +- .../Fixture/UnitTestIndexFixtureIndexB.cs | 2 +- .../Fixture/UnitTestIndexFixtureIndexC.cs | 2 +- .../Fixture/UnitTestIndexFixtureIndexD.cs | 2 +- .../Fixture/UnitTestIndexFixtureIndexE.cs | 2 +- .../Fixture/UnitTestIndexFixtureToken.cs | 2 +- .../Fixture/UnitTestIndexFixtureWqlA.cs | 2 +- .../Fixture/UnitTestIndexFixtureWqlB.cs | 2 +- .../Fixture/UnitTestIndexFixtureWqlC.cs | 2 +- .../Fixture/UnitTestIndexFixtureWqlD.cs | 2 +- .../Fixture/UnitTestIndexFixtureWqlE.cs | 2 +- .../IndexManager/UnitTestIndexManagerMemoryA.cs | 2 +- .../IndexManager/UnitTestIndexManagerMemoryB.cs | 2 +- .../IndexManager/UnitTestIndexManagerMemoryC.cs | 2 +- .../IndexManager/UnitTestIndexManagerMemoryD.cs | 2 +- .../IndexManager/UnitTestIndexManagerMemoryE.cs | 2 +- .../IndexManager/UnitTestIndexManagerStorageA.cs | 2 +- .../IndexManager/UnitTestIndexManagerStorageB.cs | 2 +- .../IndexManager/UnitTestIndexManagerStorageD.cs | 2 +- .../IndexManager/UnitTestIndexManagerStorageE.cs | 2 +- src/WebExpress.WebIndex.Test/IndexManagerTest.cs | 2 +- .../Token/UnitTestIndexAnalyze.cs | 2 +- .../Token/UnitTestIndexAnalyzeNumber.cs | 2 +- .../Token/UnitTestIndexPipeStageEmpty.cs | 2 +- .../Token/UnitTestIndexPipeStageLowerCase.cs | 2 +- .../Token/UnitTestIndexPipeStageMisspelled.cs | 2 +- .../Token/UnitTestIndexPipeStageNormalizer.cs | 2 +- .../Token/UnitTestIndexPipeStageSingular.cs | 2 +- .../Token/UnitTestIndexPipeStageStopWord.cs | 2 +- .../Token/UnitTestIndexPipeStageSurrogateCharacter.cs | 2 +- .../Token/UnitTestIndexPipeStageSynonym.cs | 2 +- .../Token/UnitTestIndexPipeStageTrim.cs | 2 +- .../WQL/UnitTestWqlSearchFuzzyA.cs | 8 ++++---- .../WebExpress.WebIndex.Test.csproj | 8 ++++---- src/WebExpress.WebIndex.Wi/ArgumentParser.cs | 2 +- src/WebExpress.WebIndex.Wi/IndexManager.cs | 2 +- src/WebExpress.WebIndex.Wi/WebExpress.WebIndex.Wi.csproj | 2 +- src/WebExpress.WebIndex/IndexDocument.cs | 2 +- src/WebExpress.WebIndex/IndexDocumentContext.cs | 4 ++-- src/WebExpress.WebIndex/IndexManager.cs | 2 +- src/WebExpress.WebIndex/IndexRetrieveOptions.cs | 4 ++-- .../Memory/IndexMemoryDocumentStore.cs | 2 +- .../Memory/IndexMemoryReversePosting.cs | 2 +- src/WebExpress.WebIndex/Memory/IndexMemoryReverseTerm.cs | 4 ++-- src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs | 2 +- src/WebExpress.WebIndex/Storage/IndexStorageBufferItem.cs | 2 +- .../Storage/IndexStorageDocumentStore.cs | 2 +- src/WebExpress.WebIndex/Storage/IndexStorageFile.cs | 2 +- src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs | 2 +- src/WebExpress.WebIndex/Storage/IndexStorageSegment.cs | 2 +- .../Storage/IndexStorageSegmentAllocator.cs | 2 +- .../Storage/IndexStorageSegmentAllocatorDocumentStore.cs | 2 +- .../Storage/IndexStorageSegmentAllocatorReverseIndex.cs | 2 +- .../Storage/IndexStorageSegmentFree.cs | 4 ++-- .../Storage/IndexStorageSegmentHashMap.cs | 2 +- .../Storage/IndexStorageSegmentHeader.cs | 2 +- .../Storage/IndexStorageSegmentIChunk.cs | 2 +- .../Storage/IndexStorageSegmentItem.cs | 2 +- .../Storage/IndexStorageSegmentPosition.cs | 2 +- .../Storage/IndexStorageSegmentStatistic.cs | 2 +- src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs | 2 +- .../Term/Pipeline/IndexPipeStageConverterLowerCase.cs | 2 +- .../Term/Pipeline/IndexPipeStageConverterMisspelled.cs | 2 +- .../Term/Pipeline/IndexPipeStageConverterNormalizer.cs | 2 +- .../Term/Pipeline/IndexPipeStageConverterTrim.cs | 2 +- .../Term/Pipeline/IndexPipeStageFilterStopWord.cs | 2 +- .../Pipeline/IndexPipeStageFilterSurrogateCharacter.cs | 2 +- src/WebExpress.WebIndex/WebExpress.WebIndex.csproj | 2 +- .../Wql/Condition/WqlExpressionNodeFilterCondition.cs | 2 +- .../WqlExpressionNodeFilterConditionBinaryEqual.cs | 2 +- .../WqlExpressionNodeFilterConditionBinaryGreaterThan.cs | 2 +- ...pressionNodeFilterConditionBinaryGreaterThanOrEqual.cs | 2 +- .../WqlExpressionNodeFilterConditionBinaryLessThan.cs | 2 +- ...lExpressionNodeFilterConditionBinaryLessThanOrEqual.cs | 2 +- .../WqlExpressionNodeFilterConditionBinaryLike.cs | 2 +- .../Wql/Condition/WqlExpressionNodeFilterConditionSet.cs | 2 +- .../Condition/WqlExpressionNodeFilterConditionSetIn.cs | 2 +- .../Condition/WqlExpressionNodeFilterConditionSetNotIn.cs | 2 +- .../Wql/Function/WqlExpressionNodeFilterFunction.cs | 2 +- .../Wql/Function/WqlExpressionNodeFilterFunctionDay.cs | 2 +- .../Wql/Function/WqlExpressionNodeFilterFunctionNow.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionError.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionNodeAttribute.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilter.cs | 2 +- .../Wql/WqlExpressionNodeFilterBinary.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrder.cs | 2 +- .../Wql/WqlExpressionNodeOrderAttribute.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameter.cs | 2 +- .../Wql/WqlExpressionNodeParameterOption.cs | 2 +- .../Wql/WqlExpressionNodePartitioning.cs | 2 +- .../Wql/WqlExpressionNodePartitioningFunction.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlExpressionNodeValue.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlParseException.cs | 2 +- src/WebExpress.WebIndex/Wql/WqlParser.cs | 4 ++-- src/WebExpress.WebIndex/Wql/WqlStatement.cs | 2 +- 105 files changed, 116 insertions(+), 116 deletions(-) diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryA.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryA.cs index dc764e5..cb8d344 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryA.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryA.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreMemoryA : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryB.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryB.cs index 0aeba15..c47f868 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryB.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryB.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreMemoryB : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryC.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryC.cs index 945d6f5..bda770a 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryC.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryC.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreMemoryC : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryD.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryD.cs index 9d93fd3..7732497 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryD.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryD.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreMemoryD : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryE.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryE.cs index f276d1a..0a687e3 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryE.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryE.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreMemoryE : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageA.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageA.cs index 4ebbc72..a56d086 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageA.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageA.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreStorageA : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageB.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageB.cs index a96a899..2af4a06 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageB.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageB.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreStorageB : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageC.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageC.cs index f840faf..35312b1 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageC.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageC.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreStorageC : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageD.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageD.cs index 7255c2d..ad90d72 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageD.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageD.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreStorageD : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs index 72c1025..c02dd91 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.DocumentStore public class UnitTestDocumentStoreStorageE : UnitTestDocumentStore { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexA.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexA.cs index 76cc793..b15fefd 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexA.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexA.cs @@ -15,7 +15,7 @@ public class UnitTestIndexFixtureIndexA : UnitTestIndexFixture public UnitTestIndexTestDocumentA RandomItem => TestData[Rand.Next(TestData.Count)]; /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureIndexA() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexB.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexB.cs index 346266c..223857b 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexB.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexB.cs @@ -15,7 +15,7 @@ public class UnitTestIndexFixtureIndexB : UnitTestIndexFixture public UnitTestIndexTestDocumentB RandomItem => TestData[Rand.Next(TestData.Count)]; /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureIndexB() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexC.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexC.cs index 8e00ce3..b961d2f 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexC.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexC.cs @@ -16,7 +16,7 @@ public class UnitTestIndexFixtureIndexC : UnitTestIndexFixture public UnitTestIndexTestDocumentC RandomItem => TestData[Rand.Next(TestData.Count)]; /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureIndexC() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexD.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexD.cs index 39d388d..f4cca7a 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexD.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexD.cs @@ -15,7 +15,7 @@ public class UnitTestIndexFixtureIndexD : UnitTestIndexFixture public UnitTestIndexTestDocumentD RandomItem => TestData[Rand.Next(TestData.Count)]; /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureIndexD() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexE.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexE.cs index aa6c7aa..97aadcd 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexE.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexE.cs @@ -15,7 +15,7 @@ public class UnitTestIndexFixtureIndexE : UnitTestIndexFixture public UnitTestIndexTestDocumentE RandomItem => TestData[Rand.Next(TestData.Count)]; /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureIndexE() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureToken.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureToken.cs index e48f5dd..34be730 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureToken.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureToken.cs @@ -19,7 +19,7 @@ public class UnitTestIndexFixtureToken : UnitTestIndexFixture public IndexTokenAnalyzer TokenAnalyzer { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureToken() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs index 569f306..c76aac0 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs @@ -17,7 +17,7 @@ public class UnitTestIndexFixtureWqlA : UnitTestIndexFixture public IEnumerable TestData { get; } = UnitTestIndexTestDocumentFactoryA.GenerateTestData(); /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureWqlA() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs index 154342d..ac7a206 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs @@ -17,7 +17,7 @@ public class UnitTestIndexFixtureWqlB : UnitTestIndexFixture public IEnumerable TestData { get; } = UnitTestIndexTestDocumentFactoryB.GenerateTestData(); /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureWqlB() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs index f632788..6c9f1f0 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs @@ -27,7 +27,7 @@ public class UnitTestIndexFixtureWqlC : UnitTestIndexFixture public string Term { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureWqlC() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs index 1073f0a..8498115 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs @@ -17,7 +17,7 @@ public class UnitTestIndexFixtureWqlD : UnitTestIndexFixture public IEnumerable TestData { get; } = UnitTestIndexTestDocumentFactoryD.GenerateTestData(); /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureWqlD() { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs index 3c7ecb6..0186a09 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs @@ -17,7 +17,7 @@ public class UnitTestIndexFixtureWqlE : UnitTestIndexFixture public IEnumerable TestData { get; } = UnitTestIndexTestDocumentFactoryE.GenerateTestData(); /// - /// Constructor + /// Initializes a new instance of the class. /// public UnitTestIndexFixtureWqlE() { diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs index 2b1cce0..0cef8e1 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerMemoryA : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs index a4983bb..5b29cee 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerMemoryB : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs index 243acde..0599758 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs @@ -12,7 +12,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerMemoryC : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs index 60353c9..1111e81 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerMemoryD : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs index 7175806..d9a65fb 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerMemoryE : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs index 3534465..f6820fc 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerStorageA : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs index eca873f..acf6b4c 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerStorageB : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs index ead6943..f1e3b93 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerStorageD : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs index 9757d5e..b1a77b0 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs @@ -11,7 +11,7 @@ namespace WebExpress.WebIndex.Test.IndexManager public class UnitTestIndexManagerStorageE : UnitTestIndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The log. /// The test context. diff --git a/src/WebExpress.WebIndex.Test/IndexManagerTest.cs b/src/WebExpress.WebIndex.Test/IndexManagerTest.cs index ac7a569..a7488df 100644 --- a/src/WebExpress.WebIndex.Test/IndexManagerTest.cs +++ b/src/WebExpress.WebIndex.Test/IndexManagerTest.cs @@ -3,7 +3,7 @@ internal class IndexManagerTest : WebIndex.IndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// public IndexManagerTest() { diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs index cce07e8..0af4e74 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs @@ -17,7 +17,7 @@ public class UnitTestIndexAnalyze : IClassFixture protected UnitTestIndexFixtureToken Fixture { get; set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyzeNumber.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyzeNumber.cs index 58724e5..3b51a26 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyzeNumber.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyzeNumber.cs @@ -17,7 +17,7 @@ public class UnitTestIndexAnalyzeNumber : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageEmpty.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageEmpty.cs index df8cc54..a488845 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageEmpty.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageEmpty.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageEmpty : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageLowerCase.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageLowerCase.cs index a8e1030..5238a32 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageLowerCase.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageLowerCase.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageLowerCase : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageMisspelled.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageMisspelled.cs index 747e634..76a20ef 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageMisspelled.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageMisspelled.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageMisspelled : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageNormalizer.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageNormalizer.cs index 5139428..cee60ce 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageNormalizer.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageNormalizer.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageNormalizer : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSingular.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSingular.cs index d988514..b612e46 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSingular.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSingular.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageSingular : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs index 1cd9162..59ad4ce 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageStopWord : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs index 0552540..3a7835e 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSurrogateCharacter.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageSurrogateCharacter : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSynonym.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSynonym.cs index dffcd30..5d64783 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSynonym.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageSynonym.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageSynonym : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageTrim.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageTrim.cs index 779141c..8478d45 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageTrim.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageTrim.cs @@ -19,7 +19,7 @@ public class UnitTestIndexPipeStageTrim : IClassFixture - /// Constructor + /// Initializes a new instance of the class. /// /// The test context. /// The log. diff --git a/src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchFuzzyA.cs b/src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchFuzzyA.cs index c4a4183..567e01e 100644 --- a/src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchFuzzyA.cs +++ b/src/WebExpress.WebIndex.Test/WQL/UnitTestWqlSearchFuzzyA.cs @@ -120,8 +120,8 @@ public void Fuzzy() Assert.NotNull(res); Assert.NotNull(item); - Assert.Equal(3, res.Count()); - Assert.Equal("Text = 'Hel' ~50", wql.ToString()); + Assert.Equal(4, res.Count()); + Assert.Equal("Text ~ 'Helena' ~50", wql.ToString()); Assert.NotNull(wql.Filter); Assert.Null(wql.Order); Assert.Null(wql.Partitioning); @@ -140,8 +140,8 @@ public void FuzzyFromQueryable() Assert.NotNull(res); Assert.NotNull(item); - Assert.Equal(3, res.Count()); - Assert.Equal("Text = 'Hel~' ~50", wql.ToString()); + Assert.Equal(6, res.Count()); + Assert.Equal("Text ~ 'Hel' ~50", wql.ToString()); Assert.NotNull(wql.Filter); Assert.Null(wql.Order); Assert.Null(wql.Partitioning); diff --git a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj index 1ad76b3..3daa2ff 100644 --- a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj +++ b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable false true @@ -23,9 +23,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/WebExpress.WebIndex.Wi/ArgumentParser.cs b/src/WebExpress.WebIndex.Wi/ArgumentParser.cs index eb112f7..373106b 100644 --- a/src/WebExpress.WebIndex.Wi/ArgumentParser.cs +++ b/src/WebExpress.WebIndex.Wi/ArgumentParser.cs @@ -32,7 +32,7 @@ public static ArgumentParser Current } /// - /// Constructor + /// Initializes a new instance of the class. /// public ArgumentParser() { diff --git a/src/WebExpress.WebIndex.Wi/IndexManager.cs b/src/WebExpress.WebIndex.Wi/IndexManager.cs index 70505ad..be20028 100644 --- a/src/WebExpress.WebIndex.Wi/IndexManager.cs +++ b/src/WebExpress.WebIndex.Wi/IndexManager.cs @@ -9,7 +9,7 @@ namespace WebExpress.WebIndex.Wi internal class IndexManager : WebIndex.IndexManager { /// - /// Constructor + /// Initializes a new instance of the class. /// public IndexManager() { diff --git a/src/WebExpress.WebIndex.Wi/WebExpress.WebIndex.Wi.csproj b/src/WebExpress.WebIndex.Wi/WebExpress.WebIndex.Wi.csproj index 702a8d9..5f9ef57 100644 --- a/src/WebExpress.WebIndex.Wi/WebExpress.WebIndex.Wi.csproj +++ b/src/WebExpress.WebIndex.Wi/WebExpress.WebIndex.Wi.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable disable WiApp diff --git a/src/WebExpress.WebIndex/IndexDocument.cs b/src/WebExpress.WebIndex/IndexDocument.cs index 9c60ec5..1c6625f 100644 --- a/src/WebExpress.WebIndex/IndexDocument.cs +++ b/src/WebExpress.WebIndex/IndexDocument.cs @@ -58,7 +58,7 @@ public class IndexDocument : Dictionary>, IInd public IEnumerable All => DocumentStore.All; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The index context. /// The index type. diff --git a/src/WebExpress.WebIndex/IndexDocumentContext.cs b/src/WebExpress.WebIndex/IndexDocumentContext.cs index 5a8c2ef..8191aea 100644 --- a/src/WebExpress.WebIndex/IndexDocumentContext.cs +++ b/src/WebExpress.WebIndex/IndexDocumentContext.cs @@ -13,14 +13,14 @@ public class IndexDocumemntContext : IndexContext, IIndexDocumemntContext public IndexTokenAnalyzer TokenAnalyzer { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// public IndexDocumemntContext() { } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The base context. /// The tike analyzer. diff --git a/src/WebExpress.WebIndex/IndexManager.cs b/src/WebExpress.WebIndex/IndexManager.cs index 4055820..eb079f3 100644 --- a/src/WebExpress.WebIndex/IndexManager.cs +++ b/src/WebExpress.WebIndex/IndexManager.cs @@ -37,7 +37,7 @@ public abstract class IndexManager : IDisposable protected IndexTokenAnalyzer TokenAnalyzer { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// public IndexManager() { diff --git a/src/WebExpress.WebIndex/IndexRetrieveOptions.cs b/src/WebExpress.WebIndex/IndexRetrieveOptions.cs index 9fe6ef2..5d28421 100644 --- a/src/WebExpress.WebIndex/IndexRetrieveOptions.cs +++ b/src/WebExpress.WebIndex/IndexRetrieveOptions.cs @@ -21,14 +21,14 @@ public struct IndexRetrieveOptions public uint Distance { get; internal set; } = 0; /// - /// Constructor + /// Initializes a new instance of the class. /// public IndexRetrieveOptions() { } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The maximum results. public IndexRetrieveOptions(uint maxResults) diff --git a/src/WebExpress.WebIndex/Memory/IndexMemoryDocumentStore.cs b/src/WebExpress.WebIndex/Memory/IndexMemoryDocumentStore.cs index 381fd51..6a53f04 100644 --- a/src/WebExpress.WebIndex/Memory/IndexMemoryDocumentStore.cs +++ b/src/WebExpress.WebIndex/Memory/IndexMemoryDocumentStore.cs @@ -27,7 +27,7 @@ public class IndexMemoryDocumentStore : Dictionary, IIndexDocumentSt public IIndexContext Context { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The index context. /// The predicted capacity (number of items to store) of the document store. diff --git a/src/WebExpress.WebIndex/Memory/IndexMemoryReversePosting.cs b/src/WebExpress.WebIndex/Memory/IndexMemoryReversePosting.cs index 1c2a3c2..92129d7 100644 --- a/src/WebExpress.WebIndex/Memory/IndexMemoryReversePosting.cs +++ b/src/WebExpress.WebIndex/Memory/IndexMemoryReversePosting.cs @@ -19,7 +19,7 @@ public class IndexMemoryReversePosting public IndexMemoryReversePosition Positions { get; private set;} = []; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The item. /// The position of the term in the input value. diff --git a/src/WebExpress.WebIndex/Memory/IndexMemoryReverseTerm.cs b/src/WebExpress.WebIndex/Memory/IndexMemoryReverseTerm.cs index b23bf6e..6786ff3 100644 --- a/src/WebExpress.WebIndex/Memory/IndexMemoryReverseTerm.cs +++ b/src/WebExpress.WebIndex/Memory/IndexMemoryReverseTerm.cs @@ -92,7 +92,7 @@ public IEnumerable PreOrder } /// - /// Constructor + /// Initializes a new instance of the class. /// internal IndexMemoryReverseTerm() { @@ -197,7 +197,7 @@ internal virtual IEnumerable GetPostings(string term) { foreach (var node in GetLeafs(term)) { - foreach (var posting in node.Postings) + foreach (var posting in node.Postings ?? []) { yield return posting; } diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs b/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs index 989041c..48e9b96 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs @@ -52,7 +52,7 @@ public class IndexStorageBuffer : IDisposable private object Guard { get; } = new object(); /// - /// Constructor + /// Initializes a new instance of the class. /// /// A stream for the index file. public IndexStorageBuffer(IndexStorageFile file) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageBufferItem.cs b/src/WebExpress.WebIndex/Storage/IndexStorageBufferItem.cs index 2d1b41f..aa2b29d 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageBufferItem.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageBufferItem.cs @@ -29,7 +29,7 @@ public class IndexStorageBufferItem public IIndexStorageSegment Segment { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The segment to be cached. public IndexStorageBufferItem(IIndexStorageSegment segment) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs index bd7d786..647dcfb 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs @@ -65,7 +65,7 @@ public class IndexStorageDocumentStore : IIndexDocumentStore, IIndexStorag public uint Capacity { get; set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The index context. /// The predicted capacity (number of items to store) of the document store. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageFile.cs b/src/WebExpress.WebIndex/Storage/IndexStorageFile.cs index f328d7b..6eba6bc 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageFile.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageFile.cs @@ -34,7 +34,7 @@ public class IndexStorageFile : IDisposable public ulong NextFreeAddr { get; internal set; } = 0ul; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The file name. public IndexStorageFile(string fileName) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs b/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs index 715ac6e..77c1579 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs @@ -65,7 +65,7 @@ public class IndexStorageReverse : IIndexReverse, IIndexStorage where T : public IEnumerable All => Term.All.Distinct(); /// - /// Constructor + /// Initializes a new instance of the class. /// /// The index context. /// The property that makes up the index. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegment.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegment.cs index 9c37397..74c6787 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegment.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegment.cs @@ -15,7 +15,7 @@ public abstract class IndexStorageSegment : IIndexStorageSegment public IndexStorageContext Context { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The address of the segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocator.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocator.cs index 66b611b..107d589 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocator.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocator.cs @@ -18,7 +18,7 @@ public abstract class IndexStorageSegmentAllocator : IndexStorageSegment public ulong NextFreeAddr { get; protected set; } = 0ul; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The address of the segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorDocumentStore.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorDocumentStore.cs index f5a93b0..7d7d6fc 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorDocumentStore.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorDocumentStore.cs @@ -77,7 +77,7 @@ public IEnumerable FreeChunkSegments } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. public IndexStorageSegmentAllocatorDocumentStore(IndexStorageContext context) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorReverseIndex.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorReverseIndex.cs index 3edf5ba..abb179e 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorReverseIndex.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentAllocatorReverseIndex.cs @@ -106,7 +106,7 @@ public IEnumerable FreePositions } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. public IndexStorageSegmentAllocatorReverseIndex(IndexStorageContext context) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentFree.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentFree.cs index f979a3f..5679842 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentFree.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentFree.cs @@ -23,7 +23,7 @@ public class IndexStorageSegmentFree : IndexStorageSegment, IIndexStorageSegment public ulong SuccessorAddr { get; set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. public IndexStorageSegmentFree(IndexStorageContext context) @@ -32,7 +32,7 @@ public IndexStorageSegmentFree(IndexStorageContext context) } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The adress of the free segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs index f51cf7e..fb47279 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs @@ -52,7 +52,7 @@ public IEnumerable All } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The number of elements to be stored in the hash map. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs index af1172d..d649d0c 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs @@ -20,7 +20,7 @@ public class IndexStorageSegmentHeader : IndexStorageSegment public byte Version { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. public IndexStorageSegmentHeader(IndexStorageContext context) diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentIChunk.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentIChunk.cs index f13f5de..57cbedf 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentIChunk.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentIChunk.cs @@ -36,7 +36,7 @@ public class IndexStorageSegmentChunk : IndexStorageSegment, IIndexStorageSegmen public ulong NextChunkAddr { get; set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The adress of the segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentItem.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentItem.cs index 89031d9..563e24a 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentItem.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentItem.cs @@ -66,7 +66,7 @@ public IEnumerable ChunkSegments } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The adress of the segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPosition.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPosition.cs index 7e39e90..9b301ff 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPosition.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPosition.cs @@ -26,7 +26,7 @@ public class IndexStorageSegmentPosition : IndexStorageSegment, IIndexStorageSeg public ulong SuccessorAddr { get; set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. /// The address of the segment. diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentStatistic.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentStatistic.cs index 8205d24..30359a2 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentStatistic.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentStatistic.cs @@ -18,7 +18,7 @@ public class IndexStorageSegmentStatistic : IndexStorageSegment public uint Count { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context of the index. public IndexStorageSegmentStatistic(IndexStorageContext context) diff --git a/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs b/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs index fe6269b..af17ae2 100644 --- a/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs +++ b/src/WebExpress.WebIndex/Term/IndexTokenAnalyzer.cs @@ -26,7 +26,7 @@ public sealed class IndexTokenAnalyzer : IDisposable private List TextProcessingPipeline { get; } = []; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexTokenAnalyzer(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterLowerCase.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterLowerCase.cs index 47d5bf4..2d31bd8 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterLowerCase.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterLowerCase.cs @@ -14,7 +14,7 @@ public class IndexPipeStageConverterLowerCase : IIndexPipeStage public string Name => "LowerCase"; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageConverterLowerCase(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterMisspelled.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterMisspelled.cs index 11674af..07d54b0 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterMisspelled.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterMisspelled.cs @@ -21,7 +21,7 @@ public class IndexPipeStageConverterMisspelled : IIndexPipeStage internal Dictionary> MisspelledWordDictionary { get; } = []; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageConverterMisspelled(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterNormalizer.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterNormalizer.cs index 0ed3b5c..912bc87 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterNormalizer.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterNormalizer.cs @@ -15,7 +15,7 @@ public class IndexPipeStageConverterNormalizer : IIndexPipeStage public string Name => "Normalizer"; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageConverterNormalizer(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterTrim.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterTrim.cs index c477833..b53b277 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterTrim.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageConverterTrim.cs @@ -19,7 +19,7 @@ public class IndexPipeStageConverterTrim : IIndexPipeStage public string Name => "Trim"; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageConverterTrim(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterStopWord.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterStopWord.cs index b1a4e79..6a9a151 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterStopWord.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterStopWord.cs @@ -21,7 +21,7 @@ public class IndexPipeStageFilterStopWord : IIndexPipeStage private Dictionary> StopWordDictionary { get; } = []; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageFilterStopWord(IIndexContext context) diff --git a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs index cfdcd3c..21ee7ac 100644 --- a/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs +++ b/src/WebExpress.WebIndex/Term/Pipeline/IndexPipeStageFilterSurrogateCharacter.cs @@ -15,7 +15,7 @@ public class IndexPipeStageFilterSurrogateCharacter : IIndexPipeStage public string Name => "SurrogateCharacter"; /// - /// Constructor + /// Initializes a new instance of the class. /// /// The reference to the context. public IndexPipeStageFilterSurrogateCharacter(IIndexContext context) diff --git a/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj b/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj index 2362d82..677f4e7 100644 --- a/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj +++ b/src/WebExpress.WebIndex/WebExpress.WebIndex.csproj @@ -5,7 +5,7 @@ WebExpress.WebIndex 0.0.8.0 0.0.8.0 - net8.0 + net9.0 any https://github.com/ReneSchwarzer/WebExpress.WebIndex Rene_Schwarzer@hotmail.de diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterCondition.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterCondition.cs index ae74422..78fd1e0 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterCondition.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterCondition.cs @@ -26,7 +26,7 @@ public abstract class WqlExpressionNodeFilterCondition : IWqlExpressionNodeFi public CultureInfo Culture { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// One or more tokens that determine the operation. Multiple tokens are separated by spaces. protected WqlExpressionNodeFilterCondition(string token) diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryEqual.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryEqual.cs index b0eec31..1586a98 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryEqual.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryEqual.cs @@ -6,7 +6,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryEqual : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryEqual() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThan.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThan.cs index 8c98081..41eb5c2 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThan.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThan.cs @@ -7,7 +7,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryGreaterThan : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryGreaterThan() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual.cs index dfc087a..e374a83 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual.cs @@ -7,7 +7,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryGreaterThanOrEqual() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThan.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThan.cs index 006055f..57b64fb 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThan.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThan.cs @@ -7,7 +7,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryLessThan : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryLessThan() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThanOrEqual.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThanOrEqual.cs index edc855b..b0019ae 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThanOrEqual.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLessThanOrEqual.cs @@ -7,7 +7,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryLessThanOrEqual : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryLessThanOrEqual() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLike.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLike.cs index 97bd375..0eafb09 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLike.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionBinaryLike.cs @@ -6,7 +6,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionBinaryLike : WqlExpressionNodeFilterConditionBinary where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionBinaryLike() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSet.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSet.cs index 1c4503b..a6db64a 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSet.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSet.cs @@ -14,7 +14,7 @@ public abstract class WqlExpressionNodeFilterConditionSet : WqlExpressionNode public IEnumerable> Parameters { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// One or more tokens that determine the operation. Multiple tokens are separated by spaces. protected WqlExpressionNodeFilterConditionSet(string token) diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetIn.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetIn.cs index 1544e74..45699c9 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetIn.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetIn.cs @@ -9,7 +9,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionSetIn : WqlExpressionNodeFilterConditionSet where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionSetIn() diff --git a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetNotIn.cs b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetNotIn.cs index 58d9fb2..d010329 100644 --- a/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetNotIn.cs +++ b/src/WebExpress.WebIndex/Wql/Condition/WqlExpressionNodeFilterConditionSetNotIn.cs @@ -9,7 +9,7 @@ namespace WebExpress.WebIndex.Wql.Condition public class WqlExpressionNodeFilterConditionSetNotIn : WqlExpressionNodeFilterConditionSet where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// /// The operator. public WqlExpressionNodeFilterConditionSetNotIn() diff --git a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunction.cs b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunction.cs index 51f325a..aab050e 100644 --- a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunction.cs +++ b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunction.cs @@ -19,7 +19,7 @@ public abstract class WqlExpressionNodeFilterFunction : IWqlExpressionNode public IEnumerable> Parameters { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The function name protected WqlExpressionNodeFilterFunction(string name) diff --git a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionDay.cs b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionDay.cs index b53e12f..0709064 100644 --- a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionDay.cs +++ b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionDay.cs @@ -10,7 +10,7 @@ namespace WebExpress.WebIndex.Wql.Function public class WqlExpressionNodeFilterFunctionDay : WqlExpressionNodeFilterFunction where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// public WqlExpressionNodeFilterFunctionDay() : base("day") diff --git a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionNow.cs b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionNow.cs index 99c5552..ef6baa4 100644 --- a/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionNow.cs +++ b/src/WebExpress.WebIndex/Wql/Function/WqlExpressionNodeFilterFunctionNow.cs @@ -10,7 +10,7 @@ namespace WebExpress.WebIndex.Wql.Function public class WqlExpressionNodeFilterFunctionNow : WqlExpressionNodeFilterFunction where T : IIndexItem { /// - /// Constructor + /// Initializes a new instance of the class. /// public WqlExpressionNodeFilterFunctionNow() :base("now") diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionError.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionError.cs index 8543049..bff1b2d 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionError.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionError.cs @@ -28,7 +28,7 @@ public class WqlExpressionError public string Message { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionError() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeAttribute.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeAttribute.cs index e278165..8b3152f 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeAttribute.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeAttribute.cs @@ -23,7 +23,7 @@ public class WqlExpressionNodeAttribute : IWqlExpressionNode where T : IIn public IIndexReverse ReverseIndex { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeAttribute() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilter.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilter.cs index cbd7415..a16c18a 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilter.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilter.cs @@ -16,7 +16,7 @@ public class WqlExpressionNodeFilter : IWqlExpressionNodeApply where T : I public WqlExpressionNodeFilterCondition Condition { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeFilter() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilterBinary.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilterBinary.cs index 5799f85..4f9cd4f 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilterBinary.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeFilterBinary.cs @@ -25,7 +25,7 @@ public class WqlExpressionNodeFilterBinary : WqlExpressionNodeFilter where public WqlExpressionNodeFilter RightFilter { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeFilterBinary() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrder.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrder.cs index 57a2b9f..794b28c 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrder.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrder.cs @@ -15,7 +15,7 @@ public class WqlExpressionNodeOrder : IWqlExpressionNode where T : IIndexI public IReadOnlyList> Attributes { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeOrder() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrderAttribute.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrderAttribute.cs index b93afa3..0d9c563 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrderAttribute.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeOrderAttribute.cs @@ -23,7 +23,7 @@ public class WqlExpressionNodeOrderAttribute : IWqlExpressionNode where T public int Position { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeOrderAttribute() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameter.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameter.cs index 8467b3a..049a739 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameter.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameter.cs @@ -18,7 +18,7 @@ public class WqlExpressionNodeParameter : IWqlExpressionNode where T : IIn public WqlExpressionNodeFilterFunction Function { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeParameter() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameterOption.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameterOption.cs index a6c9308..076e1bf 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameterOption.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeParameterOption.cs @@ -16,7 +16,7 @@ public class WqlExpressionNodeParameterOption : IWqlExpressionNode where T public uint? Distance { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeParameterOption() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioning.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioning.cs index 25dcce9..869b4df 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioning.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioning.cs @@ -15,7 +15,7 @@ public class WqlExpressionNodePartitioning : IWqlExpressionNode where T : public IReadOnlyList> PartitioningFunctions { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodePartitioning() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioningFunction.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioningFunction.cs index 121612a..0c9b3d0 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioningFunction.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodePartitioningFunction.cs @@ -19,7 +19,7 @@ public class WqlExpressionNodePartitioningFunction : IWqlExpressionNode wh public int Value { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodePartitioningFunction() { diff --git a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeValue.cs b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeValue.cs index a496d9d..77635a4 100644 --- a/src/WebExpress.WebIndex/Wql/WqlExpressionNodeValue.cs +++ b/src/WebExpress.WebIndex/Wql/WqlExpressionNodeValue.cs @@ -26,7 +26,7 @@ public class WqlExpressionNodeValue : IWqlExpressionNode where T : IIndexI public CultureInfo Culture { get; internal set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlExpressionNodeValue() { diff --git a/src/WebExpress.WebIndex/Wql/WqlParseException.cs b/src/WebExpress.WebIndex/Wql/WqlParseException.cs index 73f64c4..e133d97 100644 --- a/src/WebExpress.WebIndex/Wql/WqlParseException.cs +++ b/src/WebExpress.WebIndex/Wql/WqlParseException.cs @@ -10,7 +10,7 @@ public class WqlParseException : Exception public WqlToken Token { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The massage. /// The token that caused the exception. diff --git a/src/WebExpress.WebIndex/Wql/WqlParser.cs b/src/WebExpress.WebIndex/Wql/WqlParser.cs index 6a3d770..b589fcb 100644 --- a/src/WebExpress.WebIndex/Wql/WqlParser.cs +++ b/src/WebExpress.WebIndex/Wql/WqlParser.cs @@ -79,7 +79,7 @@ public partial class WqlParser : IWqlParser where T : IIndexItem protected IIndexDocument IndexDocument { get; private set; } /// - /// Constructor + /// Initializes a new instance of the class. /// internal WqlParser() { @@ -99,7 +99,7 @@ internal WqlParser() } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The index field. internal WqlParser(IIndexDocument indexFiled) diff --git a/src/WebExpress.WebIndex/Wql/WqlStatement.cs b/src/WebExpress.WebIndex/Wql/WqlStatement.cs index 1fd0c00..25f289c 100644 --- a/src/WebExpress.WebIndex/Wql/WqlStatement.cs +++ b/src/WebExpress.WebIndex/Wql/WqlStatement.cs @@ -77,7 +77,7 @@ public IEnumerable> SyntaxTree } /// - /// Constructor + /// Initializes a new instance of the class. /// /// The original wql statement. internal WqlStatement(string raw) From c87912d87c0270259a19a5e1b3c30b060d27726a Mon Sep 17 00:00:00 2001 From: Rene Schwarzer Date: Fri, 10 Jan 2025 00:30:21 +0100 Subject: [PATCH 04/23] general improvements and bug fixes --- .../UnitTestDocumentStoreMemoryF.cs | 212 ++++++++++ .../UnitTestDocumentStoreStorageE.cs | 2 +- .../UnitTestDocumentStoreStorageF.cs | 242 +++++++++++ .../Fixture/UnitTestIndexFixtureIndexF.cs | 34 ++ .../Fixture/UnitTestIndexFixtureWqlA.cs | 9 +- .../Fixture/UnitTestIndexFixtureWqlB.cs | 9 +- .../Fixture/UnitTestIndexFixtureWqlC.cs | 9 +- .../Fixture/UnitTestIndexFixtureWqlD.cs | 9 +- .../Fixture/UnitTestIndexFixtureWqlE.cs | 9 +- .../Fixture/UnitTestIndexFixtureWqlF.cs | 58 +++ .../IndexManager/UnitTestIndexManager.cs | 8 +- .../UnitTestIndexManagerMemoryA.cs | 89 +---- .../UnitTestIndexManagerMemoryB.cs | 92 +---- .../UnitTestIndexManagerMemoryC.cs | 209 ++-------- .../UnitTestIndexManagerMemoryD.cs | 92 +---- .../UnitTestIndexManagerMemoryE.cs | 92 +---- .../UnitTestIndexManagerMemoryF.cs | 341 ++++++++++++++++ .../UnitTestIndexManagerStorageA.cs | 123 +++--- .../UnitTestIndexManagerStorageB.cs | 129 +++--- .../UnitTestIndexManagerStorageC.cs | 367 ++++------------- .../UnitTestIndexManagerStorageD.cs | 128 +++--- .../UnitTestIndexManagerStorageE.cs | 129 +++--- .../UnitTestIndexManagerStorageF.cs | 376 ++++++++++++++++++ .../UnitTestReverseIndexMemoryA.cs | 4 +- .../UnitTestReverseIndexMemoryB.cs | 4 +- .../UnitTestReverseIndexMemoryD.cs | 4 +- .../UnitTestReverseIndexMemoryE.cs | 4 +- .../UnitTestReverseIndexMemoryF.cs | 189 +++++++++ .../UnitTestReverseIndexStorageF.cs | 136 +++++++ .../TestDocument/UnitTestIndexTestDocument.cs | 6 +- .../UnitTestIndexTestDocumentF.cs | 24 ++ .../UnitTestIndexTestDocumentFactory.cs | 3 + .../UnitTestIndexTestDocumentFactoryA.cs | 2 +- .../UnitTestIndexTestDocumentFactoryB.cs | 5 +- .../UnitTestIndexTestDocumentFactoryC.cs | 3 + .../UnitTestIndexTestDocumentFactoryD.cs | 3 + .../UnitTestIndexTestDocumentFactoryE.cs | 8 +- .../UnitTestIndexTestDocumentFactoryF.cs | 34 ++ .../Token/UnitTestIndexAnalyze.cs | 101 +---- .../Token/UnitTestIndexPipeStageStopWord.cs | 61 ++- .../WebExpress.WebIndex.Test.csproj | 4 + src/WebExpress.WebIndex.Wi/Model/ViewModel.cs | 10 +- src/WebExpress.WebIndex/Asstes/StopWords.de | 33 +- src/WebExpress.WebIndex/Asstes/StopWords.en | 29 +- src/WebExpress.WebIndex/IndexManager.cs | 5 +- .../Storage/IIndexStorageSegment.cs | 3 + .../Storage/IIndexStorageSegmentChunk.cs | 3 + .../Storage/IIndexStorageSegmentListItem.cs | 3 + .../Storage/IndexStorageBuffer.cs | 10 +- .../Storage/IndexStorageDocumentStore.cs | 9 +- .../Storage/IndexStorageReverse.cs | 9 +- .../Storage/IndexStorageSchema.cs | 18 +- .../Storage/IndexStorageSegmentHashMap.cs | 3 + .../Storage/IndexStorageSegmentHeader.cs | 21 +- .../Storage/IndexStorageSegmentPostingNode.cs | 3 +- .../Storage/IndexStorageSegmentTermNode.cs | 13 +- .../Term/IndexTermTokenizer.cs | 2 +- 57 files changed, 2276 insertions(+), 1261 deletions(-) create mode 100644 src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryF.cs create mode 100644 src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageF.cs create mode 100644 src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexF.cs create mode 100644 src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlF.cs create mode 100644 src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryF.cs create mode 100644 src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageF.cs create mode 100644 src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryF.cs create mode 100644 src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageF.cs create mode 100644 src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentF.cs create mode 100644 src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryF.cs diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryF.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryF.cs new file mode 100644 index 0000000..371db61 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreMemoryF.cs @@ -0,0 +1,212 @@ +using WebExpress.WebIndex.Memory; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.DocumentStore +{ + /// + /// Test class for testing the memory-based document store for unicode. + /// + public class UnitTestDocumentStoreMemoryF : UnitTestDocumentStore + { + /// + /// Initializes a new instance of the class. + /// + /// The log. + /// The test context. + public UnitTestDocumentStoreMemoryF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) + : base(fixture, output) + { + } + + /// + /// Creates a document store. + /// + [Fact] + public void Create() + { + // preconditions + var context = new IndexContext(); + + // test execution + var documentStore = new IndexMemoryDocumentStore(context, (uint)Fixture.TestData.Count); + + // postconditions + documentStore.Dispose(); + } + + /// + /// Adds items to a document store. + /// + [Fact] + public void Add() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + + // test execution + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + var i = documentStore.GetItem(Fixture.TestData[0].Id); + + Assert.True(i != null && i.Id == Fixture.TestData[0].Id); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Update an entry in the reverse index where the item has a first name change. + /// + [Fact] + public void UpdateWithChange() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + var randomItem = Fixture.RandomItem; + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + var name = "Update_" + randomItem.Name; + var changed = new UnitTestIndexTestDocumentF + { + Id = randomItem.Id, + Name = name + }; + + // test execution + documentStore.Update(changed); + + var all = documentStore.All; + + Assert.True(all.Select(x => x.Id).OrderBy(x => x).SequenceEqual(Fixture.TestData.Select(x => x.Id).OrderBy(x => x))); + Assert.True(all.Where(x => x.Name == name).Any()); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Changes an entry in the reverse index without the element to be changed having any changes. + /// + [Fact] + public void UpdateWithoutChanges() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + var randomItem = Fixture.RandomItem; + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + documentStore.Update(randomItem); + var all = documentStore.All; + + Assert.True(all.Select(x => x.Id).OrderBy(x => x).SequenceEqual(Fixture.TestData.Select(x => x.Id).OrderBy(x => x))); + Assert.True(all.Where(x => x.Name == randomItem.Name).Any()); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Removes an entry from the document store. + /// + [Fact] + public void Remove() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + documentStore.Delete(Fixture.TestData[0]); + var all = documentStore.All; + + Assert.True(all.Select(x => x.Id).SequenceEqual(Fixture.TestData.Where(x => x.Id != Fixture.TestData[0].Id).Select(x => x.Id))); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Retrieve a entry of the reverse index. + /// + [Fact] + public void Retrieve() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var document in Fixture.TestData) + { + documentStore.Add(document); + } + + // test execution + var item = documentStore.GetItem(Fixture.TestData[0].Id); + + Assert.NotNull(documentStore); + Assert.NotNull(item); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Return all entries of the document store. + /// + [Fact] + public void All() + { + // preconditions + Preconditions(); + var documentStore = new IndexMemoryDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + var all = documentStore.All; + + Assert.True(all.Select(x => x.Id).OrderBy(x => x).SequenceEqual(Fixture.TestData.Select(x => x.Id).OrderBy(x => x))); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs index c02dd91..a74b584 100644 --- a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageE.cs @@ -72,7 +72,7 @@ public void UpdateWithChange() // preconditions Preconditions(); var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); - var randomItem = Fixture.RandomItem; + var randomItem = Fixture.TestData.LastOrDefault(); documentStore.Clear(); foreach (var item in Fixture.TestData) diff --git a/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageF.cs b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageF.cs new file mode 100644 index 0000000..5945ef0 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/DocumentStore/UnitTestDocumentStoreStorageF.cs @@ -0,0 +1,242 @@ +using WebExpress.WebIndex.Storage; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.DocumentStore +{ + /// + /// Test class for testing the storage-based document store. + /// + public class UnitTestDocumentStoreStorageF : UnitTestDocumentStore + { + /// + /// Initializes a new instance of the class. + /// + /// The log. + /// The test context. + public UnitTestDocumentStoreStorageF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) + : base(fixture, output) + { + } + + /// + /// Creates a document store. + /// + [Fact] + public void Create() + { + // preconditions + Preconditions(); + + // test execution + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + // postconditions + documentStore.Dispose(); + } + + /// + /// Adds items to a document store. + /// + [Fact] + public void Add() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + + // test execution + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + var i = documentStore.GetItem(Fixture.TestData[0].Id); + + Assert.True(i != null && i.Id == Fixture.TestData[0].Id); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Update an entry in the reverse index where the item has a first name change. + /// + [Fact] + public void UpdateWithChange() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + var randomItem = Fixture.RandomItem; + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + var name = "Update_" + randomItem.Name; + var changed = new UnitTestIndexTestDocumentF + { + Id = randomItem.Id, + Name = name + }; + + // test execution + documentStore.Update(changed); + + var all = documentStore.All; + + Assert.Equal(all.Select(x => x.Id).OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); + Assert.True(all.Where(x => x.Name == name).Any()); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Changes an entry in the reverse index without the element to be changed having any changes. + /// + [Fact] + public void UpdateWithoutChanges() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + var randomItem = Fixture.RandomItem; + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + documentStore.Update(randomItem); + var all = documentStore.All; + + Assert.Equal(all.Select(x => x.Id).OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); + Assert.True(all.Where(x => x.Name == randomItem.Name).Any()); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Removes an entry from the document store. + /// + [Fact] + public void Remove() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + documentStore.Delete(Fixture.TestData[0]); + var all = documentStore.All; + + Assert.Equal(all.Select(x => x.Id).OrderBy(x => x), Fixture.TestData.Where(x => x.Id != Fixture.TestData[0].Id).Select(x => x.Id).OrderBy(x => x)); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Retrieve a entry of the reverse index. + /// + [Fact] + public void Retrieve() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var document in Fixture.TestData) + { + documentStore.Add(document); + } + + // test execution + var item = documentStore.GetItem(Fixture.TestData[0].Id); + + Assert.NotNull(documentStore); + Assert.NotNull(item); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Return all entries of the document store. + /// + [Fact] + public void All() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + // test execution + var all = documentStore.All; + + Assert.Equal(all.Select(x => x.Id).OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + + /// + /// Reopen the document store. + /// + [Fact] + public void Reopen() + { + // preconditions + Preconditions(); + var documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + documentStore.Clear(); + foreach (var item in Fixture.TestData) + { + documentStore.Add(item); + } + + documentStore.Dispose(); + documentStore = new IndexStorageDocumentStore(Context, (uint)Fixture.TestData.Count); + + // test execution + var all = documentStore.All; + + Assert.Equal("wds", documentStore.Header.Identifier); + Assert.Equal(all.Select(x => x.Id).OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); + + // postconditions + documentStore.Dispose(); + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexF.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexF.cs new file mode 100644 index 0000000..1cf47d1 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureIndexF.cs @@ -0,0 +1,34 @@ +using WebExpress.WebIndex.Test.Document; + +namespace WebExpress.WebIndex.Test.Fixture +{ + /// + /// Represents a fixture for unit tests related to index functionality. + /// + public class UnitTestIndexFixtureIndexF : UnitTestIndexFixture + { + /// + /// Returns the test data. + /// + public List TestData { get; } = UnitTestIndexTestDocumentFactoryF.GenerateTestData(); + + /// + /// Returns a random document item. + /// + public UnitTestIndexTestDocumentF RandomItem => TestData[Rand.Next(TestData.Count)]; + + /// + /// Initializes a new instance of the class. + /// + public UnitTestIndexFixtureIndexF() + { + } + + /// + /// Disposes of the resources used by the current instance. + /// + public override void Dispose() + { + } + } +} diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs index c76aac0..a9a67da 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlA.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Reflection; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Wql; @@ -23,7 +24,11 @@ public UnitTestIndexFixtureWqlA() { var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); IndexManager.ReIndex(TestData); } @@ -40,7 +45,7 @@ public override void Dispose() /// /// Executes a wql statement. /// - /// Tje wql statement. + /// The wql statement. /// The WQL parser. public IWqlStatement ExecuteWql(string wql) { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs index ac7a206..8c2536a 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlB.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Reflection; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Wql; @@ -23,7 +24,11 @@ public UnitTestIndexFixtureWqlB() { var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); IndexManager.ReIndex(TestData); } @@ -40,7 +45,7 @@ public override void Dispose() /// /// Executes a wql statement. /// - /// Tje wql statement. + /// The wql statement. /// The WQL parser. public IWqlStatement ExecuteWql(string wql) { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs index 6c9f1f0..4f6dfaf 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlC.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Reflection; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Wql; @@ -33,7 +34,11 @@ public UnitTestIndexFixtureWqlC() { var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); IndexManager.ReIndex(TestData); RandomItem = TestData.Skip(Rand.Next(TestData.Count())).FirstOrDefault(); @@ -52,7 +57,7 @@ public override void Dispose() /// /// Executes a wql statement. /// - /// Tje wql statement. + /// The wql statement. /// The WQL parser. public IWqlStatement ExecuteWql(string wql) { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs index 8498115..04ac6b6 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlD.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Reflection; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Wql; @@ -23,7 +24,11 @@ public UnitTestIndexFixtureWqlD() { var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); IndexManager.ReIndex(TestData); } @@ -40,7 +45,7 @@ public override void Dispose() /// /// Executes a wql statement. /// - /// Tje wql statement. + /// The wql statement. /// The WQL parser. public IWqlStatement ExecuteWql(string wql) { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs index 0186a09..d96aeee 100644 --- a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlE.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Reflection; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Wql; @@ -23,7 +24,11 @@ public UnitTestIndexFixtureWqlE() { var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); IndexManager.ReIndex(TestData); } @@ -40,7 +45,7 @@ public override void Dispose() /// /// Executes a wql statement. /// - /// Tje wql statement. + /// The wql statement. /// The WQL parser. public IWqlStatement ExecuteWql(string wql) { diff --git a/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlF.cs b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlF.cs new file mode 100644 index 0000000..2d5ac30 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/Fixture/UnitTestIndexFixtureWqlF.cs @@ -0,0 +1,58 @@ +using System.Globalization; +using System.Reflection; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Wql; + +namespace WebExpress.WebIndex.Test.Fixture +{ + /// + /// Provides a fixture for unit tests that involve the IndexManager and WQL statements for unicode testing. + /// + public class UnitTestIndexFixtureWqlF : UnitTestIndexFixture + { + /// + /// Returns the index manager. + /// + public WebIndex.IndexManager IndexManager { get; } = new IndexManagerTest(); + + /// + /// Returns the test data. + /// + public IEnumerable TestData { get; } = UnitTestIndexTestDocumentFactoryE.GenerateTestData(); + + /// + /// Initializes a new instance of the class. + /// + public UnitTestIndexFixtureWqlF() + { + var context = new IndexContext(); + context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); + + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(TestData); + } + + /// + /// Disposes of the resources used by the current instance. + /// + public override void Dispose() + { + IndexManager.Dispose(); + Directory.Delete(IndexManager.Context.IndexDirectory, true); + } + + /// + /// Executes a wql statement. + /// + /// The wql statement. + /// The WQL parser. + public IWqlStatement ExecuteWql(string wql) + { + return IndexManager.Retrieve(wql); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManager.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManager.cs index 7d4d3d6..e5b6895 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManager.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManager.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using System.Reflection; +using Xunit.Abstractions; namespace WebExpress.WebIndex.Test.IndexManager { @@ -37,7 +38,10 @@ protected void Preconditions() var context = new IndexContext(); context.IndexDirectory = Path.Combine(context.IndexDirectory, Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); IndexManager = new IndexManagerTest(); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManagerTest).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); Context = context; } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs index 0cef8e1..7318672 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryA.cs @@ -41,12 +41,16 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -64,12 +68,16 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -84,75 +92,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs index 5b29cee..675e718 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryB.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -65,13 +69,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -86,78 +94,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs index 0599758..8d9b3e8 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryC.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using System.Globalization; +using System.Globalization; using WebExpress.WebIndex.Test.Document; using WebExpress.WebIndex.Test.Fixture; using Xunit.Abstractions; @@ -42,61 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public async Task ReIndexAsync_En() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); - - // test execution - await IndexManager.ReIndexAsync(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -112,135 +67,47 @@ public void ReIndex_De() } /// - /// Tests the reindex function from the index manager. + /// Tests the reindex function in a series of tests from the index manager. /// - [Fact] - public void ReIndex_DeDE() + [Theory] + [InlineData(100, 100, 100, 15, "en")] + [InlineData(1000, 100, 2000, 15, "en")] + [InlineData(500, 75, 400, 10, "en")] + public async Task ReIndexAsync(int itemCount, int wordCount, int vocabulary, int wordLength, string culture) { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text}'"); - Assert.NotNull(wql); + var w = wordCount; + var i = itemCount; + var v = vocabulary; + var l = wordLength; - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { // preconditions Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text}'"); - Assert.NotNull(wql); - var item = wql.Apply(); - Assert.NotEmpty(item); + var output = ""; + var data = UnitTestIndexTestDocumentFactoryC.GenerateTestData(i, w, v, l); - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function in a series of tests from the index manager. - /// - [Fact] - public async Task ReIndexAsync_Series() - { - var stopWatch = new Stopwatch(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); - var itemCount = Enumerable.Range(1, 10).Select(x => x * 10000); - var wordCount = Enumerable.Range(1, 1).Select(x => x * 100); - var vocabulary = Enumerable.Range(1, 1).Select(x => x * 20000); - var wordLength = Enumerable.Range(1, 1).Select(x => x * 15); - var file = await Task.Run(() => File.CreateText(Path.Combine(Environment.CurrentDirectory, "memory-reindexasync_series.csv"))); + try + { + // test execution + await IndexManager.ReIndexAsync(data); - Output.WriteLine("item count;wordCount;vocabulary;wordLength;elapsed reindex [hh:mm:ss];elapsed retrieval [ms];size of process mem [MB]"); - file.WriteLine("item count;wordCount;vocabulary;wordLength;elapsed reindex [hh:mm:ss];elapsed retrieval [ms];size of process mem [MB]"); + var randomItem = IndexManager.All().Skip(new Random().Next() % data.Count()).FirstOrDefault(); + var wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); + Assert.NotNull(wql); - foreach (var w in wordCount) + var item = wql.Apply(); + Assert.NotEmpty(item); + } + catch (Exception ex) + { + output += ex.Message + " " + ex.StackTrace; + } + finally { - foreach (var i in itemCount) - { - foreach (var v in vocabulary) - { - foreach (var l in wordLength) - { - // disabled due to long execution time. activate if necessary. - /** - // preconditions - Preconditions(); - var output = ""; - var data = UnitTestIndexTestDocumentFactoryC.GenerateTestData(i, w, v, l); - var mem = Fixture.GetUsedMemory(); - - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); - - try - { - // preparing for a measurement - stopWatch.Start(); - - // test execution - await IndexManager.ReIndexAsync(data); - - // stop measurement - var elapsedReindex = stopWatch.Elapsed; - stopWatch.Reset(); - - var randomItem = IndexManager.All().Skip(new Random().Next() % data.Count()).FirstOrDefault(); - var wql = IndexManager.Select($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - // preparing for a measurement - stopWatch.Start(); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // stop measurement - var elapsedRetrieval = stopWatch.Elapsed; - stopWatch.Reset(); - - var documentStoreSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wds", SearchOption.AllDirectories).Sum(file => file.Length); - var reverseIndexSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wri", SearchOption.AllDirectories).Sum(file => file.Length); - - output = $"{i};{w};{v};{l};{elapsedReindex:hh\\:mm\\:ss};{(int)Math.Ceiling(elapsedRetrieval.TotalMilliseconds)};{Fixture.GetUsedMemory() - mem}"; - } - catch (Exception ex) - { - output += ex.Message + " " + ex.StackTrace; - } - finally - { - // postconditions - Output.WriteLine(output); - file.WriteLine(output); - file.Flush(); - Postconditions(); - } - /**/ - } - } - } + // postconditions + Postconditions(); } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs index 1111e81..be37636 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryD.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -65,13 +69,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -86,78 +94,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs index d9a65fb..5d4c35a 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryE.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -65,13 +69,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -86,78 +94,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Memory); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryF.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryF.cs new file mode 100644 index 0000000..fe83105 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerMemoryF.cs @@ -0,0 +1,341 @@ +using System.Globalization; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.IndexManager +{ + /// + /// Test class for testing the memory-based index manager for unicode. + /// + public class UnitTestIndexManagerMemoryF : UnitTestIndexManager + { + /// + /// Initializes a new instance of the class. + /// + /// The log. + /// The test context. + public UnitTestIndexManagerMemoryF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) + : base(fixture, output) + { + } + + /// + /// Tests registering a document in the index manager. + /// + [Fact] + public void Create() + { + // preconditions + Preconditions(); + + // test execution + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + + Assert.NotNull(IndexManager.GetIndexDocument()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the reindex function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); + + // test execution + IndexManager.ReIndex(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.NotEmpty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the reindex function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Memory); + + // test execution + await IndexManager.ReIndexAsync(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.NotEmpty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the removal of a document from the index manager. + /// + [Fact] + public void Delete() + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var before = wql.Apply().ToList(); + Assert.True(before.Any()); + + // test execution + IndexManager.Delete(randomItem); + + wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var after = wql.Apply().ToList(); + Assert.True(before.Count - 1 == after.Count); + + // postconditions + Postconditions(); + } + + /// + /// Tests the add function of the index manager. + /// + [Theory] + [InlineData("ED242C79-E41B-4214-BFBC-C4673E87433B", "Aurora")] + [InlineData("A20BC371-10F9-4F43-9DA8-F4B4F0BE26AB", "李明")] + [InlineData("80A78EBB-9819-45AF-BC0F-68E68D0C8C1A", "Sun Leaf Lion 🌞🌿🦁")] + [InlineData("29F34DFD-432D-4315-88C2-CE41F293AC71", "🦋🌼🌙 Butterfly Flower Moon")] + public void Add(string id, string name) + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Insert(new UnitTestIndexTestDocumentF() + { + Id = Guid.Parse(id), + Name = name + }); + + var wql = IndexManager.Retrieve($"name = '{name}'"); + var item = wql.Apply(); + + Assert.NotNull(wql); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the add function of the index manager. + /// + [Theory] + [InlineData("9733A649-1E5E-4B1F-8C6E-9A4B6AB54292", "🌟🍀🐉")] + public void NotAdd(string id, string name) + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Insert(new UnitTestIndexTestDocumentF() + { + Id = Guid.Parse(id), + Name = name + }); + + var wql = IndexManager.Retrieve($"name = '{name}'"); + var item = wql.Apply(); + + Assert.NotNull(wql); + Assert.Empty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the update function of the index manager. + /// + [Fact] + public void Update() + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Update(new UnitTestIndexTestDocumentF() + { + Id = randomItem.Id, + Name = "Aurora" + }); + + var wql = IndexManager.Retrieve("name = 'Aurora'"); + var item = wql.Apply(); + + Assert.NotNull(wql); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the update function of the index manager. + /// + [Fact] + public async Task UpdateAsync() + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + await IndexManager.ReIndexAsync(Fixture.TestData); + + // test execution + await IndexManager.UpdateAsync(new UnitTestIndexTestDocumentF() + { + Id = randomItem.Id, + Name = "Aurora" + }); + + var wql = IndexManager.Retrieve("name = 'Aurora'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests removing a document on the index manager. + /// + [Fact] + public void Clear() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + var documents = IndexManager.All(); + + Assert.NotNull(documents); + Assert.True(documents.Any()); + + // test execution + IndexManager.Clear(); + + documents = IndexManager.All(); + + Assert.NotNull(documents); + Assert.False(documents.Any()); + + // postconditions + Postconditions(); + } + + /// + /// Return all entries of the index manager. + /// + [Fact] + public void All() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + var all = IndexManager.All(); + + Assert.NotEmpty(all); + + // postconditions + Postconditions(); + } + + /// + /// Tests get a document from the index manager. + /// + [Fact] + public void GetDocument() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + + // test execution + var document = IndexManager.GetIndexDocument(); + Assert.NotNull(document); + Assert.True(document.GetType() == typeof(IndexDocument)); + + // postconditions + Postconditions(); + } + + /// + /// Tests get a document from the index manager. + /// + [Fact] + public void GetDocument_Not() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Memory); + + // test execution + var document = IndexManager.GetIndexDocument(); + Assert.Null(document); + + // postconditions + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs index f6820fc..154636e 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageA.cs @@ -41,12 +41,16 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -64,12 +68,16 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -84,75 +92,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve("text ~ 'Helena'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.Equal(4, item.Count()); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// @@ -370,5 +309,39 @@ public void GetDocument_Not() // postconditions Postconditions(); } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve("text ~ 'Helena'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve("text ~ 'Helena'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs index acf6b4c..dd080c2 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageB.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -65,13 +69,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -91,7 +99,7 @@ public async Task ReIndexAsync_En() /// Tests the reindex function from the index manager. /// [Fact] - public async Task ReIndexAsyncCancel_En() + public async Task ReIndexAsyncCancel() { // preconditions Preconditions(); @@ -121,78 +129,6 @@ public async Task ReIndexAsyncCancel_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// @@ -401,5 +337,40 @@ public void GetDocument_Not() // postconditions Postconditions(); } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageC.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageC.cs index 2a50f26..6940cfc 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageC.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageC.cs @@ -35,109 +35,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public async Task ReIndexAsync_En() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); - - // test execution - await IndexManager.ReIndexAsync(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -155,204 +63,62 @@ public void ReIndex_Fr() /// /// Tests the reindex function in a series of tests from the index manager. /// - [Fact] - public void ReIndex_Series() + [Theory] + [InlineData(100, 100, 100, 15, "en")] + [InlineData(1000, 100, 2000, 15, "en")] + [InlineData(5000, 75, 4000, 10, "en")] + public async Task ReIndexAsync(int itemCount, int wordCount, int vocabulary, int wordLength, string culture) { var stopWatch = new Stopwatch(); - var itemCount = Enumerable.Range(1, 1).Select(x => x * 100); - var wordCount = Enumerable.Range(1, 1).Select(x => x * 100); - var vocabulary = Enumerable.Range(1, 1).Select(x => x * 20000); - var wordLength = Enumerable.Range(1, 1).Select(x => x * 15); - var maxCachedSegments = Enumerable.Range(5, 1).Select(x => x * 10000); - var bufferSize = Enumerable.Range(12, 1).Select(x => Math.Pow(2, x)); - var path = Path.Combine(Environment.CurrentDirectory, "storage-reindex_series.csv"); + var w = wordCount; + var i = itemCount; + var v = vocabulary; + var l = wordLength; + var maxCachedSegmentsRange = Enumerable.Range(5, 1).Select(x => x * 10000); + var bufferSizeRange = Enumerable.Range(12, 1).Select(x => Math.Pow(2, x)); + var path = Path.Combine(Environment.CurrentDirectory, "storage-reindexasync_series.csv"); var exists = File.Exists(path); - if (!exists) - { - File.AppendAllText(path, "timestamp;item count;wordCount;vocabulary;wordLength;max cached segments;buffer size;elapsed reindex [hh:mm:ss];elapsed retrieval [ms];size of document store [MB];size of reverse index [MB];∑ storage space [MB];size of process mem [MB]" + Environment.NewLine); - } + var data = UnitTestIndexTestDocumentFactoryC.GenerateTestData(i, w, v, l); + var randomItem = default(UnitTestIndexTestDocumentC); + var mem = Fixture.GetUsedMemory(); - foreach (var w in wordCount) + foreach (var m in maxCachedSegmentsRange) { - foreach (var i in itemCount) + foreach (var b in bufferSizeRange) { - foreach (var v in vocabulary) + // preconditions + IndexStorageBuffer.MaxCachedSegments = (uint)m; + IndexStorageFile.BufferSize = (uint)b; + + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.Retrieve($"text = 'xyz'").Apply(); + + try { - foreach (var l in wordLength) - { - var data = UnitTestIndexTestDocumentFactoryC.GenerateTestData(i, w, v, l); - var randomItem = default(UnitTestIndexTestDocumentC); - var mem = Fixture.GetUsedMemory(); - - foreach (var m in maxCachedSegments) - { - foreach (var b in bufferSize) - { - // preconditions - IndexStorageBuffer.MaxCachedSegments = (uint)m; - IndexStorageFile.BufferSize = (uint)b; - - Preconditions(); - var output = ""; - - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); - IndexManager.Retrieve($"text = 'xyz'").Apply(); - - try - { - // preparing for a measurement - stopWatch.Start(); - - // test execution - IndexManager.ReIndex(data); - - // stop measurement - var elapsedReindex = stopWatch.Elapsed; - stopWatch.Reset(); - - randomItem ??= IndexManager.All().Skip(new Random().Next() % data.Count()).FirstOrDefault(); - var wql = IndexManager.Retrieve($"text ~ '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - // preparing for a measurement - stopWatch.Start(); - - var item = wql.Apply(); - - // stop measurement - var elapsedRetrieval = stopWatch.Elapsed; - stopWatch.Reset(); - - Assert.NotEmpty(item); - - IndexManager.Dispose(); - - var documentStoreSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wds", SearchOption.AllDirectories).Sum(file => file.Length); - var reverseIndexSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wri", SearchOption.AllDirectories).Sum(file => file.Length); - - output = $"{DateTime.Now};{i};{w};{v};{l};{m};{b};{elapsedReindex:hh\\:mm\\:ss};{(int)Math.Ceiling(elapsedRetrieval.TotalMilliseconds)};{Math.Round((double)documentStoreSize / 1024 / 1024, 2)};{Math.Round((double)reverseIndexSize / 1024 / 1024, 2)};{Math.Round((double)(documentStoreSize + reverseIndexSize) / 1024 / 1024, 2)};{Fixture.GetUsedMemory() - mem}"; - } - catch (Exception ex) - { - Output.WriteLine(ex.Message + " " + ex.StackTrace); - throw; - } - finally - { - // postconditions - File.AppendAllText(path, output + Environment.NewLine); - Postconditions(); - } - - Thread.Sleep(5000); - } - } - } - } - } - } - } + // test execution + await IndexManager.ReIndexAsync(data); - /// - /// Tests the reindex function in a series of tests from the index manager. - /// - [Fact] - public async Task ReIndexAsync_Series() - { - var stopWatch = new Stopwatch(); + randomItem ??= IndexManager.All().Skip(new Random().Next() % data.Count()).FirstOrDefault(); + var wql = IndexManager.Retrieve($"text ~ '{randomItem.Text.Split(' ').FirstOrDefault()}'"); + Assert.NotNull(wql); - var itemCount = Enumerable.Range(1, 1).Select(x => x * 10000); - var wordCount = Enumerable.Range(1, 1).Select(x => x * 100); - var vocabulary = Enumerable.Range(1, 1).Select(x => x * 20000); - var wordLength = Enumerable.Range(1, 1).Select(x => x * 15); - var maxCachedSegments = Enumerable.Range(5, 1).Select(x => x * 10000); - var bufferSize = Enumerable.Range(12, 1).Select(x => Math.Pow(2, x)); - var path = Path.Combine(Environment.CurrentDirectory, "storage-reindexasync_series.csv"); - var exists = File.Exists(path); + var item = wql.Apply(); - if (!exists) - { - File.AppendAllText(path, "timestamp;item count;wordCount;vocabulary;wordLength;max cached segments;buffer size;elapsed reindex [hh:mm:ss];elapsed retrieval [ms];size of document store [MB];size of reverse index [MB];∑ storage space [MB];size of process mem [MB]" + Environment.NewLine); - } + Assert.NotEmpty(item); - foreach (var w in wordCount) - { - foreach (var i in itemCount) - { - foreach (var v in vocabulary) + IndexManager.Dispose(); + } + catch (Exception ex) + { + throw; + } + finally { - foreach (var l in wordLength) - { - var data = UnitTestIndexTestDocumentFactoryC.GenerateTestData(i, w, v, l); - var randomItem = default(UnitTestIndexTestDocumentC); - var mem = Fixture.GetUsedMemory(); - - foreach (var m in maxCachedSegments) - { - foreach (var b in bufferSize) - { - // preconditions - IndexStorageBuffer.MaxCachedSegments = (uint)m; - IndexStorageFile.BufferSize = (uint)b; - - Preconditions(); - var output = ""; - - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); - IndexManager.Retrieve($"text = 'xyz'").Apply(); - - try - { - // preparing for a measurement - stopWatch.Start(); - - // test execution - await IndexManager.ReIndexAsync(data); - - // stop measurement - var elapsedReindex = stopWatch.Elapsed; - stopWatch.Reset(); - - randomItem ??= IndexManager.All().Skip(new Random().Next() % data.Count()).FirstOrDefault(); - var wql = IndexManager.Retrieve($"text ~ '{randomItem.Text.Split(' ').FirstOrDefault()}'"); - Assert.NotNull(wql); - - // preparing for a measurement - stopWatch.Start(); - - var item = wql.Apply(); - - // stop measurement - var elapsedRetrieval = stopWatch.Elapsed; - stopWatch.Reset(); - - Assert.NotEmpty(item); - - IndexManager.Dispose(); - - var documentStoreSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wds", SearchOption.AllDirectories).Sum(file => file.Length); - var reverseIndexSize = new DirectoryInfo(IndexManager.Context.IndexDirectory).GetFiles("*.wri", SearchOption.AllDirectories).Sum(file => file.Length); - - output = $"{DateTime.Now};{i};{w};{v};{l};{m};{b};{elapsedReindex:hh\\:mm\\:ss};{(int)Math.Ceiling(elapsedRetrieval.TotalMilliseconds)};{Math.Round((double)documentStoreSize / 1024 / 1024, 2)};{Math.Round((double)reverseIndexSize / 1024 / 1024, 2)};{Math.Round((double)(documentStoreSize + reverseIndexSize) / 1024 / 1024, 2)};{Fixture.GetUsedMemory() - mem}"; - } - catch (Exception ex) - { - Output.WriteLine(ex.Message + " " + ex.StackTrace); - throw; - } - finally - { - // postconditions - File.AppendAllText(path, output + Environment.NewLine); - Postconditions(); - } - - Thread.Sleep(5000); - } - } - } + // postconditions + Postconditions(); } } } @@ -566,5 +332,40 @@ public void GetDocument_Not() // postconditions Postconditions(); } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve($"text = '{randomItem.Text.Split(' ').FirstOrDefault()}'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs index f1e3b93..d553612 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageD.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -64,14 +68,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. - /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -86,78 +93,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// @@ -366,5 +301,40 @@ public void GetDocument_Not() // postconditions Postconditions(); } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve($"firstname = '{randomItem.FirstName}'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs index b1a77b0..c33bef3 100644 --- a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageE.cs @@ -41,13 +41,17 @@ public void Create() /// /// Tests the reindex function from the index manager. /// - [Fact] - public void ReIndex_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution IndexManager.ReIndex(Fixture.TestData); @@ -65,13 +69,17 @@ public void ReIndex_En() /// /// Tests the reindex function from the index manager. /// - [Fact] - public async Task ReIndexAsync_En() + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) { // preconditions Preconditions(); var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); // test execution await IndexManager.ReIndexAsync(Fixture.TestData); @@ -86,78 +94,6 @@ public async Task ReIndexAsync_En() Postconditions(); } - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_De() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_DeDE() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("de-DE"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - - /// - /// Tests the reindex function from the index manager. - /// - [Fact] - public void ReIndex_Fr() - { - // preconditions - Preconditions(); - var randomItem = Fixture.RandomItem; - IndexManager.Create(CultureInfo.GetCultureInfo("fr"), IndexType.Storage); - - // test execution - IndexManager.ReIndex(Fixture.TestData); - - var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); - Assert.NotNull(wql); - - var item = wql.Apply(); - Assert.NotEmpty(item); - - // postconditions - Postconditions(); - } - /// /// Tests the removal of a document from the index manager. /// @@ -254,7 +190,7 @@ public async Task UpdateAsync() { // preconditions Preconditions(); - var randomItem = Fixture.RandomItem; + var randomItem = Fixture.TestData.LastOrDefault(); IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); await IndexManager.ReIndexAsync(Fixture.TestData); @@ -366,5 +302,40 @@ public void GetDocument_Not() // postconditions Postconditions(); } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } } } diff --git a/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageF.cs b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageF.cs new file mode 100644 index 0000000..a8672bd --- /dev/null +++ b/src/WebExpress.WebIndex.Test/IndexManager/UnitTestIndexManagerStorageF.cs @@ -0,0 +1,376 @@ +using System.Globalization; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.IndexManager +{ + /// + /// Test class for testing the storage-based index manager for unicode. + /// + public class UnitTestIndexManagerStorageF : UnitTestIndexManager + { + /// + /// Initializes a new instance of the class. + /// + /// The log. + /// The test context. + public UnitTestIndexManagerStorageF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) + : base(fixture, output) + { + } + + /// + /// Tests registering a document in the index manager. + /// + [Fact] + public void Create() + { + // preconditions + Preconditions(); + + // test execution + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + + Assert.NotNull(IndexManager.GetIndexDocument()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the reindex function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void ReIndex(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + + // test execution + IndexManager.ReIndex(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.NotEmpty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the reindex function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public async Task ReIndexAsync(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + + // test execution + await IndexManager.ReIndexAsync(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.NotEmpty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the removal of a document from the index manager. + /// + [Fact] + public void Delete() + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var before = wql.Apply().ToList(); + Assert.True(before.Any()); + + // test execution + IndexManager.Delete(randomItem); + + wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var after = wql.Apply().ToList(); + Assert.Equal(before.Count - 1, after.Count); + + // postconditions + Postconditions(); + } + + /// + /// Tests the add function of the index manager. + /// + [Theory] + [InlineData("ED242C79-E41B-4214-BFBC-C4673E87433B", "Aurora")] + [InlineData("A20BC371-10F9-4F43-9DA8-F4B4F0BE26AB", "李明")] + [InlineData("80A78EBB-9819-45AF-BC0F-68E68D0C8C1A", "Sun Leaf Lion 🌞🌿🦁")] + [InlineData("29F34DFD-432D-4315-88C2-CE41F293AC71", "🦋🌼🌙 Butterfly Flower Moon")] + public void Add(string id, string name) + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Insert(new UnitTestIndexTestDocumentF() + { + Id = Guid.Parse(id), + Name = name + }); + + var wql = IndexManager.Retrieve($"name = '{name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the add function of the index manager. + /// + [Theory] + [InlineData("9733A649-1E5E-4B1F-8C6E-9A4B6AB54292", "🌟🍀🐉")] + public void NotAdd(string id, string name) + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Insert(new UnitTestIndexTestDocumentF() + { + Id = Guid.Parse(id), + Name = name + }); + + var wql = IndexManager.Retrieve($"name = '{name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.Empty(item); + + // postconditions + Postconditions(); + } + + /// + /// Tests the update function of the index manager. + /// + [Fact] + public void Update() + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + IndexManager.Update(new UnitTestIndexTestDocumentF() + { + Id = randomItem.Id, + Name = "Aurora" + }); + + var wql = IndexManager.Retrieve("name = 'Aurora'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests the update function of the index manager. + /// + [Fact] + public async Task UpdateAsync() + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + await IndexManager.ReIndexAsync(Fixture.TestData); + + // test execution + await IndexManager.UpdateAsync(new UnitTestIndexTestDocumentF() + { + Id = randomItem.Id, + Name = "Aurora" + }); + + var wql = IndexManager.Retrieve("name = 'Aurora'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + Assert.Equal(1, item.Count()); + + // postconditions + Postconditions(); + } + + /// + /// Tests removing a document on the index manager. + /// + [Fact] + public void Clear() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + var documents = IndexManager.All(); + + Assert.NotNull(documents); + Assert.True(documents.Any()); + + // test execution + IndexManager.Clear(); + + documents = IndexManager.All(); + + Assert.NotNull(documents); + Assert.False(documents.Any()); + + // postconditions + Postconditions(); + } + + /// + /// Return all entries of the index manager. + /// + [Fact] + public void All() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + + // test execution + var all = IndexManager.All(); + + Assert.True(all.Select(x => x.Id).OrderBy(x => x).SequenceEqual(Fixture.TestData.Select(x => x.Id).OrderBy(x => x))); + + // postconditions + Postconditions(); + } + + /// + /// Tests get a document from the index manager. + /// + [Fact] + public void GetDocument() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + + // test execution + var document = IndexManager.GetIndexDocument(); + Assert.NotNull(document); + Assert.True(document.GetType() == typeof(IndexDocument)); + + // postconditions + Postconditions(); + } + + /// + /// Tests get a document from the index manager. + /// + [Fact] + public void GetDocument_Not() + { + // preconditions + Preconditions(); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + IndexManager.Create(CultureInfo.GetCultureInfo("en"), IndexType.Storage); + + // test execution + var document = IndexManager.GetIndexDocument(); + Assert.Null(document); + + // postconditions + Postconditions(); + } + + /// + /// Tests the close and open function from the index manager. + /// + [Theory] + [InlineData("en")] + [InlineData("de")] + [InlineData("de-DE")] + [InlineData("fr")] + public void Reopen(string culture) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + IndexManager.ReIndex(Fixture.TestData); + var wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + var item = wql.Apply(); + var count = item.Count(); + + // test execution + IndexManager.Close(); + + IndexManager.Create(CultureInfo.GetCultureInfo(culture), IndexType.Storage); + wql = IndexManager.Retrieve($"name = '{randomItem.Name}'"); + Assert.NotNull(wql); + + item = wql.Apply(); + Assert.Equal(count, item.Count()); + + // postconditions + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryA.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryA.cs index 0041b25..bb1c6de 100644 --- a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryA.cs +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryA.cs @@ -199,9 +199,9 @@ public void All() } // test execution - //var all = reverseIndex.All; + var all = reverseIndex.All; - //Assert.True(all.Select(x => x.DocumentID).SequenceEqual(data.Select(x => x.DocumentID))); + Assert.Equal(all.OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); // postconditions reverseIndex.Dispose(); diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryB.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryB.cs index 339ef38..3031b1f 100644 --- a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryB.cs +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryB.cs @@ -198,9 +198,9 @@ public void All() } // test execution - //var all = reverseIndex.All; + var all = reverseIndex.All; - //Assert.True(all.Select(x => x.DocumentID).SequenceEqual(data.Select(x => x.DocumentID))); + Assert.Equal(all.OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); // postconditions reverseIndex.Dispose(); diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryD.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryD.cs index eed2d4d..73dd66e 100644 --- a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryD.cs +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryD.cs @@ -198,9 +198,9 @@ public void All() } // test execution - //var all = reverseIndex.All; + var all = reverseIndex.All; - //Assert.True(all.Select(x => x.DocumentID).SequenceEqual(data.Select(x => x.DocumentID))); + Assert.Equal(all.OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); // postconditions reverseIndex.Dispose(); diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryE.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryE.cs index fd9d368..2b9dbab 100644 --- a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryE.cs +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryE.cs @@ -198,9 +198,9 @@ public void All() } // test execution - //var all = reverseIndex.All; + var all = reverseIndex.All; - //Assert.True(all.Select(x => x.DocumentID).SequenceEqual(data.Select(x => x.DocumentID))); + Assert.Equal(all.OrderBy(x => x), Fixture.TestData.Select(x => x.Id).OrderBy(x => x)); // postconditions reverseIndex.Dispose(); diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryF.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryF.cs new file mode 100644 index 0000000..a9c8f11 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexMemoryF.cs @@ -0,0 +1,189 @@ +using System.Globalization; +using System.Reflection; +using WebExpress.WebIndex.Memory; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.ReverseIndex +{ + /// + /// Test class for testing the memory-based reverse index for unicode. + /// + /// The log. + /// The test context. + public class UnitTestReverseIndexMemoryF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) : UnitTestReverseIndex(fixture, output) + { + /// + /// Returns the property. + /// + protected static PropertyInfo Property => typeof(UnitTestIndexTestDocumentF).GetProperty("Name"); + + /// + /// Creates a reverse index. + /// + [Fact] + public void Create() + { + // preconditions + Preconditions(); + + // test execution + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Adds items to a reverse index. + /// + [Fact] + public void Add() + { + // preconditions + Preconditions(); + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + reverseIndex.Clear(); + + foreach (var item in Fixture.TestData) + { + // test execution + reverseIndex.Add(item); + } + + Assert.NotNull(reverseIndex); + + // postconditions + Postconditions(); + } + + /// + /// Adds a token to an existing entry in the reverse index. + /// + [Theory] + [InlineData("Aurora", true)] + [InlineData("😊🌸🐼", false)] + [InlineData("张伟", true)] + public void AddToken(string str, bool valid) + { + // preconditions + Preconditions(); + var doc = new UnitTestIndexTestDocumentF() { Id = Guid.Parse("9A274C29-E210-49C9-A673-238F79636CD9"), Name = str }; + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + var token = Context.TokenAnalyzer.Analyze(str, CultureInfo.GetCultureInfo("en")); + + // test execution + reverseIndex.Add(doc, token); + var item = reverseIndex.Retrieve(str, new IndexRetrieveOptions()); + + if (valid) + { + Assert.Contains(doc.Id, item); + } + else + { + Assert.Empty(item); + } + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Removes a token without deleting the entire entry. + /// + [Fact] + public void Remove() + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + reverseIndex.Clear(); + foreach (var item in Fixture.TestData) + { + reverseIndex.Add(item); + } + + var token = Context.TokenAnalyzer.Analyze("Aurora", CultureInfo.GetCultureInfo("en")); + reverseIndex.Add(randomItem, token.TakeLast(1)); + + // test execution + reverseIndex.Delete(randomItem, token.TakeLast(1)); + + var items = reverseIndex.Retrieve("aurora", new IndexRetrieveOptions()); + Assert.Empty(items); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Retrieve a entry of the reverse index. + /// + [Fact] + public void Retrieve() + { + // preconditions + Preconditions(); + var randomItem = Fixture.RandomItem; + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + reverseIndex.Clear(); + foreach (var item in Fixture.TestData) + { + // test execution + reverseIndex.Add(item); + } + + // test execution + var items = reverseIndex.Retrieve(randomItem.Name, new IndexRetrieveOptions()); + + if (randomItem.Name != "😊🌸🐼") + { + Assert.True(items.Any()); + } + else + { + Assert.Empty(items); + } + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Return all entries of the reverse index. + /// + [Fact] + public void All() + { + // preconditions + Preconditions(); + var reverseIndex = new IndexMemoryReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + reverseIndex.Clear(); + foreach (var item in Fixture.TestData) + { + // test execution + reverseIndex.Add(item); + } + + // test execution + var all = reverseIndex.All; + + Assert.Equal(all.OrderBy(x => x), Fixture.TestData.Where(x => x.Name != "😊🌸🐼").Select(x => x.Id).OrderBy(x => x)); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageF.cs b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageF.cs new file mode 100644 index 0000000..879c686 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/ReverseIndex/UnitTestReverseIndexStorageF.cs @@ -0,0 +1,136 @@ +using System.Globalization; +using System.Reflection; +using WebExpress.WebIndex.Storage; +using WebExpress.WebIndex.Test.Document; +using WebExpress.WebIndex.Test.Fixture; +using Xunit.Abstractions; + +namespace WebExpress.WebIndex.Test.ReverseIndex +{ + /// + /// Test class for testing the storage-based reverse index for unicode. + /// + /// The log. + /// The test context. + public class UnitTestReverseIndexStorageF(UnitTestIndexFixtureIndexF fixture, ITestOutputHelper output) : UnitTestReverseIndex(fixture, output) + { + /// + /// Test class for testing the storage-based reverse index. + /// + protected static PropertyInfo Property => typeof(UnitTestIndexTestDocumentF).GetProperty("Name"); + + /// + /// Creates a reverse index. + /// + [Fact] + public void Create() + { + // preconditions + Preconditions(); + + // test execution + var reverseIndex = new IndexStorageReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Adds items to a reverse index. + /// + [Theory] + [InlineData("ED242C79-E41B-4214-BFBC-C4673E87433B", "Aurora", true)] + [InlineData("A20BC371-10F9-4F43-9DA8-F4B4F0BE26AB", "李明", true)] + [InlineData("9733A649-1E5E-4B1F-8C6E-9A4B6AB54292", "🌟🍀🐉", false)] + [InlineData("80A78EBB-9819-45AF-BC0F-68E68D0C8C1A", "Sun Leaf Lion 🌞🌿🦁", true)] + [InlineData("29F34DFD-432D-4315-88C2-CE41F293AC71", "🦋🌼🌙 Butterfly Flower Moon", true)] + public void Add(string id, string name, bool valid) + { + // preconditions + Preconditions(); + var doc = new UnitTestIndexTestDocumentF() { Id = Guid.Parse(id), Name = name }; + var reverseIndex = new IndexStorageReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + // test execution + reverseIndex.Add(new UnitTestIndexTestDocumentF() { Id = Guid.Parse(id), Name = name }); + + Assert.NotNull(reverseIndex); + + var items = reverseIndex.Retrieve(name, new IndexRetrieveOptions()); + + if (valid) + { + Assert.Contains(doc.Id, items); + } + else + { + Assert.Empty(items); + } + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Removes a token without deleting the entire entry. + /// + [Theory] + [InlineData("Aurora")] + [InlineData("张伟")] + public void Remove(string str) + { + // preconditions + Preconditions(); + var randomItem = Fixture.TestData?.LastOrDefault(); + var reverseIndex = new IndexStorageReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + + foreach (var item in Fixture.TestData) + { + reverseIndex.Add(item); + } + + var token = Context.TokenAnalyzer.Analyze(str, CultureInfo.GetCultureInfo("en")); + reverseIndex.Add(randomItem, token.TakeLast(1)); + + // test execution + reverseIndex.Delete(randomItem, token.TakeLast(1)); + + var items = reverseIndex.Retrieve(str, new IndexRetrieveOptions()); + Assert.Empty(items); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + + /// + /// Retrieve a entry of the reverse index. + /// + [Theory] + [InlineData("张伟", IndexRetrieveMethod.Phrase)] + public void Retrieve(string str, IndexRetrieveMethod method) + { + // preconditions + Preconditions(); + var reverseIndex = new IndexStorageReverse(Context, Property, CultureInfo.GetCultureInfo("en")); + var option = new IndexRetrieveOptions() { Method = method }; + + foreach (var item in Fixture.TestData) + { + // test execution + reverseIndex.Add(item); + } + + // test execution + var items = reverseIndex.Retrieve(str, option); + + Assert.NotEmpty(items); + + // postconditions + reverseIndex.Dispose(); + Postconditions(); + } + } +} diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocument.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocument.cs index ff8236e..4593438 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocument.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocument.cs @@ -1,8 +1,10 @@ -using System.Text; -using WebExpress.WebIndex.WebAttribute; +using WebExpress.WebIndex.WebAttribute; namespace WebExpress.WebIndex.Test.Document { + /// + /// Abstract class representing a unit test document for index testing. + /// public abstract class UnitTestIndexTestDocument : IIndexItem { /// diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentF.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentF.cs new file mode 100644 index 0000000..6d36844 --- /dev/null +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentF.cs @@ -0,0 +1,24 @@ +namespace WebExpress.WebIndex.Test.Document +{ + /// + /// Represents a test document for unicode. + /// + public class UnitTestIndexTestDocumentF : UnitTestIndexTestDocument + { + /// + /// Returns or sets the name. + /// + public string Name { get; set; } + + /// + /// Convert the object into a string representation. + /// + /// + /// A string that represents the current object. + /// + public override string ToString() + { + return $"{Id} - {Name}"; + } + } +} diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactory.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactory.cs index e8ad0ab..52a288f 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactory.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactory.cs @@ -2,6 +2,9 @@ namespace WebExpress.WebIndex.Test.Document { + /// + /// Abstract factory class for creating unit test documents for indexing. + /// public abstract class UnitTestIndexTestDocumentFactory { /// diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryA.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryA.cs index 5042b41..44a1bc3 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryA.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryA.cs @@ -1,7 +1,7 @@ namespace WebExpress.WebIndex.Test.Document { /// - /// Represents a test document for a person. + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentA. /// public class UnitTestIndexTestDocumentFactoryA : UnitTestIndexTestDocumentFactory { diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryB.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryB.cs index 18283c6..da99209 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryB.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryB.cs @@ -1,5 +1,8 @@ namespace WebExpress.WebIndex.Test.Document { + /// + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentB. + /// public class UnitTestIndexTestDocumentFactoryB : UnitTestIndexTestDocumentFactory { /// @@ -24,7 +27,7 @@ public static List GenerateTestData() Date = DateTime.Now.AddMonths(i % 12), Price = i, New = i % 2 != 0, - Adress = new UnitTestIndexTestDocumentB.AdressClass() { City = GenerateCity(1), Zip = GenerateZip(i), Street = GenerateSreet(i)} + Adress = new UnitTestIndexTestDocumentB.AdressClass() { City = GenerateCity(1), Zip = GenerateZip(i), Street = GenerateSreet(i) } }); } diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryC.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryC.cs index fbcc66d..5063c84 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryC.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryC.cs @@ -1,5 +1,8 @@ namespace WebExpress.WebIndex.Test.Document { + /// + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentC. + /// public class UnitTestIndexTestDocumentFactoryC : UnitTestIndexTestDocumentFactory { /// diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryD.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryD.cs index d2739a5..06cb83d 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryD.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryD.cs @@ -1,5 +1,8 @@ namespace WebExpress.WebIndex.Test.Document { + /// + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentD. + /// public class UnitTestIndexTestDocumentFactoryD : UnitTestIndexTestDocumentFactory { /// diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryE.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryE.cs index c8a1e42..334eb46 100644 --- a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryE.cs +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryE.cs @@ -1,7 +1,7 @@ namespace WebExpress.WebIndex.Test.Document { /// - /// Represents a test document for a person. + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentE. /// public class UnitTestIndexTestDocumentFactoryE : UnitTestIndexTestDocumentFactory { @@ -139,9 +139,13 @@ public static List GenerateTestData() { Id = Guid.Parse("160a6cba-5f74-4d0d-939a-5e0764276b04"), Name = "Lars" + }, + new () + { + Id = Guid.Parse("4fa7861e-54cd-408c-8651-0dd05cb94bd1"), + Name = "René" } - }; return testDataList; diff --git a/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryF.cs b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryF.cs new file mode 100644 index 0000000..797c68a --- /dev/null +++ b/src/WebExpress.WebIndex.Test/TestDocument/UnitTestIndexTestDocumentFactoryF.cs @@ -0,0 +1,34 @@ +namespace WebExpress.WebIndex.Test.Document +{ + /// + /// Factory class for creating unit test documents of type UnitTestIndexTestDocumentF. + /// + public class UnitTestIndexTestDocumentFactoryF : UnitTestIndexTestDocumentFactory + { + /// + /// Generates a list of test data for unit testing. + /// + /// + /// A list of objects. + /// + public static List GenerateTestData() + { + var testDataList = new List + { + new () + { + Id = Guid.Parse("c3d50744-5d66-422c-a0ab-ff024c1eacfc"), + Name = "😊🌸🐼" + }, + new () + { + Id = Guid.Parse("98714568-2925-46a0-b9ea-999a94ef07b4"), + Name = "张伟" + } + + }; + + return testDataList; + } + } +} diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs index 0af4e74..27fb125 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexAnalyze.cs @@ -30,100 +30,39 @@ public UnitTestIndexAnalyze(UnitTestIndexFixtureToken fixture, ITestOutputHelper /// /// Tests the analysis function of an supported language. /// - [Fact] - public void Analyze1_En() + [Theory] + [InlineData("en", "abc def, ghi jkl mno-p.", "abc", "def", "ghi", "jkl", "mno-p")] + [InlineData("en", "abc 😊🌸🐼, ghi jkl mno-p.", "abc", "ghi", "jkl", "mno-p")] + [InlineData("en", "??? ??")] + [InlineData("en", "???... ")] + [InlineData("en", "theya??r", "theya")] + [InlineData("en", "http://example.com/abc", "http", "example", "com", "abc")] + public void Token(string culture, string input, params string[] expected) { - // preconditions - var input = "abc def, ghi jkl mno-p."; - - // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("en")); - - Assert.Equal(5, tokens.Count()); - Assert.True(tokens.First().Position == 0); - Assert.Equal("abc", tokens.First().Value); - Assert.True(tokens.Skip(1).First().Position == 1); - Assert.Equal("def", tokens.Skip(1).First().Value); - Assert.True(tokens.Skip(2).First().Position == 2); - Assert.Equal("ghi", tokens.Skip(2).First().Value); - Assert.True(tokens.Skip(3).First().Position == 3); - Assert.Equal("jkl", tokens.Skip(3).First().Value); - Assert.True(tokens.Skip(4).First().Position == 4); - Assert.Equal("mno-p", tokens.Skip(4).First().Value); - } - - /// - /// Tests the analysis function of an supported language. - /// - [Fact] - public void Analyze2_En() - { - // preconditions - var input = Fixture.GetRessource("JourneyThroughTheUniverse.en"); - // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("en")); + var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo(culture)); - Assert.Equal(241, tokens.Count()); // of 546 + Assert.Equal(expected, tokens.Select(x => x.Value)); } /// /// Tests the analysis function of an supported language. /// - [Fact] - public void Analyze3_En() - { - var input = Fixture.GetRessource("InterstellarConversations.en"); - - // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("en")); - - Assert.Equal(170, tokens.Count()); // of 281 - } - - /// - /// Tests the analysis function of an supported language. - /// - [Fact] - public void Analyze_De() - { - // preconditions - var input = Fixture.GetRessource("BotanischeBindungenMicrosReiseZuVerdantia.de"); - - // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("de")); - - Assert.Equal(418, tokens.Count()); // of 731 - } - - /// - /// Tests the analysis function of a regional language. - /// - [Fact] - public void Analyze_DeDE() - { - // preconditions - var input = Fixture.GetRessource("BotanischeBindungenMicrosReiseZuVerdantia.de"); - - // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("de-DE")); - - Assert.Equal(418, tokens.Count()); // of 731 - } - - /// - /// Tests the analysis function of an unsupported language. - /// - [Fact] - public void Analyze_Fr() + [Theory] + [InlineData("en", "JourneyThroughTheUniverse.en", 241)] + [InlineData("en", "InterstellarConversations.en", 165)] + [InlineData("de", "BotanischeBindungenMicrosReiseZuVerdantia.de", 392)] + [InlineData("de-DE", "BotanischeBindungenMicrosReiseZuVerdantia.de", 392)] + [InlineData("fr", "BotanischeBindungenMicrosReiseZuVerdantia.de", 716)] + public void Ressource(string culture, string ressource, int count) { // preconditions - var input = Fixture.GetRessource("BotanischeBindungenMicrosReiseZuVerdantia.de"); + var input = Fixture.GetRessource(ressource); // test execution - var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo("fr")); + var tokens = Fixture.TokenAnalyzer.Analyze(input, CultureInfo.GetCultureInfo(culture)); - Assert.Equal(719, tokens.Count()); // of 731 + Assert.Equal(count, tokens.Count()); } } } diff --git a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs index 59ad4ce..80051df 100644 --- a/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs +++ b/src/WebExpress.WebIndex.Test/Token/UnitTestIndexPipeStageStopWord.cs @@ -32,51 +32,38 @@ public UnitTestIndexPipeStageStopWord(UnitTestIndexFixtureToken fixture, ITestOu /// /// Tests the stop word method. This function is part of the stemming process and removes stop words. /// - [Fact] - public void StopWord_En() + [InlineData + ( + "en", + "May the force be with you.", + "may", "the", "be", "with", "you" + )] + [Theory] + [InlineData + ( + "de", + "Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt.", + "als", "eines", "aus", "er", "sich", "in", "seinem", "zu", "einem" + )] + [InlineData + ( + "en", + "😊🌸🐼", + null + )] + public void StopWord(string cultureStr, string str, params string[] tokenStr) { - var culture = CultureInfo.GetCultureInfo("en"); + var culture = CultureInfo.GetCultureInfo(cultureStr); var pipeStage = new IndexPipeStageFilterStopWord(Fixture.Context); - var token = IndexTermTokenizer.Tokenize("May the force be with you.", culture); + var token = IndexTermTokenizer.Tokenize(str.ToLower(), culture); var res = pipeStage.Process(token, culture) .Select(x => x.Value) .ToList(); - Assert.DoesNotContain("the", res); - Assert.DoesNotContain("be", res); - Assert.DoesNotContain("with", res); - - Assert.True(token.Count() - 3 == res.Count); - } - - /// - /// Tests the stop word method. This function is part of the stemming process and removes stop words. - /// - [Fact] - public void StopWord_De() - { - var culture = CultureInfo.GetCultureInfo("de"); - var pipeStage = new IndexPipeStageFilterStopWord(Fixture.Context); - - var token = IndexTermTokenizer.Tokenize("Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt.".ToLower(), culture); - - var res = pipeStage.Process(token, culture) - .Select(x => x.Value) - .ToList(); - - Assert.DoesNotContain("als", res); - Assert.DoesNotContain("eines", res); - Assert.DoesNotContain("aus", res); - Assert.DoesNotContain("er", res); - Assert.DoesNotContain("sich", res); - Assert.DoesNotContain("in", res); - Assert.DoesNotContain("seinem", res); - Assert.DoesNotContain("zu", res); - Assert.DoesNotContain("einem", res); - - Assert.True(token.Count() - 9 == res.Count); + Assert.DoesNotContain(tokenStr, res); + Assert.True(token.Count() - (tokenStr?.Length ?? 0) == res.Count); } } } diff --git a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj index 3daa2ff..cbda14f 100644 --- a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj +++ b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj @@ -22,6 +22,10 @@ + + + + diff --git a/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs b/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs index 457daf8..62f2ca7 100644 --- a/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs +++ b/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs @@ -56,7 +56,10 @@ public bool CreateIndexFile(string indexFile) var runtimeClass = CurrentObjectType.BuildRuntimeClass(); var context = new IndexContext { IndexDirectory = CurrentDirectory }; IndexManager = new IndexManager(); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManager).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); IndexManager.Create(runtimeClass, CultureInfo.GetCultureInfo("en"), IndexType.Storage); @@ -81,7 +84,10 @@ public bool OpenIndexFile(string indexFile) var context = new IndexContext { IndexDirectory = CurrentDirectory }; IndexManager = new IndexManager(); - IndexManager.Initialization(context); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManager).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(IndexManager, [context]); IndexManager.Create(runtimeClass, CultureInfo.GetCultureInfo("en"), IndexType.Storage); diff --git a/src/WebExpress.WebIndex/Asstes/StopWords.de b/src/WebExpress.WebIndex/Asstes/StopWords.de index 39cf6e2..45b0b92 100644 --- a/src/WebExpress.WebIndex/Asstes/StopWords.de +++ b/src/WebExpress.WebIndex/Asstes/StopWords.de @@ -1,4 +1,5 @@ # Stoppwörter. Ein Stoppwort pro Zeile. +a aber abermals absolut @@ -68,6 +69,7 @@ außerdem ähnlichsten ähnlichster ähnlichstes +b beide beidem beiden @@ -136,6 +138,7 @@ bricht bringt baut brennt +c circa charakterisiert charmant @@ -150,6 +153,7 @@ cooperativ couragiert creativ cynisch +d dabei dadurch dafür @@ -325,6 +329,7 @@ durchschnittlich durchsichtig durstig dynamisch +e eben ebenso ehrlich @@ -439,6 +444,7 @@ exotisch exquisit extrem extravagant +f falls fast ferner @@ -481,6 +487,7 @@ funktional furchtlos fürsorglich füllig +g gegen gegenüber gehabt @@ -551,6 +558,7 @@ grün günstig gut gültig +h hab habe haben @@ -595,6 +603,7 @@ hohl hungrig hurtig hygienisch +i ich ihm ihn @@ -660,6 +669,7 @@ irreal irrelevant irritierend isoliert +j ja jahr jahre @@ -704,7 +714,8 @@ jüngst jüngste jüngsten jüngster -jüngstes, +jüngstes +k kam kann konnte @@ -738,6 +749,7 @@ kurze kurzen kurzer kurzes +l lange länger längst @@ -748,7 +760,8 @@ lediglich leider ließ liegt -los, +los +m machen macht machte @@ -796,10 +809,12 @@ müssen musste müssen müsste +n nach nachdem nahm natürlich +nbsp neben nein neue @@ -818,20 +833,25 @@ niemanden noch nun nur +o ob oben oder offen oft -ohne, +ohne +p per pfui plötzlich prinzipiell pro +q quasi +r rund rief +s sagte sah satt @@ -890,6 +910,7 @@ such suche suchen sucht +t tage tagen tat @@ -898,6 +919,7 @@ tel tritt trotzdem tun +u über überhaupt übrigens @@ -906,6 +928,7 @@ und uns unserer unter +v vergangenen vergangener vergangenes @@ -917,6 +940,7 @@ vor vorbei vorher völlig +w während wann war @@ -948,6 +972,9 @@ wohl wollen wollte würden +x +y +z zehn zehnte zehnten diff --git a/src/WebExpress.WebIndex/Asstes/StopWords.en b/src/WebExpress.WebIndex/Asstes/StopWords.en index 1f0bb2b..a3fd2b3 100644 --- a/src/WebExpress.WebIndex/Asstes/StopWords.en +++ b/src/WebExpress.WebIndex/Asstes/StopWords.en @@ -14,6 +14,7 @@ are aren't as at +b be because been @@ -27,12 +28,14 @@ beyond both but by +c can cannot concerning considering could could've +d despite did did've @@ -45,6 +48,7 @@ doing don't down during +e each else enough @@ -56,6 +60,7 @@ everybody everyone everything everywhere +f few for from @@ -75,6 +80,7 @@ four from further furthermore +g get given gives @@ -85,6 +91,7 @@ gone got gotten greetings +h had hadn't has @@ -134,8 +141,10 @@ it it's its itself +j just justly +k keep keeps kept @@ -143,6 +152,7 @@ kindly know known knows +l last latter latterly @@ -153,6 +163,7 @@ let's like likely little +m mainly many may @@ -170,7 +181,9 @@ much must my myself +n namely +nbsp near nearly necessarily @@ -189,6 +202,7 @@ nothing notwithstanding now nowhere +o obviously of off @@ -209,6 +223,7 @@ out over overall own +p particular particularly per @@ -221,6 +236,7 @@ presumably probably provided provides +q quasi quarter queen @@ -231,6 +247,7 @@ quit quite quoth quote +r readily really recent @@ -246,6 +263,7 @@ resulting right round roughly +s same saw say @@ -287,6 +305,7 @@ soon still such sure +t take taken taking @@ -345,6 +364,7 @@ try trying twice two +u underneath understand understood @@ -362,6 +382,7 @@ useful uses using usually +v value various very @@ -372,6 +393,7 @@ vast virtually visible voluntarily +w want was way @@ -417,10 +439,14 @@ who's why's won't wouldn't +x +y you you'd you'll +you'r you're +you'v you've your yours @@ -439,4 +465,5 @@ you've your yours yourself -yourselves \ No newline at end of file +yourselves +z \ No newline at end of file diff --git a/src/WebExpress.WebIndex/IndexManager.cs b/src/WebExpress.WebIndex/IndexManager.cs index eb079f3..688f83b 100644 --- a/src/WebExpress.WebIndex/IndexManager.cs +++ b/src/WebExpress.WebIndex/IndexManager.cs @@ -3,12 +3,15 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using WebExpress.WebIndex.Term; using WebExpress.WebIndex.Term.Pipeline; using WebExpress.WebIndex.Wql; +[assembly: InternalsVisibleTo("WebExpress.WebIndex.Test")] + namespace WebExpress.WebIndex { /// @@ -47,7 +50,7 @@ public IndexManager() /// Initialization of the IndexManager. /// /// The reference to the context. - public void Initialization(IIndexContext context) + protected void Initialization(IIndexContext context) { Context = context; Directory.CreateDirectory(Context.IndexDirectory); diff --git a/src/WebExpress.WebIndex/Storage/IIndexStorageSegment.cs b/src/WebExpress.WebIndex/Storage/IIndexStorageSegment.cs index 6a72f0f..e30fa75 100644 --- a/src/WebExpress.WebIndex/Storage/IIndexStorageSegment.cs +++ b/src/WebExpress.WebIndex/Storage/IIndexStorageSegment.cs @@ -2,6 +2,9 @@ namespace WebExpress.WebIndex.Storage { + /// + /// Interface for managing index storage segments. + /// public interface IIndexStorageSegment { /// diff --git a/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentChunk.cs b/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentChunk.cs index f47725a..1233533 100644 --- a/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentChunk.cs +++ b/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentChunk.cs @@ -2,6 +2,9 @@ namespace WebExpress.WebIndex.Storage { + /// + /// Represents a chunk of an index storage segment that can be compared and has an address of the next chunk. + /// public interface IIndexStorageSegmentChunk : IIndexStorageSegment, IComparable { /// diff --git a/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentListItem.cs b/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentListItem.cs index 6ca3e32..01a951b 100644 --- a/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentListItem.cs +++ b/src/WebExpress.WebIndex/Storage/IIndexStorageSegmentListItem.cs @@ -2,6 +2,9 @@ namespace WebExpress.WebIndex.Storage { + /// + /// Interface for managing index storage segment list items. + /// public interface IIndexStorageSegmentListItem : IIndexStorageSegment, IComparable { /// diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs b/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs index 48e9b96..f787fda 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageBuffer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading; namespace WebExpress.WebIndex.Storage @@ -61,8 +62,8 @@ public IndexStorageBuffer(IndexStorageFile file) _imperishableCache = new Dictionary((int)MaxCachedSegments); _writeCache = new Dictionary((int)MaxCachedSegments); - Reader = new BinaryReader(file.FileStream); - Writer = new BinaryWriter(file.FileStream); + Reader = new BinaryReader(file.FileStream, Encoding.UTF8); + Writer = new BinaryWriter(file.FileStream, Encoding.UTF8); Timer = new Timer((state) => { @@ -84,7 +85,10 @@ public T Read(ulong addr, IndexStorageContext context) where T : IIndexStorag { if (GetSegment(addr, out IIndexStorageSegment readCached)) { - return (T)readCached; + if (readCached is T cachedSegment) + { + return cachedSegment; + } } var segment = (T)Activator.CreateInstance(typeof(T), context, addr); diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs index 647dcfb..ae2a114 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageDocumentStore.cs @@ -14,6 +14,9 @@ namespace WebExpress.WebIndex.Storage /// The data type. This must have the IIndexItem interface. public class IndexStorageDocumentStore : IIndexDocumentStore, IIndexStorage where T : IIndexItem { + private readonly string _extentions = "wds"; + private readonly int _version = 1; + /// /// Returns the file name for the reverse index. /// @@ -74,11 +77,11 @@ public IndexStorageDocumentStore(IIndexContext context, uint capacity) Context = context; StorageContext = new IndexStorageContext(this); Capacity = capacity; - FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.wds"); + FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.{_extentions}"); var exists = File.Exists(FileName); IndexFile = new IndexStorageFile(FileName); - Header = new IndexStorageSegmentHeader(StorageContext) { Identifier = "wds" }; + Header = new IndexStorageSegmentHeader(StorageContext) { Identifier = _extentions, Version = (byte)_version }; Allocator = new IndexStorageSegmentAllocatorDocumentStore(StorageContext); Statistic = new IndexStorageSegmentStatistic(StorageContext); HashMap = new IndexStorageSegmentHashMap(StorageContext, Capacity); @@ -165,7 +168,7 @@ public void Update(T item) public void Clear() { IndexFile.NextFreeAddr = 0; - Header = new IndexStorageSegmentHeader(StorageContext) { Identifier = "wfi" }; + Header = new IndexStorageSegmentHeader(StorageContext) { Identifier = _extentions, Version = (byte)_version }; Allocator = new IndexStorageSegmentAllocatorDocumentStore(StorageContext); Statistic = new IndexStorageSegmentStatistic(StorageContext); HashMap = new IndexStorageSegmentHashMap(StorageContext, Capacity); diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs b/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs index 77c1579..9bdab63 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageReverse.cs @@ -14,6 +14,9 @@ namespace WebExpress.WebIndex.Storage /// The data type. This must have the IIndexItem interface. public class IndexStorageReverse : IIndexReverse, IIndexStorage where T : IIndexItem { + private readonly string _extentions = "wri"; + private readonly int _version = 1; + /// /// The property that makes up the index. /// @@ -75,12 +78,12 @@ public IndexStorageReverse(IIndexDocumemntContext context, PropertyInfo property Context = context; Property = property; Culture = culture; - FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.{property.Name}.wri"); + FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.{property.Name}.{_extentions}"); var exists = File.Exists(FileName); IndexFile = new IndexStorageFile(FileName); - Header = new IndexStorageSegmentHeader(new IndexStorageContext(this)) { Identifier = "wri" }; + Header = new IndexStorageSegmentHeader(new IndexStorageContext(this)) { Identifier = _extentions, Version = (byte)_version }; Allocator = new IndexStorageSegmentAllocatorReverseIndex(new IndexStorageContext(this)); Statistic = new IndexStorageSegmentStatistic(new IndexStorageContext(this)); Term = new IndexStorageSegmentTerm(new IndexStorageContext(this)); @@ -178,7 +181,7 @@ public void Clear() { IndexFile.NextFreeAddr = 0; - Header = new IndexStorageSegmentHeader(new IndexStorageContext(this)) { Identifier = "wri" }; + Header = new IndexStorageSegmentHeader(new IndexStorageContext(this)) { Identifier = _extentions, Version = (byte)_version }; Allocator = new IndexStorageSegmentAllocatorReverseIndex(new IndexStorageContext(this)); Statistic = new IndexStorageSegmentStatistic(new IndexStorageContext(this)); Term = new IndexStorageSegmentTerm(new IndexStorageContext(this)); diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSchema.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSchema.cs index 440fa39..aa3273f 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSchema.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSchema.cs @@ -13,6 +13,9 @@ namespace WebExpress.WebIndex.Storage /// The data type. This must have the IIndexItem interface. public class IndexStorageSchema : IIndexSchema where T : IIndexItem { + private readonly string _extentions = "ws"; + private readonly int _version = 1; + /// /// Returns the file name. /// @@ -24,13 +27,13 @@ public class IndexStorageSchema : IIndexSchema where T : IIndexItem public IIndexContext Context { get; private set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The index context. public IndexStorageSchema(IIndexContext context) { Context = context; - FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.ws"); + FileName = Path.Combine(Context.IndexDirectory, $"{typeof(T).Name}.{_extentions}"); if (!File.Exists(FileName)) { @@ -121,17 +124,6 @@ private object GetType(PropertyInfo property) } return "Object"; - - //return new - //{ - //Name = property.PropertyType.Name, - //Fields = property.PropertyType.GetProperties().Select(x => new - //{ - // Name = x.Name, - // Type = GetType(x), - // Ignore = Attribute.IsDefined(x, typeof(IndexIgnoreAttribute)) - //}) - //}; } /// diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs index fb47279..4d5ad8c 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHashMap.cs @@ -4,6 +4,9 @@ namespace WebExpress.WebIndex.Storage { + /// + /// Represents a hash map segment in the index storage. + /// public class IndexStorageSegmentHashMap : IndexStorageSegment { /// diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs index d649d0c..e942d17 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentHeader.cs @@ -2,12 +2,15 @@ namespace WebExpress.WebIndex.Storage { + /// + /// Represents the header segment of the index storage. + /// public class IndexStorageSegmentHeader : IndexStorageSegment { /// /// Returns the amount of space required on the storage device. /// - public const uint SegmentSize = 3; + public const uint SegmentSize = 3 + sizeof(byte); /// /// Returns or sets the file identifire. @@ -34,8 +37,18 @@ public IndexStorageSegmentHeader(IndexStorageContext context) /// The reader for i/o operations. public override void Read(BinaryReader reader) { - Identifier = new string(reader.ReadChars((int)SegmentSize)); - Version = reader.ReadByte(); + var identifier = new string(reader.ReadChars(3)); + var version = reader.ReadByte(); + + if (!Identifier.Equals(identifier)) + { + throw new IOException($"A file with the identifier '{Identifier}' is expected. However, '{identifier}' was read."); + } + + if (!Version.Equals(version)) + { + throw new IOException($"The expected file version is '{Version}', but version '{version}' was read."); + } } /// @@ -44,7 +57,7 @@ public override void Read(BinaryReader reader) /// The writer for i/o operations. public override void Write(BinaryWriter writer) { - writer.Write(Identifier.ToCharArray(0, (int)SegmentSize)); + writer.Write(Identifier.ToCharArray(0, 3)); writer.Write(Version); } } diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPostingNode.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPostingNode.cs index 75fe6f3..156689f 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPostingNode.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentPostingNode.cs @@ -426,10 +426,11 @@ public void RemovePositions() /// The reader for i/o operations. public override void Read(BinaryReader reader) { - DocumentID = new Guid(reader.ReadBytes(16)); + var guid = reader.ReadBytes(16); LeftAddr = reader.ReadUInt64(); RightAddr = reader.ReadUInt64(); PositionAddr = reader.ReadUInt64(); + DocumentID = new Guid(guid); } /// diff --git a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentTermNode.cs b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentTermNode.cs index 63915f4..21c5b87 100644 --- a/src/WebExpress.WebIndex/Storage/IndexStorageSegmentTermNode.cs +++ b/src/WebExpress.WebIndex/Storage/IndexStorageSegmentTermNode.cs @@ -23,7 +23,7 @@ public class IndexStorageSegmentTermNode(IndexStorageContext context, ulong addr /// /// Returns the amount of space required on the storage device. /// - public const uint SegmentSize = sizeof(char) + sizeof(ulong) + sizeof(ulong) + sizeof(uint) + sizeof(ulong); + public const uint SegmentSize = sizeof(uint) + sizeof(ulong) + sizeof(ulong) + sizeof(uint) + sizeof(ulong); /// /// Returns or sets the character of the node. @@ -72,9 +72,9 @@ public IEnumerable Children while (addr != 0) { var item = Context.IndexFile.Read(addr, Context); - yield return item; - addr = item.SiblingAddr; + + yield return item; } } } @@ -390,6 +390,7 @@ private IndexStorageSegmentTermNode AddChild(IndexStorageSegmentTermNode node) ChildAddr = node.Addr; Context.IndexFile.Write(this); + Context.IndexFile.Write(node); } else { @@ -464,7 +465,7 @@ internal virtual IEnumerable GetPostings(string { foreach (var node in GetLeafs(term)) { - foreach (var posting in node.Posting?.PreOrder ?? Enumerable.Empty()) + foreach (var posting in node.Posting?.PreOrder ?? []) { yield return posting; } @@ -533,7 +534,7 @@ public virtual IEnumerable GetLeafs(string term) /// The reader for i/o operations. public override void Read(BinaryReader reader) { - Character = reader.ReadChar(); + Character = (char)reader.ReadUInt32(); SiblingAddr = reader.ReadUInt64(); ChildAddr = reader.ReadUInt64(); Fequency = reader.ReadUInt32(); @@ -546,7 +547,7 @@ public override void Read(BinaryReader reader) /// The writer for i/o operations. public override void Write(BinaryWriter writer) { - writer.Write(Character); + writer.Write((uint)Character); writer.Write(SiblingAddr); writer.Write(ChildAddr); writer.Write(Fequency); diff --git a/src/WebExpress.WebIndex/Term/IndexTermTokenizer.cs b/src/WebExpress.WebIndex/Term/IndexTermTokenizer.cs index b93cb49..2304108 100644 --- a/src/WebExpress.WebIndex/Term/IndexTermTokenizer.cs +++ b/src/WebExpress.WebIndex/Term/IndexTermTokenizer.cs @@ -13,7 +13,7 @@ public static class IndexTermTokenizer /// /// Enumeration of separators. /// - private static char[] Delimiters { get; } = ['?', '!', ':', '<', '>', '=', '%', '(', ')', '"', '“', '”', '\'']; + private static char[] Delimiters { get; } = ['?', '!', '&', ':', ';', '<', '>', '=', '|', '%', '(', ')', '"', '“', '”', '/', '.', '␦', '\'']; /// /// Enumeration of wildcards. From 23d258c9de565812ce199798785c05706894cef8 Mon Sep 17 00:00:00 2001 From: Rene Schwarzer Date: Sat, 11 Jan 2025 17:38:16 +0100 Subject: [PATCH 05/23] add webindex explorer --- doc/concept.md | 717 +- .../WebExpress.WebIndex.Test.csproj | 4 +- src/WebExpress.WebIndex.Wi/Model/ViewModel.cs | 5 +- src/WebExpress.WebIndex.WiUI/App.xaml | 19 + src/WebExpress.WebIndex.WiUI/App.xaml.cs | 15 + src/WebExpress.WebIndex.WiUI/AppShell.xaml | 20 + src/WebExpress.WebIndex.WiUI/AppShell.xaml.cs | 10 + .../Converters/FieldTypeConverter.cs | 28 + .../Converters/NullToBooleanConverter.cs | 38 + src/WebExpress.WebIndex.WiUI/IndexManager.cs | 142 + src/WebExpress.WebIndex.WiUI/MauiProgram.cs | 27 + src/WebExpress.WebIndex.WiUI/Model/Field.cs | 28 + .../Model/FieldType.cs | 106 + src/WebExpress.WebIndex.WiUI/Model/Index.cs | 18 + .../Model/MainViewModel.cs | 293 + .../Model/ObjectType.cs | 134 + src/WebExpress.WebIndex.WiUI/Model/Project.cs | 60 + .../Model/ProjectService.cs | 60 + .../Model/ProjectViewModel.cs | 116 + src/WebExpress.WebIndex.WiUI/Model/Term.cs | 38 + .../Pages/MainPage.xaml | 193 + .../Pages/MainPage.xaml.cs | 82 + .../Pages/ProjectPage.xaml | 72 + .../Pages/ProjectPage.xaml.cs | 19 + .../Platforms/Android/AndroidManifest.xml | 6 + .../Platforms/Android/MainActivity.cs | 11 + .../Platforms/Android/MainApplication.cs | 16 + .../Android/Resources/values/colors.xml | 6 + .../Platforms/MacCatalyst/AppDelegate.cs | 10 + .../Platforms/MacCatalyst/Entitlements.plist | 14 + .../Platforms/MacCatalyst/Info.plist | 38 + .../Platforms/MacCatalyst/Program.cs | 16 + .../Platforms/Tizen/Main.cs | 17 + .../Platforms/Tizen/tizen-manifest.xml | 15 + .../Platforms/Windows/App.xaml | 8 + .../Platforms/Windows/App.xaml.cs | 25 + .../Platforms/Windows/Package.appxmanifest | 46 + .../Platforms/Windows/app.manifest | 15 + .../Platforms/iOS/AppDelegate.cs | 10 + .../Platforms/iOS/Info.plist | 32 + .../Platforms/iOS/Program.cs | 16 + .../iOS/Resources/PrivacyInfo.xcprivacy | 51 + .../Properties/launchSettings.json | 8 + .../Resources/AppIcon/appicon.svg | 4 + .../Resources/AppIcon/appiconfg.svg | 8 + .../Resources/Fonts/FluentUI.cs | 7921 +++++++++++++++++ .../Resources/Fonts/OpenSans-Regular.ttf | Bin 0 -> 107280 bytes .../Resources/Fonts/OpenSans-Semibold.ttf | Bin 0 -> 111184 bytes .../Resources/Images/dotnet_bot.png | Bin 0 -> 93437 bytes .../Resources/Raw/AboutAssets.txt | 15 + .../Resources/Splash/splash.svg | 8 + .../Resources/Styles/Colors.xaml | 45 + .../Resources/Styles/Styles.xaml | 451 + .../WebExpress.WebIndex.WiUI.csproj | 83 + src/WebExpress.WebIndex.sln | 7 + src/WebExpress.WebIndex/IndexManager.cs | 7 +- .../Storage/IndexStorageSegmentHeader.cs | 2 +- 57 files changed, 10792 insertions(+), 363 deletions(-) create mode 100644 src/WebExpress.WebIndex.WiUI/App.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/App.xaml.cs create mode 100644 src/WebExpress.WebIndex.WiUI/AppShell.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/AppShell.xaml.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Converters/FieldTypeConverter.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Converters/NullToBooleanConverter.cs create mode 100644 src/WebExpress.WebIndex.WiUI/IndexManager.cs create mode 100644 src/WebExpress.WebIndex.WiUI/MauiProgram.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/Field.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/FieldType.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/Index.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/MainViewModel.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/ObjectType.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/Project.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/ProjectService.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/ProjectViewModel.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Model/Term.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Pages/ProjectPage.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/Pages/ProjectPage.xaml.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Android/AndroidManifest.xml create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Android/MainActivity.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Android/MainApplication.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Android/Resources/values/colors.xml create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/MacCatalyst/AppDelegate.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/MacCatalyst/Entitlements.plist create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/MacCatalyst/Info.plist create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/MacCatalyst/Program.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Tizen/Main.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Tizen/tizen-manifest.xml create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Windows/App.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Windows/App.xaml.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Windows/Package.appxmanifest create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/Windows/app.manifest create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/iOS/AppDelegate.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/iOS/Info.plist create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/iOS/Program.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Platforms/iOS/Resources/PrivacyInfo.xcprivacy create mode 100644 src/WebExpress.WebIndex.WiUI/Properties/launchSettings.json create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/AppIcon/appicon.svg create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/AppIcon/appiconfg.svg create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Fonts/FluentUI.cs create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Fonts/OpenSans-Regular.ttf create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Fonts/OpenSans-Semibold.ttf create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Images/dotnet_bot.png create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Raw/AboutAssets.txt create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Splash/splash.svg create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Styles/Colors.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/Resources/Styles/Styles.xaml create mode 100644 src/WebExpress.WebIndex.WiUI/WebExpress.WebIndex.WiUI.csproj diff --git a/doc/concept.md b/doc/concept.md index 9fead52..dd77cbd 100644 --- a/doc/concept.md +++ b/doc/concept.md @@ -28,15 +28,15 @@ allows for a fast and efficient search, as the time-consuming part is carried ou search consists only of quick lookup operations in the reverse index. ``` - ┌──────────┐ indexing - │ document ├──────────────┐ - └──────────┘ │ - ▼ - ┌───────┐ searching ┌───────────┐ ┌─────────────────────────────────────────────────┐ ╔══════════╗ - │ query ├──────────>│ tokenizer ├──────>│ stemming, lemmatization & stoppword filter pipe ├──────>║ WebIndex ║ - └───────┘ └───────────┘ └─────────────────────────────────────────────────┘ ╚══════════╝ - ▲ results │ - └───────────────────────────────────────────────────────────────────────────────────────────────────┘ +┌──────────┐ indexing +│ document ├──────────────┐ +└──────────┘ │ + ▼ +┌───────┐ searching ┌───────────┐ ┌─────────────────────────────────────────────────┐ ╔══════════╗ +│ query ├──────────>│ tokenizer ├──────>│ stemming, lemmatization & stoppword filter pipe ├──────>║ WebIndex ║ +└───────┘ └───────────┘ └─────────────────────────────────────────────────┘ ╚══════════╝ + ▲ results │ + └───────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` Stemming and lemmatization are text preprocessing techniques in natural language processing (NLP). They reduce the inflected forms of @@ -58,131 +58,131 @@ In this instance, indexing is performed on two documents by executing a series o stop-word removal. The outcome of these operations is a multi-dimensional table, which serves as a representation of the reverse index. ``` - ┌document a────────────────────────────────────────┐ ┌document b────────────────────────────────────────┐ - │ No, fine, no , good, fine, good. You know Marty, │ │ Thanks a lot, kid. Now, of course not, Biff, now,│ - │ you look so familiar, do I know your mother? Hey │ │ I wouldn't want that to happen. I'm gonna ram │ - │ man, the dance is over. Unless you know someone │ │ him. Well, Marty, I want to thank you for all │ - │ else who could play the guitar. Who's are these? │ │ your good advice, I'll never forget it. Doc, │ - │ Maybe you were adopted. │ │ look, all we need is a little plutonium. │ - └──────────────────────┬───────────────────────────┘ └──────────────────────┬───────────────────────────┘ - │ │ - │ │ - ▼ ▼ - ┌normalized document a─────────────────────────────┐ ┌normalized document b─────────────────────────────┐ - │ no fine no good fine good you know marty │ │ thank a lot kid now of course not biff now │ - │ you look so familiar do i know your mother hey │ │ i would not want that to happen i am gonna ram │ - │ man the dance is over unless you know someone │ │ him well marty i want to thank you for all │ - │ else who could play the guitar who is are these │ │ your good advice i will never forget it doc │ - │ maybe you were adopted │ │ look all we need is a little plutonium │ - └──────────────────────┬───────────────────────────┘ └──────────────────────┬───────────────────────────┘ - │ │ - │ │ - ▼ ▼ - ┌stopword cleaned document a───────────────────────┐ ┌stopword cleaned document b───────────────────────┐ - │ fine good fine good know marty │ │ thank lot kid course biff │ - │ look familiar know mother │ │ would want happen gonna ram │ - │ dance unless know someone │ │ well marty want thank │ - │ else could play guitar these │ │ good advice never forget doc │ - │ maybe adopted │ │ look need little plutonium │ - └─────────────────────┬────────────────────────────┘ └─────────────────────┬────────────────────────────┘ +┌document a────────────────────────────────────────┐ ┌document b────────────────────────────────────────┐ +│ No, fine, no , good, fine, good. You know Marty, │ │ Thanks a lot, kid. Now, of course not, Biff, now,│ +│ you look so familiar, do I know your mother? Hey │ │ I wouldn't want that to happen. I'm gonna ram │ +│ man, the dance is over. Unless you know someone │ │ him. Well, Marty, I want to thank you for all │ +│ else who could play the guitar. Who's are these? │ │ your good advice, I'll never forget it. Doc, │ +│ Maybe you were adopted. │ │ look, all we need is a little plutonium. │ +└──────────────────────┬───────────────────────────┘ └──────────────────────┬───────────────────────────┘ │ │ │ │ - └───────────────┐ ┌─────────────────┘ - ▼ ▼ - ╔WebIndex═══════════════════════════════════════╗ - ║ Term │ Fequency │ Documnet │ Position ║ - ║═══════════════════════════════════════════════║ - ║ adopted │ 1 │ a │ 211 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ advice │ 1 │ b │ 153 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ biff │ 1 │ b │ 40 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ could │ 1 │ a │ 156 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ course │ 1 │ b │ 28 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ dance │ 1 │ a │ 108 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ doc │ 1 │ b │ 183 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ else │ 1 │ a │ 147 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ familiar │ 1 │ a │ 62 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ fine │ 2 │ a │ 5 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ forget │ 1 │ b │ 22 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ gonna │ 1 │ b │ 87 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ good │ 3 │ a │ 16, 28 ║ - ║ │ │ b │ 148 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ guitar │ 1 │ a │ 171 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ happen │ 1 │ b │ 75 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ kid │ 1 │ b │ 15 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ know │ 3 │ a │ 38, 77, 134 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ little │ 1 │ b │ 211 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ look │ 2 │ a │ 54 ║ - ║ │ │ b │ 188 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ lot │ 1 │ b │ 10 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ marty │ 2 │ a │ 43 ║ - ║ │ │ b │ 108 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ maybe │ 1 │ a │ 196 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ mother │ 1 │ a │ 87 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ need │ 1 │ b │ 201 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ never │ 1 │ b │ 166 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ play │ 1 │ a │ 162 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ plutonium │ 1 │ b │ 218 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ ram │ 1 │ b │ 93 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ someone │ 1 │ a │ 139 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ thank │ 2 │ b │ 0, 125 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ these │ 1 │ a │ 189 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ unless │ 1 │ a │ 123 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ want │ 2 │ b │ 62, 117 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ well │ 1 │ b │ 102 ║ - ║───────────┼──────────┼──────────┼─────────────║ - ║ would │ 1 │ b │ 53 ║ - ╚═══════════════════════════════════════════════╝ - ▲ - │ - │ - ┌stop word cleaned query──┐ - │ marty play guitar │ - └─────────────────────────┘ - ▲ - │ - │ - ┌normalized query─────────┐ - │ marty play the guitar │ - └─────────────────────────┘ - ▲ - │ - │ - ┌query───────┴─────────────┐ - │ 'Marty play the guitar.' │ - └──────────────────────────┘ + ▼ ▼ +┌normalized document a─────────────────────────────┐ ┌normalized document b─────────────────────────────┐ +│ no fine no good fine good you know marty │ │ thank a lot kid now of course not biff now │ +│ you look so familiar do i know your mother hey │ │ i would not want that to happen i am gonna ram │ +│ man the dance is over unless you know someone │ │ him well marty i want to thank you for all │ +│ else who could play the guitar who is are these │ │ your good advice i will never forget it doc │ +│ maybe you were adopted │ │ look all we need is a little plutonium │ +└──────────────────────┬───────────────────────────┘ └──────────────────────┬───────────────────────────┘ + │ │ + │ │ + ▼ ▼ +┌stopword cleaned document a───────────────────────┐ ┌stopword cleaned document b───────────────────────┐ +│ fine good fine good know marty │ │ thank lot kid course biff │ +│ look familiar know mother │ │ would want happen gonna ram │ +│ dance unless know someone │ │ well marty want thank │ +│ else could play guitar these │ │ good advice never forget doc │ +│ maybe adopted │ │ look need little plutonium │ +└─────────────────────┬────────────────────────────┘ └─────────────────────┬────────────────────────────┘ + │ │ + │ │ + └───────────────┐ ┌─────────────────┘ + ▼ ▼ + ╔WebIndex═══════════════════════════════════════╗ + ║ Term │ Fequency │ Documnet │ Position ║ + ║═══════════════════════════════════════════════║ + ║ adopted │ 1 │ a │ 211 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ advice │ 1 │ b │ 153 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ biff │ 1 │ b │ 40 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ could │ 1 │ a │ 156 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ course │ 1 │ b │ 28 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ dance │ 1 │ a │ 108 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ doc │ 1 │ b │ 183 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ else │ 1 │ a │ 147 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ familiar │ 1 │ a │ 62 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ fine │ 2 │ a │ 5 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ forget │ 1 │ b │ 22 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ gonna │ 1 │ b │ 87 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ good │ 3 │ a │ 16, 28 ║ + ║ │ │ b │ 148 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ guitar │ 1 │ a │ 171 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ happen │ 1 │ b │ 75 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ kid │ 1 │ b │ 15 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ know │ 3 │ a │ 38, 77, 134 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ little │ 1 │ b │ 211 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ look │ 2 │ a │ 54 ║ + ║ │ │ b │ 188 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ lot │ 1 │ b │ 10 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ marty │ 2 │ a │ 43 ║ + ║ │ │ b │ 108 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ maybe │ 1 │ a │ 196 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ mother │ 1 │ a │ 87 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ need │ 1 │ b │ 201 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ never │ 1 │ b │ 166 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ play │ 1 │ a │ 162 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ plutonium │ 1 │ b │ 218 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ ram │ 1 │ b │ 93 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ someone │ 1 │ a │ 139 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ thank │ 2 │ b │ 0, 125 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ these │ 1 │ a │ 189 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ unless │ 1 │ a │ 123 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ want │ 2 │ b │ 62, 117 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ well │ 1 │ b │ 102 ║ + ║───────────┼──────────┼──────────┼─────────────║ + ║ would │ 1 │ b │ 53 ║ + ╚═══════════════════════════════════════════════╝ + ▲ + │ + │ + ┌stop word cleaned query──┐ + │ marty play guitar │ + └─────────────────────────┘ + ▲ + │ + │ + ┌normalized query─────────┐ + │ marty play the guitar │ + └─────────────────────────┘ + ▲ + │ + │ + ┌query───────┴─────────────┐ + │ 'Marty play the guitar.' │ + └──────────────────────────┘ ``` `WebIndex` is an efficient system that combines document store and reverse indices to support a variety of search options. The @@ -195,42 +195,42 @@ posting. When searching for one or more terms, the IDs of the instances and thei determined. ``` - ╔═══════════════════════════════════════ IndexManager ═╗ - ║ ┌──────────┐ ║ - ║ │ WebIndex │ ║ - ║ └────┬─────┘ ║ - ║ │ 1 ║ - ║ │ ╔══════ IndexDocumentStore ═╗ ║ - ║ │ * ║ ║ ║ - ║ ┌──────┴────────┐ 1 ║ * ┌──────┐ ║ ║ - ║ │ IndexDocument ├───────┤ Item │ ║ ║ - ║ └──────┬────────┘ ║ └──────┘ ║ ║ - ║ │ 1 ╚═══════════════════════════╝ ║ - ║ │ ║ - ║ │ * ║ - ║ ┌─────┴──────┐ ║ - ║ │ IndexField │ ║ - ║ └─────┬──────┘ ║ - ║ │ 1 ║ - ║ ╔══════│═════ IndexReverse ═╗ ║ - ║ ║ │ * ║ ║ - ║ ║ ┌───┴──┐ ║ ║ - ║ ║ │ Term │ ║ ║ - ║ ║ └───┬──┘ ║ ║ - ║ ║ │ 1 ║ ║ - ║ ║ │ ║ ║ - ║ ║ │ * ║ ║ - ║ ║ ┌────┴────┐ ║ ║ - ║ ║ │ Posting │ ║ ║ - ║ ║ └────┬────┘ ║ ║ - ║ ║ │ 1 ║ ║ - ║ ║ │ ║ ║ - ║ ║ │ * ║ ║ - ║ ║ ┌────┴─────┐ ║ ║ - ║ ║ │ Position │ ║ ║ - ║ ║ └──────────┘ ║ ║ - ║ ╚═══════════════════════════╝ ║ - ╚══════════════════════════════════════════════════════╝ +╔IndexManager══════════════════════════════════════════╗ +║ ┌──────────┐ ║ +║ │ WebIndex │ ║ +║ └────┬─────┘ ║ +║ 1 │ ║ +║ │ ┌IndexDocumentStore---------┐ ║ +║ * ▼ ¦ ¦ ║ +║ ┌───────────────┐ 1 ¦ * ┌──────┐ ¦ ║ +║ │ IndexDocument ├──────►│ Item │ ¦ ║ +║ └──────┬────────┘ ¦ └──────┘ ¦ ║ +║ 1 │ └---------------------------┘ ║ +║ │ ║ +║ * ▼ ║ +║ ┌────────────┐ ║ +║ │ IndexField │ ║ +║ └─────┬──────┘ ║ +║ 1 │ ║ +║ ┌------│--------IndexReverse┐ ║ +║ ¦ * ▼ ¦ ║ +║ ¦ ┌──────┐ ¦ ║ +║ ¦ │ Term │ ¦ ║ +║ ¦ └───┬──┘ ¦ ║ +║ ¦ 1 │ ¦ ║ +║ ¦ │ ¦ ║ +║ ¦ * ▼ ¦ ║ +║ ¦ ┌─────────┐ ¦ ║ +║ ¦ │ Posting │ ¦ ║ +║ ¦ └────┬────┘ ¦ ║ +║ ¦ 1 │ ¦ ║ +║ ¦ │ ¦ ║ +║ ¦ * ▼ ¦ ║ +║ ¦ ┌──────────┐ ¦ ║ +║ ¦ │ Position │ ¦ ║ +║ ¦ └──────────┘ ¦ ║ +║ └---------------------------┘ ║ +╚══════════════════════════════════════════════════════╝ ``` # IndexManager @@ -369,21 +369,21 @@ positional data in the reverse index. The name and type of the field are essenti If a field is marked with the IndexIgnore attribute, it will be excluded from the indexing process. ``` - ┌───────────────┐ - ┌───────────────┐ ┌────────────────────┐ │ <> │ - │ IndexDocument ├───────┤ IndexDocumentStore │ │ IIndexItem │ - └──────┬────────┘ └────────────────────┘ └───────────────┘ - │ ▲ - ┌──────────────────┬─────────┴────────┬──────────────────┐ ¦ - │ Property 1 │ Property 2 │ Property … │ Property n ┌─────────────┐ - ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ │ MyIndexItem │ - │ IndexField 1 │ │ IndexField 2 │ │ IndexField … │ │ IndexField n │ <--> ├─────────────┤ - └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ Property 1 │ - │ │ │ │ │ Property 2 │ - ┌───────┴────────┐ ┌───────┴────────┐ ┌───────┴────────┐ ┌───────┴────────┐ │ Property … │ - │ IndexReverse 1 │ │ IndexReverse 2 │ │ IndexReverse … │ │ IndexReverse n │ │ Property n │ - └────────────────┘ └────────────────┘ └────────────────┘ └────────────────┘ ├─────────────┤ - └─────────────┘ + ┌───────────────┐ + ┌───────────────┐ ┌────────────────────┐ │ <> │ + │ IndexDocument ├───────┤ IndexDocumentStore │ │ IIndexItem │ + └──────┬────────┘ └────────────────────┘ └───────────────┘ + │ ▲ + ┌──────────────────┬─────────┴────────┬──────────────────┐ ¦ + │ Property 1 │ Property 2 │ Property … │ Property n ┌─────────────┐ + ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ │ MyIndexItem │ + │ IndexField 1 │ │ IndexField 2 │ │ IndexField … │ │ IndexField n │ <--> ├─────────────┤ + └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ Property 1 │ + │ │ │ │ │ Property 2 │ +┌───────┴────────┐ ┌───────┴────────┐ ┌───────┴────────┐ ┌───────┴────────┐ │ Property … │ +│ IndexReverse 1 │ │ IndexReverse 2 │ │ IndexReverse … │ │ IndexReverse n │ │ Property n │ +└────────────────┘ └────────────────┘ └────────────────┘ └────────────────┘ ├─────────────┤ + └─────────────┘ ``` ## IndexSchema The index schema file contains important metadata, which provides detailed information about the structure and characteristics of @@ -593,22 +593,22 @@ This process ensures efficient use of storage space without compromising the int this method allows for faster data transmission and enhances the overall performance of the `IndexDocumentStore`. Access to the original data can be obtained at any time through decompression and deserialization. ``` - ┌──────────────────────────────┐ - │ start │ - │ ┌────────────────────────────┤ - │ │ if !contains(id) │ look up document id in hash map - │ │ ┌──────────────────────────┤ - │ │ │ gzip(data) │ gzip the data - │ │ │ add item │ adding an items segment - │ │ └──────────────────────────┤ - │ │ else │ - │ │ ┌──────────────────────────┤ - │ │ │ throw ArgumentException │ - │ │ └──────────────────────────┤ - │ │ end if │ - │ └────────────────────────────┤ - │ end │ - └──────────────────────────────┘ +┌──────────────────────────────┐ +│ start │ +│ ┌────────────────────────────┤ +│ │ if !contains(id) │ look up document id in hash map +│ │ ┌──────────────────────────┤ +│ │ │ gzip(data) │ gzip the data +│ │ │ add item │ adding an items segment +│ │ └──────────────────────────┤ +│ │ else │ +│ │ ┌──────────────────────────┤ +│ │ │ throw ArgumentException │ +│ │ └──────────────────────────┤ +│ │ end if │ +│ └────────────────────────────┤ +│ end │ +└──────────────────────────────┘ ``` **Update**: The update process consists of a combination of delete and add operations. If the data is of the same size, the existing item @@ -616,45 +616,45 @@ segment is reused. Otherwise, a new item segment is created and used. This appro system efficiency by avoiding unnecessary storage allocations. ``` - ┌──────────────────────────────┐ - │ start │ - │ ┌────────────────────────────┤ - │ │ if contains(id) │ look up document id in hash map - │ │ ┌──────────────────────────┤ - │ │ │ delete │ delete item - │ │ │ gzip(data) │ gzip the data - │ │ │ delete item │ remove the existing item segment - │ │ │ add item │ adding the updated item segment - │ │ └──────────────────────────┤ - │ │ else │ - │ │ ┌──────────────────────────┤ - │ │ │ add │ add item - │ │ └──────────────────────────┤ - │ │ end if │ - │ └────────────────────────────┤ - │ end │ - └──────────────────────────────┘ +┌──────────────────────────────┐ +│ start │ +│ ┌────────────────────────────┤ +│ │ if contains(id) │ look up document id in hash map +│ │ ┌──────────────────────────┤ +│ │ │ delete │ delete item +│ │ │ gzip(data) │ gzip the data +│ │ │ delete item │ remove the existing item segment +│ │ │ add item │ adding the updated item segment +│ │ └──────────────────────────┤ +│ │ else │ +│ │ ┌──────────────────────────┤ +│ │ │ add │ add item +│ │ └──────────────────────────┤ +│ │ end if │ +│ └────────────────────────────┤ +│ end │ +└──────────────────────────────┘ ``` **Remove**: Documents that are no longer needed can be securely removed from the document storage by using the delete function. This ensures efficient use of storage and keeps the document storage tidy and well-organized. ``` - ┌──────────────────────────────┐ - │ start │ - │ ┌────────────────────────────┤ - │ │ if !contains(id) │ look up document id in hash map - │ │ ┌──────────────────────────┤ - │ │ │ delete item │ remove the existing item segment - │ │ └──────────────────────────┤ - │ │ else │ - │ │ ┌──────────────────────────┤ - │ │ │ throw ArgumentException │ - │ │ └──────────────────────────┤ - │ │ end if │ - │ └────────────────────────────┤ - │ end │ - └──────────────────────────────┘ +┌──────────────────────────────┐ +│ start │ +│ ┌────────────────────────────┤ +│ │ if !contains(id) │ look up document id in hash map +│ │ ┌──────────────────────────┤ +│ │ │ delete item │ remove the existing item segment +│ │ └──────────────────────────┤ +│ │ else │ +│ │ ┌──────────────────────────┤ +│ │ │ throw ArgumentException │ +│ │ └──────────────────────────┤ +│ │ end if │ +│ └────────────────────────────┤ +│ end │ +└──────────────────────────────┘ ``` ### IndexReverse @@ -737,41 +737,41 @@ position in the documents. is as follows: ``` - ┌──────────────────────────────┐ - │ start │ - │ ┌────────────────────────────┤ - │ │ loop over terms │ retrieve all terms from the new IndexField - │ │ ┌──────────────────────────┤ - │ │ │ tn := gettermnode(term) │ - │ │ │ if tn != null │ - │ │ │ ┌────────────────────────┤ - │ │ │ │ p := getposting(id) │ - │ │ │ │ if p != null │ - │ │ │ │ ┌──────────────────────┤ - │ │ │ │ │ add position │ add position associated with the existing posting - │ │ │ │ └──────────────────────┤ - │ │ │ │ else │ - │ │ │ │ ┌──────────────────────┤ - │ │ │ │ │ add posting │ add posting with the document id - │ │ │ │ │ ┌────────────────────┤ - │ │ │ │ │ │ add position │ add position associated with the new posting - │ │ │ │ └─┴────────────────────┤ - │ │ │ │ end if │ - │ │ │ └────────────────────────┤ - │ │ │ else │ - │ │ │ ┌────────────────────────┤ - │ │ │ │ add term node │ add new term node - │ │ │ │ ┌──────────────────────┤ - │ │ │ │ │ add posting │ add posting with the document id - │ │ │ │ │ ┌────────────────────┤ - │ │ │ │ │ │ add position │ add position associated with the new posting - │ │ │ └─┴─┴────────────────────┤ - │ │ │ end if │ - │ │ └──────────────────────────┤ - │ │ end loop │ - │ └────────────────────────────┤ - │ end │ - └──────────────────────────────┘ +┌──────────────────────────────┐ +│ start │ +│ ┌────────────────────────────┤ +│ │ loop over terms │ retrieve all terms from the new IndexField +│ │ ┌──────────────────────────┤ +│ │ │ tn := gettermnode(term) │ +│ │ │ if tn != null │ +│ │ │ ┌────────────────────────┤ +│ │ │ │ p := getposting(id) │ +│ │ │ │ if p != null │ +│ │ │ │ ┌──────────────────────┤ +│ │ │ │ │ add position │ add position associated with the existing posting +│ │ │ │ └──────────────────────┤ +│ │ │ │ else │ +│ │ │ │ ┌──────────────────────┤ +│ │ │ │ │ add posting │ add posting with the document id +│ │ │ │ │ ┌────────────────────┤ +│ │ │ │ │ │ add position │ add position associated with the new posting +│ │ │ │ └─┴────────────────────┤ +│ │ │ │ end if │ +│ │ │ └────────────────────────┤ +│ │ │ else │ +│ │ │ ┌────────────────────────┤ +│ │ │ │ add term node │ add new term node +│ │ │ │ ┌──────────────────────┤ +│ │ │ │ │ add posting │ add posting with the document id +│ │ │ │ │ ┌────────────────────┤ +│ │ │ │ │ │ add position │ add position associated with the new posting +│ │ │ └─┴─┴────────────────────┤ +│ │ │ end if │ +│ │ └──────────────────────────┤ +│ │ end loop │ +│ └────────────────────────────┤ +│ end │ +└──────────────────────────────┘ ``` **Update**: Updating an `IndexField` in a document is done by determining the difference between the saved and changed terms. All @@ -779,65 +779,65 @@ postings (including positions) will be deleted if they no longer exist in the ch new postings (including positions) are created for terms that were not included in the original `IndexField`. ``` - ┌──────────────────────────────┐ - │ current │ - │ │ - │ to delete = ┌─────────┼─────────────────┐ - │ current\changed │ │ changed │ - └────────────────────┼─────────┘ │ - │ to add = │ - │ changed\current │ - └───────────────────────────┘ +┌──────────────────────────────┐ +│ current │ +│ │ +│ to delete = ┌─────────┼─────────────────┐ +│ current\changed │ │ changed │ +└────────────────────┼─────────┘ │ + │ to add = │ + │ changed\current │ + └───────────────────────────┘ ``` This results in the following process: ``` - ┌──────────────────────────────────┐ - │ start │ - │ ┌────────────────────────────────┤ - │ │ deleteTerms := current\changed │ - │ │ addTerms := changed\current │ - │ │ ┌──────────────────────────────┤ - │ │ │ loop over deleteTerms │ - │ │ │ ┌────────────────────────────┤ - │ │ │ │ delete posting │ remove all postings with the document id - │ │ │ │ ┌──────────────────────────┤ - │ │ │ │ │ delete position │ remove all positions associated with the deleted postings - │ │ │ └─┴──────────────────────────┤ - │ │ │ end loop │ - │ │ └──────────────────────────────┤ - │ │ ┌──────────────────────────────┤ - │ │ │ loop over addTerms │ - │ │ │ ┌────────────────────────────┤ - │ │ │ │ add posting │ add posting with the document id - │ │ │ │ ┌──────────────────────────┤ - │ │ │ │ │ add position │ add position associated with the posting - │ │ │ └─┴──────────────────────────┤ - │ │ │ end loop │ - │ └─┴──────────────────────────────┤ - │ end │ - └──────────────────────────────────┘ +┌──────────────────────────────────┐ +│ start │ +│ ┌────────────────────────────────┤ +│ │ deleteTerms := current\changed │ +│ │ addTerms := changed\current │ +│ │ ┌──────────────────────────────┤ +│ │ │ loop over deleteTerms │ +│ │ │ ┌────────────────────────────┤ +│ │ │ │ delete posting │ remove all postings with the document id +│ │ │ │ ┌──────────────────────────┤ +│ │ │ │ │ delete position │ remove all positions associated with the deleted postings +│ │ │ └─┴──────────────────────────┤ +│ │ │ end loop │ +│ │ └──────────────────────────────┤ +│ │ ┌──────────────────────────────┤ +│ │ │ loop over addTerms │ +│ │ │ ┌────────────────────────────┤ +│ │ │ │ add posting │ add posting with the document id +│ │ │ │ ┌──────────────────────────┤ +│ │ │ │ │ add position │ add position associated with the posting +│ │ │ └─┴──────────────────────────┤ +│ │ │ end loop │ +│ └─┴──────────────────────────────┤ +│ end │ +└──────────────────────────────────┘ ``` **Remove**: The removal of an IndexField from a reverse index is carried out according to the following procedure: ``` - ┌──────────────────────────────┐ - │ start │ - │ ┌────────────────────────────┤ - │ │ loop over terms │ retrieve all terms from the stored IndexField - │ │ ┌──────────────────────────┤ - │ │ │ loop over termnode(term) │ retrieve all TermNodes that correspond to the term - │ │ │ ┌────────────────────────┤ - │ │ │ │ delete posting │ remove all postings with the document id - │ │ │ │ ┌──────────────────────┤ - │ │ │ │ │ delete position │ remove all positions associated with the deleted postings - │ │ │ └─┴──────────────────────┤ - │ │ │ end loop │ - │ │ └──────────────────────────┤ - │ │ end loop │ - │ └────────────────────────────┤ - │ end │ - └──────────────────────────────┘ +┌──────────────────────────────┐ +│ start │ +│ ┌────────────────────────────┤ +│ │ loop over terms │ retrieve all terms from the stored IndexField +│ │ ┌──────────────────────────┤ +│ │ │ loop over termnode(term) │ retrieve all TermNodes that correspond to the term +│ │ │ ┌────────────────────────┤ +│ │ │ │ delete posting │ remove all postings with the document id +│ │ │ │ ┌──────────────────────┤ +│ │ │ │ │ delete position │ remove all positions associated with the deleted postings +│ │ │ └─┴──────────────────────┤ +│ │ │ end loop │ +│ │ └──────────────────────────┤ +│ │ end loop │ +│ └────────────────────────────┤ +│ end │ +└──────────────────────────────┘ ``` ## Indexing @@ -855,7 +855,7 @@ public class Greetings : IIndexItem } // somewhere in the code... -IndexManager.Register(CultureInfo.GetCultureInfo("en"), IndexType.Storage); +IndexManager.Register(CultureInfo.GetCultureInfo("en"), IndexType.Storage); var greetings = new [] { @@ -865,46 +865,47 @@ var greetings = new [] IndexManager.ReIndex(greetings); ``` + ``` - ┌Term: 23┐ - │ null │ root - │ 0 │ - │ 53 │────►┌Term: 53┐ - │ 0 │ │ 'h' │ first letter from helge and helena - │ 0 │ │ 0 │ - └────────┘ │ 83 │────►┌Term: 83┐ - │ 0 │ │ 'e' │ second letter from helge and helena - │ 0 │ │ 0 │ - └────────┘ │ 113 │────►┌Term:113┐ - │ 0 │ │ 'l' │ third letter from helge and helena - │ 0 │ │ 0 │ - └────────┘ │ 321 │────►┌Term:143┐ - │ 0 │ │ 'e' │ fourth letter from helena - │ 0 │ ┌──│ 321 │ - └────────┘ │ │ 173 │────►┌Term:173┐ - │ │ 0 │ │ 'n' │ fifth letter from helena - │ │ 0 │ │ 0 │ - ┌Term:321┐◄───────┘ └────────┘ │ 203 │────►┌Term:203┐ - │ 'g' │ fourth letter from helge │ 0 │ │ 'a' │ sixth letter from helena - │ 0 │ │ 0 │ │ 0 │ - │ 351 │────►┌Term:351┐ └────────┘ │ 0 │ - │ 0 │ │ 'e' │ fifth letter from helge │ 2 │ - │ 0 │ │ 0 │ ┌─│ 233 │ - └────────┘ │ 0 │ │ └────────┘ - │ 1 │ │ - ┌─│ 381 │ │ - │ └────────┘ ▼ - ▼ ┌Post:233┐ - ┌Post:381┐ │ 'b2..' │ - │ 'c7..' │ │ 0 │ - │ 0 │ │ 277 │────►┌Post:277┐ - │ 0 │ ┌Pos: 265┐◄────│ 265 │ │ 'c7..' │ - ┌Pos: 413┐◄────│ 413 │ │ 1 │ └────────┘ │ 0 │ - │ 3 │ └────────┘ │ 0 │ │ 0 │ - │ 0 │ └────────┘ │ 309 │────►┌Pos: 309┐ - └────────┘ └────────┘ │ 1 │ - │ 0 │ - └────────┘ +┌Term: 23┐ +│ null │ root +│ 0 │ +│ 53 │────►┌Term: 53┐ +│ 0 │ │ 'h' │ first letter from helge and helena +│ 0 │ │ 0 │ +└────────┘ │ 83 │────►┌Term: 83┐ + │ 0 │ │ 'e' │ second letter from helge and helena + │ 0 │ │ 0 │ + └────────┘ │ 113 │────►┌Term:113┐ + │ 0 │ │ 'l' │ third letter from helge and helena + │ 0 │ │ 0 │ + └────────┘ │ 321 │────►┌Term:143┐ + │ 0 │ │ 'e' │ fourth letter from helena + │ 0 │ ┌──│ 321 │ + └────────┘ │ │ 173 │────►┌Term:173┐ + │ │ 0 │ │ 'n' │ fifth letter from helena + │ │ 0 │ │ 0 │ + ┌Term:321┐◄───────┘ └────────┘ │ 203 │────►┌Term:203┐ + │ 'g' │ fourth letter from helge │ 0 │ │ 'a' │ sixth letter from helena + │ 0 │ │ 0 │ │ 0 │ + │ 351 │────►┌Term:351┐ └────────┘ │ 0 │ + │ 0 │ │ 'e' │ fifth letter from helge │ 2 │ + │ 0 │ │ 0 │ ┌─│ 233 │ + └────────┘ │ 0 │ │ └────────┘ + │ 1 │ │ + ┌─│ 381 │ │ + │ └────────┘ ▼ + ▼ ┌Post:233┐ + ┌Post:381┐ │ 'b2..' │ + │ 'c7..' │ │ 0 │ + │ 0 │ │ 277 │────►┌Post:277┐ + │ 0 │ ┌Pos: 265┐◄────│ 265 │ │ 'c7..' │ + ┌Pos: 413┐◄────│ 413 │ │ 1 │ └────────┘ │ 0 │ + │ 3 │ └────────┘ │ 0 │ │ 0 │ + │ 0 │ └────────┘ │ 309 │────►┌Pos: 309┐ + └────────┘ └────────┘ │ 1 │ + │ 0 │ + └────────┘ ``` # WQL diff --git a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj index cbda14f..25f1ec7 100644 --- a/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj +++ b/src/WebExpress.WebIndex.Test/WebExpress.WebIndex.Test.csproj @@ -28,8 +28,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs b/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs index 62f2ca7..3a8bd10 100644 --- a/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs +++ b/src/WebExpress.WebIndex.Wi/Model/ViewModel.cs @@ -6,6 +6,9 @@ namespace WebExpress.WebIndex.Wi.Model { + /// + /// Represents the ViewModel for managing the indexing of project objects. + /// internal class ViewModel { /// @@ -143,7 +146,7 @@ public bool DropIndexFile() public IEnumerable<(string, uint, uint, uint, IEnumerable)> GetIndexTerms() { var runtimeClass = CurrentObjectType.BuildRuntimeClass(); - var document = WiApp.ViewModel.IndexManager.GetIndexDocument(runtimeClass); + var document = IndexManager.GetIndexDocument(runtimeClass); var fieldProperty = runtimeClass.GetProperty(CurrentIndexField?.Name); var methodInfo = document.GetType().GetMethod("GetReverseIndex"); var reverseIndex = methodInfo.Invoke(document, [fieldProperty]); diff --git a/src/WebExpress.WebIndex.WiUI/App.xaml b/src/WebExpress.WebIndex.WiUI/App.xaml new file mode 100644 index 0000000..47b32a1 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/App.xaml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/src/WebExpress.WebIndex.WiUI/App.xaml.cs b/src/WebExpress.WebIndex.WiUI/App.xaml.cs new file mode 100644 index 0000000..032e9aa --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/App.xaml.cs @@ -0,0 +1,15 @@ +namespace WebExpress.WebIndex.WiUI +{ + public partial class App : Application + { + public App() + { + InitializeComponent(); + } + + protected override Window CreateWindow(IActivationState? activationState) + { + return new Window(new AppShell()); + } + } +} \ No newline at end of file diff --git a/src/WebExpress.WebIndex.WiUI/AppShell.xaml b/src/WebExpress.WebIndex.WiUI/AppShell.xaml new file mode 100644 index 0000000..406429e --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/AppShell.xaml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/src/WebExpress.WebIndex.WiUI/AppShell.xaml.cs b/src/WebExpress.WebIndex.WiUI/AppShell.xaml.cs new file mode 100644 index 0000000..0331be5 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/AppShell.xaml.cs @@ -0,0 +1,10 @@ +namespace WebExpress.WebIndex.WiUI +{ + public partial class AppShell : Shell + { + public AppShell() + { + InitializeComponent(); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Converters/FieldTypeConverter.cs b/src/WebExpress.WebIndex.WiUI/Converters/FieldTypeConverter.cs new file mode 100644 index 0000000..9a3ac64 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Converters/FieldTypeConverter.cs @@ -0,0 +1,28 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using WebExpress.WebIndex.WiUI.Model; + +namespace WebExpress.WebIndex.WiUI.Converters +{ + /// + /// Custom converter for field typ to string. + /// + internal class FieldTypeConverter : JsonConverter + { + /// + /// Converts a string to an int. + /// + public override FieldType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return FieldTypeExtention.FromStringValue(reader.GetString()!); + } + + /// + /// Converts an int to a string. + /// + public override void Write(Utf8JsonWriter writer, FieldType value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Converters/NullToBooleanConverter.cs b/src/WebExpress.WebIndex.WiUI/Converters/NullToBooleanConverter.cs new file mode 100644 index 0000000..abf61f9 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Converters/NullToBooleanConverter.cs @@ -0,0 +1,38 @@ +using System.Globalization; + +namespace WebExpress.WebIndex.WiUI.Converters +{ + /// + /// Converts a null value to false and any non-null value to true. + /// + public class NullToBooleanConverter : IValueConverter + { + /// + /// Converts a value to a boolean. Returns false if the value is null, otherwise returns true. + /// + /// The value to be converted. + /// The type of the binding target property. + /// Optional parameter to be used in the converter logic. + /// The culture to be used in the converter. + /// False if the value is null, otherwise true. + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return value != null; + } + + /// + /// Converts a boolean value back to its original value. This method is not implemented and will throw an exception if called. + /// + /// The value to be converted back. + /// The type to convert to. + /// Optional parameter to be used in the converter logic. + /// The culture to be used in the converter. + /// Throws a NotImplementedException. + /// Thrown always as this method is not implemented. + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + +} diff --git a/src/WebExpress.WebIndex.WiUI/IndexManager.cs b/src/WebExpress.WebIndex.WiUI/IndexManager.cs new file mode 100644 index 0000000..2c8d796 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/IndexManager.cs @@ -0,0 +1,142 @@ +using System.Globalization; +using WebExpress.WebIndex.Wql; + +namespace WebExpress.WebIndex.WiUI +{ + /// + /// Implementation of the index manager. + /// + public class IndexManager : WebIndex.IndexManager + { + /// + /// Initializes a new instance of the class. + /// + public IndexManager() + { + } + + /// + /// Registers a data type in the index. + /// + /// The data type. This must have the IIndexItem interface. + /// The culture. + /// The index type. + public void Create(Type dataType, CultureInfo culture, IndexType type = IndexType.Memory) + { + var genericMethod = typeof(IndexManager).GetMethod("Create", 1, [typeof(CultureInfo), typeof(IndexType)]); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + specificMethod?.Invoke(this, [culture, type]); + } + + /// + /// Closes the index file of type T. + /// + /// The data type. This must have the IIndexItem interface. + public void Close(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("Close", 1, []); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + specificMethod?.Invoke(this, []); + } + + /// + /// Removes all index documents of type. + /// + /// The data type. This must have the IIndexItem interface. + public void Drop(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("Drop", 1, []); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + specificMethod?.Invoke(this, []); + } + + /// + /// Adds a item to the index. + /// + /// The data type. This must have the IIndexItem interface. + /// The data to be added to the index. + public void Insert(Type dataType, object item) + { + var genericMethod = typeof(IndexManager).GetMethods() + .Where(m => m.Name == "Insert" && m.IsGenericMethodDefinition) + .First(); + var specificMethod = genericMethod.MakeGenericMethod(dataType); + + specificMethod.Invoke(this, [item]); + } + + /// + /// Clear all data from index document. + /// + /// The data type. This must have the IIndexItem interface. + public void Clear(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("Clear", 1, []); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + specificMethod?.Invoke(this, []); + } + + /// + /// Executes a wql statement. + /// + /// The data type. This must have the IIndexItem interface. + /// The data type. This must have the IIndexItem interface. + /// The wql statement. + /// The WQL statement. + public IWqlStatement Retrieve(Type dataType, string wql) + { + if (dataType == null) + { + return null; + } + + var genericMethod = typeof(IndexManager).GetMethod("Retrieve", 1, [typeof(string)]); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + return specificMethod?.Invoke(this, [wql]) as IWqlStatement; + } + + /// + /// Counts the number of items of the index. + /// + /// The data type. This must have the IIndexItem interface. + /// The number of items. + public uint Count(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("Count", 1, []); + var specificMethod = genericMethod?.MakeGenericMethod(dataType); + + return (uint)specificMethod?.Invoke(this, [])!; + } + + /// + /// Returns all documents from the index. + /// + /// The data type. This must have the IIndexItem interface. + /// An enumeration of the documents. + public IEnumerable All(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("All", 1, []); + var specificMethod = genericMethod.MakeGenericMethod(dataType); + + return specificMethod.Invoke(this, []) as IEnumerable; + } + + /// + /// Returns an index type based on its type. + /// + /// The data type. This must have the IIndexItem interface. + /// The index type or null. + public IIndexDocument GetIndexDocument(Type dataType) + { + var genericMethod = typeof(IndexManager).GetMethod("GetIndexDocument", 1, []); + var specificMethod = genericMethod.MakeGenericMethod(dataType); + + return specificMethod.Invoke(this, []) as IIndexDocument; + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/MauiProgram.cs b/src/WebExpress.WebIndex.WiUI/MauiProgram.cs new file mode 100644 index 0000000..e074b13 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/MauiProgram.cs @@ -0,0 +1,27 @@ +using CommunityToolkit.Maui; +using Microsoft.Extensions.Logging; + +namespace WebExpress.WebIndex.WiUI +{ + public static class MauiProgram + { + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .UseMauiCommunityToolkit() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); + }); + +#if DEBUG + builder.Logging.AddDebug(); +#endif + + return builder.Build(); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/Field.cs b/src/WebExpress.WebIndex.WiUI/Model/Field.cs new file mode 100644 index 0000000..ec00256 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/Field.cs @@ -0,0 +1,28 @@ +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents an index field. + /// + public class Field + { + /// + /// Returns or sets the name of the field. + /// + public string? Name { get; set; } + + /// + /// Returns or sets the type of the field. + /// + public FieldType Type { get; set; } + + /// + /// Returns or sets the ignore attribute. + /// + public bool Ignore { get; set; } + + /// + /// Returns or sets if the field is abstract. + /// + public bool Abstract { get; set; } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/FieldType.cs b/src/WebExpress.WebIndex.WiUI/Model/FieldType.cs new file mode 100644 index 0000000..b884744 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/FieldType.cs @@ -0,0 +1,106 @@ +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents the types of field that can be used. + /// + public enum FieldType + { + /// + /// Field type for plain text. + /// + Text, + + /// + /// Field type for boolean values. + /// + Bool, + + /// + /// Field type for integer values. + /// + Int, + + /// + /// Field type for double precision floating point numbers. + /// + Double, + + /// + /// Field type for date time values. + /// + DateTime, + + /// + /// Field type for guid values. + /// + Guid, + + /// + /// Field type for undefine value. + /// + Object + } + + /// + /// Provides extension methods for the FieldType enumeration. + /// + internal static class FieldTypeExtention + { + /// + /// Converts the FieldType value to a corresponding System.Type. + /// + /// The FieldType value to convert. + /// The System.Type that corresponds to the given FieldType value. + public static Type ToType(this FieldType type) + { + return type switch + { + FieldType.Text => typeof(string), + FieldType.Bool => typeof(bool), + FieldType.Int => typeof(int), + FieldType.Double => typeof(double), + FieldType.DateTime => typeof(DateTime), + FieldType.Guid => typeof(Guid), + _ => typeof(object) + }; + } + + /// + /// Converts the FieldType value to a corresponding string representation. + /// + /// The FieldType value to convert. + /// The string representation of the given FieldType value. + public static string ToString(this FieldType type) + { + return type switch + { + FieldType.Text => "Text", + FieldType.Bool => "Boolean", + FieldType.Int => "Integer", + FieldType.Double => "Double", + FieldType.DateTime => "DateTime", + FieldType.Guid => "Guid", + _ => "Object" + }; + } + + /// + /// Converts a string to a corresponding FieldType value. + /// + /// The string to convert. + /// The FieldType value that corresponds to the given string. + public static FieldType FromStringValue(string str) + { + return str switch + { + "String" => FieldType.Text, + "Boolean" => FieldType.Bool, + "Integer" => FieldType.Int, + "Double" => FieldType.Double, + "DateTime" => FieldType.DateTime, + "Guid" => FieldType.Guid, + _ => FieldType.Object + }; + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/Index.cs b/src/WebExpress.WebIndex.WiUI/Model/Index.cs new file mode 100644 index 0000000..cb1fb18 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/Index.cs @@ -0,0 +1,18 @@ +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents an index file *.ws. + /// + public class Index + { + /// + /// Returns or sets the name of the field. + /// + public string? Name { get; set; } + + /// + /// Returns or sets the file name with its path. + /// + public string? FileNameWithPath { get; set; } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/MainViewModel.cs b/src/WebExpress.WebIndex.WiUI/Model/MainViewModel.cs new file mode 100644 index 0000000..0726695 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/MainViewModel.cs @@ -0,0 +1,293 @@ +using CommunityToolkit.Maui.Core.Extensions; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text.Json; +using WebExpress.WebIndex.Storage; +using WebExpress.WebIndex.WiUI.Converters; + +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents the main view model that implements the INotifyPropertyChanged interface. + /// + public class MainViewModel : INotifyPropertyChanged + { + private Project? _selectedProject = null; + private ObservableCollection _projects = []; + private Index? _selectedIndex = null; + private ObservableCollection _indexes = []; + private ObjectType? _selectedObjectType = null; + private Field? _selectedIndexField = null; + private Term? _selectedTerms = null; + private ObservableCollection _terms = []; + + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler? PropertyChanged; + + /// + /// Manages the indexing of project objects. + /// + public static IndexManager? IndexManager { get; private set; } + + /// + /// Returns or sets the selected project. + /// + /// + /// The selected project. + /// + public Project? SelectedProject + { + get => _selectedProject; + set + { + _selectedProject = value; OnPropertyChanged(); + + Indexes = Directory + .GetFiles(SelectedProject?.IndexPath ?? Environment.CurrentDirectory) + .Where(x => x.EndsWith(".ws")) + .Select(x => new Index() + { + Name = Path.GetFileNameWithoutExtension(x), + FileNameWithPath = x + }).ToObservableCollection(); + } + } + + /// + /// Returns or sets the collection of projects. + /// + public ObservableCollection Projects + { + get => _projects; + set { _projects = value; OnPropertyChanged(); } + } + + /// + /// Returns or sets the selected index. + /// + public Index? SelectedIndex + { + get => _selectedIndex; + set { _selectedIndex = value; OnPropertyChanged(); } + } + + /// + /// Returns or sets the collection of indexes. + /// + public ObservableCollection Indexes + { + get => _indexes; + set { _indexes = value; OnPropertyChanged(); } + } + + /// + /// Returns the selected field. + /// + /// + /// The selected field. + /// + public Field? SelectedField + { + get => _selectedIndexField; + set + { + _selectedIndexField = value; + _terms = GetIndexTerms(); + OnPropertyChanged(nameof(Terms)); + OnPropertyChanged(); + } + } + + /// + /// Returns the currently selected index file. + /// + /// + /// The name of the currently selected index file, or null if no index file is selected. + /// + public ObservableCollection? Fields + { + get { return _selectedObjectType?.Fields; } + } + + /// + /// Returns or sets the selected term. + /// + /// + /// The selected term. + /// + public Term? SelectedTerm + { + get { return _selectedTerms; } + set { _selectedTerms = value; OnPropertyChanged(); } + } + + /// + /// Returns the collection of terms. + /// + /// + /// The collection of terms. + /// + public ObservableCollection? Terms + { + get { return _terms; } + } + + /// + /// Initializes a new instance of the class. + /// + public MainViewModel() + { + Projects = ProjectService.LoadProjects(); + + SelectedProject = Projects.Where(x => x.IsSelected ?? false).FirstOrDefault(); + if (SelectedProject == null) + { + SelectedProject = Projects.FirstOrDefault(); + } + } + + /// + /// Opens the specified index file. + /// + /// The full path to the index file. + /// True if successful, otherwise fasle. + public bool CreateIndexFile(string indexFile) + { + _selectedObjectType = new ObjectType() { Name = indexFile }; + var indexFilewithPath = Path.Combine(SelectedProject?.IndexPath!, $"{indexFile}.ws"); + + var runtimeClass = _selectedObjectType.BuildRuntimeClass(); + var context = new IndexContext { IndexDirectory = indexFilewithPath }; + IndexManager = new IndexManager(); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManager).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method?.Invoke(IndexManager, [context]); + + IndexManager.Create(runtimeClass, CultureInfo.GetCultureInfo("en"), IndexType.Storage); + + OnPropertyChanged(nameof(Fields)); + + return true; + } + + /// + /// Opens the specified index file. + /// + /// The full path to the index file. + /// True if successful, otherwise fasle. + public bool OpenIndexFile(string? indexFile) + { + if (indexFile == null) + { + return false; + } + + CloseIndexFile(); + + var schema = File.ReadAllText(indexFile); + var options = new JsonSerializerOptions { Converters = { new FieldTypeConverter() } }; + _selectedObjectType = JsonSerializer.Deserialize(schema, options); + + var runtimeClass = _selectedObjectType?.BuildRuntimeClass(); + + var context = new IndexContext { IndexDirectory = Path.GetDirectoryName(indexFile) }; + IndexManager = new IndexManager(); + + // use reflection to call the protected Initialization method + var method = typeof(IndexManager).GetMethod("Initialization", BindingFlags.Instance | BindingFlags.NonPublic); + method?.Invoke(IndexManager, [context]); + + IndexManager.Create(runtimeClass!, CultureInfo.GetCultureInfo("en"), IndexType.Storage); + + OnPropertyChanged(nameof(Fields)); + + return true; + } + + /// + /// Opens the specified index field. + /// + /// The the index field. + /// True if successful, otherwise fasle. + public bool OpenIndexField(Field? indexField) + { + SelectedField = indexField; + + return true; + } + + /// + /// Close the current index file. + /// + /// True if successful, otherwise fasle. + public bool CloseIndexFile() + { + var runtimeClass = _selectedObjectType?.BuildRuntimeClass(); + IndexManager?.Close(runtimeClass!); + SelectedIndex = null; + + _selectedObjectType = null; + OnPropertyChanged(nameof(Fields)); + + return true; + } + + /// + /// Drop the current index file. + /// + /// True if successful, otherwise fasle. + public bool DropIndexFile() + { + var runtimeClass = _selectedObjectType?.BuildRuntimeClass(); + IndexManager?.Drop(runtimeClass!); + SelectedIndex = null; + _selectedObjectType = null; + + OnPropertyChanged(nameof(Fields)); + + return true; + } + + /// + /// Returns the index terms. + /// + /// The index terms + public ObservableCollection GetIndexTerms() + { + var runtimeClass = _selectedObjectType?.BuildRuntimeClass(); + var document = IndexManager?.GetIndexDocument(runtimeClass!); + var fieldProperty = runtimeClass?.GetProperty(_selectedIndexField?.Name!); + var methodInfo = document?.GetType().GetMethod("GetReverseIndex"); + var reverseIndex = methodInfo?.Invoke(document, [fieldProperty]); + var termProperty = reverseIndex?.GetType().GetProperty("Term"); + var term = termProperty?.GetValue(reverseIndex) as IndexStorageSegmentTerm; + + return term?.Terms.Select(x => + ( + new Term() + { + Value = x.Item1, + Fequency = x.Item2.Fequency, + Height = x.Item2.Posting.Height, + Balance = x.Item2.Posting.Balance, + DocumentIDs = x.Item2.Posting.PreOrder.Select(y => y.DocumentID) + } + )).ToObservableCollection()!; + } + + /// + /// Raises the PropertyChanged event for the specified property. + /// + /// The name of the property that changed. + protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/ObjectType.cs b/src/WebExpress.WebIndex.WiUI/Model/ObjectType.cs new file mode 100644 index 0000000..f73da06 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/ObjectType.cs @@ -0,0 +1,134 @@ +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using WebExpress.WebIndex.WebAttribute; + +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents an object within the WebExpress.WebIndex.Studio. + /// + public class ObjectType : INotifyPropertyChanged + { + private Dictionary _typeCache = []; + private ObservableCollection? _fields = []; + + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler? PropertyChanged; + + /// + /// Returns or sets the name of the object. + /// + public string? Name { get; set; } + + /// + /// Retuns a collection of fields associated with the object. + /// + public ObservableCollection? Fields + { + get { return _fields; } + set { _fields = value; OnPropertyChanged(); OnPropertyChanged(nameof(Fields)); } + } + + /// + /// Returns a collection of stored data objects. + /// + public ObservableCollection? All => new(MainViewModel.IndexManager?.All(BuildRuntimeClass())!); + + /// + /// Returns the number of items of the index. + /// + public uint? Count => MainViewModel.IndexManager?.Count(BuildRuntimeClass()); + + /// + /// Initializes a new instance of the class. + /// + public ObjectType() + { + + } + + /// + /// Dynamically builds a class based on the object's attributes. + /// + /// A Type representing the dynamically built class. + public Type BuildRuntimeClass() + { + if (_typeCache.TryGetValue(Name!, out Type? type)) + { + return type; + } + + var assemblyName = new AssemblyName("WebExpress.WebIndex.Wi.Model.Objects"); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule($"Module_{Name}"); + + var typeBuilder = moduleBuilder.DefineType(Name!, TypeAttributes.Public, null, [typeof(IIndexItem)]); + + BildProperty(typeBuilder, "Id", typeof(Guid), true, true); + + foreach (var attribute in Fields!.Where(x => !x.Name!.Equals("id", StringComparison.OrdinalIgnoreCase))) + { + BildProperty(typeBuilder, attribute.Name!, attribute.Type.ToType(), attribute.Ignore, attribute.Abstract); + } + + var runtimeClass = typeBuilder.CreateType(); + _typeCache.Add(Name!, runtimeClass); + + return runtimeClass; + } + + /// + /// Builds a property for the dynamically created class. + /// + /// The builder for the class type. + /// The name of the property. + /// The type of the property. + /// Indicates whether the property should be ignored by the index. + /// Indicates whether the property should be virtual. + /// A PropertyBuilder for the created property. + private PropertyBuilder BildProperty(TypeBuilder typeBuilder, string name, Type type, bool indexIgnore, bool @virtual) + { + var fieldBuilder = typeBuilder.DefineField($"_{name.ToLower()}", type, FieldAttributes.Private); + var propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.HasDefault, type, Type.EmptyTypes); + + if (indexIgnore) + { + var attrCtorParams = Array.Empty(); + var attrCtorInfo = typeof(IndexIgnoreAttribute).GetConstructor(attrCtorParams); + var attrBuilder = new CustomAttributeBuilder(attrCtorInfo!, []); + propertyBuilder.SetCustomAttribute(attrBuilder); + } + + var getMethodBuilder = typeBuilder.DefineMethod($"get_{name}", @virtual ? MethodAttributes.Public | MethodAttributes.Virtual : MethodAttributes.Public, type, Type.EmptyTypes); + var getIlGenerator = getMethodBuilder.GetILGenerator(); + getIlGenerator.Emit(OpCodes.Ldarg_0); + getIlGenerator.Emit(OpCodes.Ldfld, fieldBuilder); + getIlGenerator.Emit(OpCodes.Ret); + propertyBuilder.SetGetMethod(getMethodBuilder); + + var setMethodBuilder = typeBuilder.DefineMethod($"set_{name}", @virtual ? MethodAttributes.Public | MethodAttributes.Virtual : MethodAttributes.Public, null, [type]); + var setIlGenerator = setMethodBuilder.GetILGenerator(); + setIlGenerator.Emit(OpCodes.Ldarg_0); + setIlGenerator.Emit(OpCodes.Ldarg_1); + setIlGenerator.Emit(OpCodes.Stfld, fieldBuilder); + setIlGenerator.Emit(OpCodes.Ret); + propertyBuilder.SetSetMethod(setMethodBuilder); + + return propertyBuilder; + } + + /// + /// Raises the PropertyChanged event for the specified property. + /// + /// The name of the property that changed. + private void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/Project.cs b/src/WebExpress.WebIndex.WiUI/Model/Project.cs new file mode 100644 index 0000000..0163b4c --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/Project.cs @@ -0,0 +1,60 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents an project. + /// + public class Project : INotifyPropertyChanged + { + private string? _projectName; + private bool? _isSelected; + + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler? PropertyChanged; + + /// + /// Returns or sets the name of the project. + /// + public string? ProjectName + { + get => _projectName; + set { _projectName = value; OnPropertyChanged(); } + } + + /// + /// Returns or sets the selected project. + /// + public bool? IsSelected + { + get => _isSelected; + set { _isSelected = value; OnPropertyChanged(); OnPropertyChanged(nameof(TextColor)); } + } + + /// + /// Returns the color based on the selection status of the project. + /// Blue if the project is selected, otherwise returns black. + /// + public Color? TextColor + { + get => _isSelected.HasValue && _isSelected.Value ? Color.FromRgb(20, 20, 255) : Color.FromRgb(0, 0, 0); + } + + /// + /// Returns or sets the index path. + /// + public string? IndexPath { get; set; } + + /// + /// Raises the PropertyChanged event for the specified property. + /// + /// The name of the property that changed. This is optional and will be automatically provided by the compiler if not specified. + protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/ProjectService.cs b/src/WebExpress.WebIndex.WiUI/Model/ProjectService.cs new file mode 100644 index 0000000..a4ec7b5 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/ProjectService.cs @@ -0,0 +1,60 @@ +using System.Collections.ObjectModel; +using System.Xml.Serialization; + +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Provides services for saving and loading projects. + /// + public class ProjectService + { + private static readonly string _appFolderName = "WebExpress.WebIndex.WiUI"; + private static readonly string _projectsFileName = "projects.xml"; + + /// + /// Returns the application data path for storing project files. + /// + /// The path to the application data directory. + private static string GetAppDataPath() + { + var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + var appFolder = Path.Combine(appDataPath, _appFolderName); + Directory.CreateDirectory(appFolder); + + return appFolder; + } + + /// + /// Saves the collection of projects to an XML file in the application data directory. + /// + /// The collection of projects to save. + public static void SaveProjects(ObservableCollection projects) + { + var filePath = Path.Combine(GetAppDataPath(), _projectsFileName); + + var serializer = new XmlSerializer(typeof(ObservableCollection)); + using var writer = new StreamWriter(filePath); + + serializer.Serialize(writer, projects); + } + + /// + /// Loads the collection of projects from an XML file in the application data directory. + /// + /// The collection of projects loaded from the XML file. + public static ObservableCollection LoadProjects() + { + var filePath = Path.Combine(GetAppDataPath(), _projectsFileName); + if (!File.Exists(filePath)) + { + return []; + } + + var serializer = new XmlSerializer(typeof(ObservableCollection)); + using StreamReader reader = new StreamReader(filePath); + var result = serializer.Deserialize(reader) as ObservableCollection; + + return result ?? []; + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Model/ProjectViewModel.cs b/src/WebExpress.WebIndex.WiUI/Model/ProjectViewModel.cs new file mode 100644 index 0000000..24f5512 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/ProjectViewModel.cs @@ -0,0 +1,116 @@ +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Windows.Input; + +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// ViewModel for loading projects. + /// + public class ProjectViewModel : INotifyPropertyChanged + { + private Project? _selectedProject = null; + + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler? PropertyChanged; + + /// + /// Returns the command to add a new project. + /// + public ICommand AddProjectCommand { get; } + + /// + /// Returns the command to delete an existing project. + /// + public ICommand DeleteProjectCommand { get; } + + /// + /// Returns the command to save the current project. + /// + public ICommand SaveProjectCommand { get; } + + /// + /// Returns or sets the collection of projects. + /// + public ObservableCollection Projects { get; set; } + + /// + /// Returns or sets the selected project. + /// + public Project? SelectedProject + { + get => _selectedProject; + set + { + _selectedProject = value; + + Projects.ToList().ForEach(p => p.IsSelected = false); + + if (_selectedProject != null) + { + _selectedProject.IsSelected = true; + } + + OnPropertyChanged(); + } + } + + /// + /// Initializes a new instance of the class. + /// Loads the projects and initializes the load project command. + /// + public ProjectViewModel() + { + Projects = ProjectService.LoadProjects(); + AddProjectCommand = new Command(OnAddProject); + DeleteProjectCommand = new Command(OnDeleteProject, () => SelectedProject != null); + SaveProjectCommand = new Command(OnSaveProject, () => SelectedProject != null); + } + + /// + /// Adds a new project to the collection and saves the updated collection. + /// + private void OnAddProject() + { + var newProject = new Project { ProjectName = "New Project" }; + Projects.Add(newProject); + SelectedProject = newProject; + ProjectService.SaveProjects(Projects); + } + + /// + /// Deletes the selected project from the collection and saves the updated collection. + /// + private void OnDeleteProject() + { + if (SelectedProject != null) + { + Projects.Remove(SelectedProject); + ProjectService.SaveProjects(Projects); + } + } + + /// + /// Saves the current project to the project collection. + /// + private void OnSaveProject() + { + if (SelectedProject != null) + { + ProjectService.SaveProjects(Projects); + } + } + + /// + /// Raises the PropertyChanged event for the specified property. + /// + /// The name of the property that changed. + protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} \ No newline at end of file diff --git a/src/WebExpress.WebIndex.WiUI/Model/Term.cs b/src/WebExpress.WebIndex.WiUI/Model/Term.cs new file mode 100644 index 0000000..a7f651c --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Model/Term.cs @@ -0,0 +1,38 @@ +namespace WebExpress.WebIndex.WiUI.Model +{ + /// + /// Represents an index term. + /// + public class Term + { + /// + /// Returns or sets the collection of document IDs associated with the term. + /// + public IEnumerable DocumentIDs { get; set; } = []; + + /// + /// Returns a comma-separated string of document IDs associated with the term. + /// + public uint Documents => (uint)DocumentIDs.Count(); + + /// + /// Returns or sets the term. + /// + public string? Value { get; set; } + + /// + /// Returns or sets the frequency of the term in the documents. + /// + public uint Fequency { get; set; } + + /// + /// Returns or sets the height of the term tree. + /// + public uint Height { get; set; } + + /// + /// Returns or sets the balance factor of the term tree. + /// + public uint Balance { get; set; } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml b/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml new file mode 100644 index 0000000..bc1f80f --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml.cs b/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml.cs new file mode 100644 index 0000000..58955d5 --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Pages/MainPage.xaml.cs @@ -0,0 +1,82 @@ +using WebExpress.WebIndex.WiUI.Model; + +namespace WebExpress.WebIndex.WiUI.Pages +{ + /// + /// Represents the main page of the application. + /// Inherits from . + /// + public partial class MainPage : ContentPage + { + /// + /// Initializes a new instance of the class. + /// Sets the BindingContext to a new instance of . + /// + public MainPage() + { + InitializeComponent(); + BindingContext = new MainViewModel(); + } + + /// + /// Handles the event when an index is selected. + /// Displays an alert with the selected index. + /// + /// The source of the event. + /// The event data containing the selected item. + private void OnIndexSelected(object sender, SelectedItemChangedEventArgs e) + { + if (e.SelectedItem == null) + { + return; + } + + var selectedIndex = e.SelectedItem as Model.Index; + var context = BindingContext as MainViewModel; + + var fileNameWithPath = selectedIndex?.FileNameWithPath; + + if (File.Exists(fileNameWithPath)) + { + context?.OpenIndexFile(fileNameWithPath); + } + } + + /// + /// Handles the event when a field is selected. + /// Displays an alert with the selected field. + /// + /// The source of the event. + /// The event data containing the selected item. + private void OnFieldSelected(object sender, SelectedItemChangedEventArgs e) + { + if (e.SelectedItem == null) + { + return; + } + + var selectedIndex = e.SelectedItem as Model.Field; + var context = BindingContext as MainViewModel; + + context?.OpenIndexField(selectedIndex); + } + + + /// + /// Handles the event when a term is selected. + /// Displays an alert with the selected term. + /// + /// The source of the event. + /// The event data containing the selected item. + private void OnTermSelected(object sender, SelectedItemChangedEventArgs e) + { + if (e.SelectedItem == null) + { + return; + } + + var selectedTerm = e.SelectedItem as Model.Term; + var context = BindingContext as MainViewModel; + } + } +} diff --git a/src/WebExpress.WebIndex.WiUI/Pages/ProjectPage.xaml b/src/WebExpress.WebIndex.WiUI/Pages/ProjectPage.xaml new file mode 100644 index 0000000..ef4962f --- /dev/null +++ b/src/WebExpress.WebIndex.WiUI/Pages/ProjectPage.xaml @@ -0,0 +1,72 @@ + + + + + + + + + + +