Skip to content

Commit

Permalink
Merge pull request #18 from koculu/17-enhancement-add-constructor-to-…
Browse files Browse the repository at this point in the history
…hashedsearchengine-for-customizing-underlying-zonetree-instance

Add new constructor parameter to pass AdvancedZoneTreeOptions.
  • Loading branch information
koculu authored Feb 2, 2025
2 parents f8955b6 + 6489247 commit 6d1ec68
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/ZoneTree.FullTextSearch/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<Authors>Ahmed Yasin Koculu</Authors>
<PackageId>ZoneTree.FullTextSearch</PackageId>
<Title>ZoneTree.FullTextSearch</Title>
<ProductVersion>1.0.7.0</ProductVersion>
<Version>1.0.7.0</Version>
<ProductVersion>1.0.8.0</ProductVersion>
<Version>1.0.8.0</Version>
<Authors>Ahmed Yasin Koculu</Authors>
<AssemblyTitle>ZoneTree.FullTextSearch</AssemblyTitle>
<Description>ZoneTree.FullTextSearch is an open-source library that extends ZoneTree to provide efficient full-text search capabilities. It offers a fast, embedded search engine suitable for applications that require high performance and do not rely on external databases.</Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using ZoneTree.FullTextSearch.Model;
using ZoneTree.FullTextSearch.QueryLanguage;
using ZoneTree.FullTextSearch.Search;
using ZoneTree.FullTextSearch.SearchEngines;

namespace ZoneTree.FullTextSearch.Index;

Expand Down Expand Up @@ -91,33 +92,26 @@ public bool IsReadOnly
/// Initializes a new instance of the <see cref="IndexOfTokenRecordPreviousToken{TRecord, TToken}"/> class,
/// with the option to configure primary and secondary zone trees.
/// </summary>
/// <param name="dataPath">The path to the data storage, defaulting to "data".</param>
/// <param name="recordComparer">The comparer of record.</param>
/// <param name="tokenComparer">The comparer of token.</param>
/// <param name="useSecondaryIndex">Indicates whether a secondary index should be used to perform faster deletion.</param>
/// <param name="dataPath">The path to the data storage, defaulting to "data".</param>
/// <param name="configure1">Optional configuration action for the primary zone tree.</param>
/// <param name="configure2">Optional configuration action for the secondary zone tree.</param>
/// <param name="useSecondaryIndex">Indicates whether a secondary index should be used to perform faster deletion.</param>
/// <param name="blockCacheLifeTimeInMilliseconds">Defines the life time of cached blocks. Default is 1 minute.</param>
/// /// <param name="advancedOptions">Advanced ZoneTree Options enabling customization of underlying ZoneTree instances.</param>
public IndexOfTokenRecordPreviousToken(
string dataPath = "data",
IRefComparer<TRecord> recordComparer = null,
IRefComparer<TToken> tokenComparer = null,
bool useSecondaryIndex = false,
Action<
ZoneTreeFactory<
CompositeKeyOfTokenRecordPrevious<TRecord, TToken>,
byte>> configure1 = null,
Action<
ZoneTreeFactory<
CompositeKeyOfRecordToken<TRecord, TToken>,
byte>> configure2 = null,
long blockCacheLifeTimeInMilliseconds = 60_000)
long blockCacheLifeTimeInMilliseconds = 60_000,
AdvancedZoneTreeOptions<TRecord, TToken> advancedOptions = null)
{
if (recordComparer == null)
recordComparer = ComponentsForKnownTypes.GetComparer<TRecord>();
if (tokenComparer == null)
tokenComparer = ComponentsForKnownTypes.GetComparer<TToken>();
var factory1 = new ZoneTreeFactory<CompositeKeyOfTokenRecordPrevious<TRecord, TToken>, byte>()
var fileStreamProvider = advancedOptions?.FileStreamProvider;
var factory1 = new ZoneTreeFactory<CompositeKeyOfTokenRecordPrevious<TRecord, TToken>, byte>(fileStreamProvider)
.SetDataDirectory($"{dataPath}/index1")
.SetIsDeletedDelegate(
(in CompositeKeyOfTokenRecordPrevious<TRecord, TToken> key, in byte value) => value == 1)
Expand All @@ -128,7 +122,7 @@ public IndexOfTokenRecordPreviousToken(
recordComparer,
tokenComparer));

configure1?.Invoke(factory1);
advancedOptions?.FactoryConfigurator1?.Invoke(factory1);

ZoneTree1 = factory1.OpenOrCreate();
Maintainer1 = ZoneTree1.CreateMaintainer();
Expand All @@ -141,7 +135,7 @@ public IndexOfTokenRecordPreviousToken(
this.useSecondaryIndex = useSecondaryIndex;
if (useSecondaryIndex)
{
var factory2 = new ZoneTreeFactory<CompositeKeyOfRecordToken<TRecord, TToken>, byte>()
var factory2 = new ZoneTreeFactory<CompositeKeyOfRecordToken<TRecord, TToken>, byte>(fileStreamProvider)
.SetDataDirectory($"{dataPath}/index2")
.SetIsDeletedDelegate(
(in CompositeKeyOfRecordToken<TRecord, TToken> key, in byte value) => value == 1)
Expand All @@ -152,7 +146,7 @@ public IndexOfTokenRecordPreviousToken(
recordComparer,
tokenComparer));

configure2?.Invoke(factory2);
advancedOptions?.FactoryConfigurator2?.Invoke(factory2);

ZoneTree2 = factory2.OpenOrCreate();
Maintainer2 = ZoneTree2.CreateMaintainer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Tenray.ZoneTree;
using ZoneTree.FullTextSearch.Model;
using Tenray.ZoneTree.AbstractFileStream;

namespace ZoneTree.FullTextSearch.SearchEngines;

/// <summary>
/// Provides advanced options for configuring the underlying ZoneTree instances
/// used in the full-text search engine.
/// </summary>
/// <typeparam name="TRecord">
/// The type of the record being indexed.
/// </typeparam>
/// <typeparam name="TToken">
/// The type of the token used for hashing and indexing.
/// </typeparam>
public sealed class AdvancedZoneTreeOptions<TRecord, TToken>
where TRecord : unmanaged
where TToken : unmanaged
{
/// <summary>
/// Gets or sets the <see cref="IFileStreamProvider"/> used to manage file streams
/// for storing ZoneTree data. If this is <c>null</c>, the default implementation
/// provided by ZoneTree will be used.
/// </summary>
public IFileStreamProvider FileStreamProvider { get; set; }

/// <summary>
/// Gets or sets an optional delegate that configures the <see cref="ZoneTreeFactory{TKey,TValue}"/>
/// for the <see cref="CompositeKeyOfTokenRecordPrevious{TRecord, TToken}"/> keys
/// and <see cref="byte"/> values.
/// <para>
/// This is called before the factory builds its internal ZoneTree. You can use it
/// to configure advanced settings such as in-memory or on-disk data paths, caching,
/// block sizes, compression, or other low-level ZoneTree behaviors.
/// </para>
/// </summary>
/// <remarks>
/// This configurator applies specifically to data indexed by the hashed token
/// combined with the "previous token" to enforce token order.
/// </remarks>
public Action<
ZoneTreeFactory<
CompositeKeyOfTokenRecordPrevious<TRecord, TToken>,
byte>> FactoryConfigurator1
{ get; set; }

/// <summary>
/// Gets or sets an optional delegate that configures the <see cref="ZoneTreeFactory{TKey,TValue}"/>
/// for the <see cref="CompositeKeyOfRecordToken{TRecord, TToken}"/> keys and <see cref="byte"/> values.
/// <para>
/// Similar to <see cref="FactoryConfigurator1"/>, this is invoked before the factory
/// completes its setup, allowing custom adjustments for storage, caching, and other
/// advanced ZoneTree features.
/// </para>
/// </summary>
/// <remarks>
/// This configurator applies specifically to data indexed by the record combined
/// with the token, often used for efficient record deletion or secondary indexing.
/// </remarks>
public Action<
ZoneTreeFactory<
CompositeKeyOfRecordToken<TRecord, TToken>,
byte>> FactoryConfigurator2
{ get; set; }
}
16 changes: 12 additions & 4 deletions src/ZoneTree.FullTextSearch/SearchEngines/HashedSearchEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using ZoneTree.FullTextSearch.Tokenizer;
using ZoneTree.FullTextSearch.Hashing;
using System.Security.Cryptography;
using ZoneTree.FullTextSearch.Model;
using Tenray.ZoneTree.AbstractFileStream;

namespace ZoneTree.FullTextSearch.SearchEngines;

Expand All @@ -35,6 +37,11 @@ public sealed class HashedSearchEngine<TRecord> : IDisposable
/// </summary>
readonly IHashCodeGenerator HashCodeGenerator;

/// <summary>
/// The flag that describes if the instance is disposed.
/// </summary>
bool isDisposed;

/// <summary>
/// Initializes a new instance of the <see cref="HashedSearchEngine{TRecord}"/> class.
/// </summary>
Expand All @@ -44,21 +51,24 @@ public sealed class HashedSearchEngine<TRecord> : IDisposable
/// <param name="wordTokenizer">The tokenizer used to split words. If null, a default tokenizer is used.</param>
/// <param name="hashCodeGenerator">The hash code generator used to generate hash codes for the tokens. If null, a default generator is used.</param>
/// <param name="blockCacheLifeTimeInMilliseconds">Defines the life time of cached blocks. Default is 1 minute.</param>
/// <param name="advancedOptions">Advanced ZoneTree Options enabling customization of underlying ZoneTree instances.</param>
public HashedSearchEngine(
string dataPath = "data",
bool useSecondaryIndex = false,
IWordTokenizer wordTokenizer = null,
IRefComparer<TRecord> recordComparer = null,
IHashCodeGenerator hashCodeGenerator = null,
long blockCacheLifeTimeInMilliseconds = 60_000)
long blockCacheLifeTimeInMilliseconds = 60_000,
AdvancedZoneTreeOptions<TRecord, ulong> advancedOptions = null)
{
HashCodeGenerator = hashCodeGenerator ?? new DefaultHashCodeGenerator();
Index = new(
dataPath,
recordComparer,
new UInt64ComparerAscending(),
useSecondaryIndex,
blockCacheLifeTimeInMilliseconds: blockCacheLifeTimeInMilliseconds);
blockCacheLifeTimeInMilliseconds,
advancedOptions);
WordTokenizer =
wordTokenizer ??
new WordTokenizer(hashCodeGenerator: HashCodeGenerator);
Expand Down Expand Up @@ -413,8 +423,6 @@ public void Drop()
Index.Drop();
}

bool isDisposed;

/// <summary>
/// Disposes the resources used by the search engine.
/// </summary>
Expand Down
12 changes: 9 additions & 3 deletions src/ZoneTree.FullTextSearch/Storage/RecordTable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Tenray.ZoneTree;
using Tenray.ZoneTree.AbstractFileStream;

namespace ZoneTree.FullTextSearch;

Expand Down Expand Up @@ -34,6 +35,9 @@ public sealed class RecordTable<TRecord, TValue> : IDisposable where TRecord : u
/// </summary>
public bool IsDropped { get => isDropped; }

/// <summary>
/// The flag that describes if the instance is dropped.
/// </summary>
bool isDropped;

/// <summary>
Expand All @@ -43,15 +47,17 @@ public sealed class RecordTable<TRecord, TValue> : IDisposable where TRecord : u
/// <param name="factory1">Optional configuration action for the first ZoneTree factory.</param>
/// <param name="factory2">Optional configuration action for the second ZoneTree factory.</param>
/// <param name="blockCacheLifeTimeInMilliseconds">Defines the life time of cached blocks. Default is 1 minute.</param>
/// <param name="fileStreamProvider">Optional custom file stream provider.</param>
public RecordTable(
string dataPath = "data",
Action<ZoneTreeFactory<TRecord, TValue>> factory1 = null,
Action<ZoneTreeFactory<TValue, TRecord>> factory2 = null,
long blockCacheLifeTimeInMilliseconds = 60_000)
long blockCacheLifeTimeInMilliseconds = 60_000,
IFileStreamProvider fileStreamProvider = null)
{
var f1 = new ZoneTreeFactory<TRecord, TValue>()
var f1 = new ZoneTreeFactory<TRecord, TValue>(fileStreamProvider)
.SetDataDirectory($"{dataPath}/rectable1");
var f2 = new ZoneTreeFactory<TValue, TRecord>()
var f2 = new ZoneTreeFactory<TValue, TRecord>(fileStreamProvider)
.SetDataDirectory($"{dataPath}/rectable2");
factory1?.Invoke(f1);
factory2?.Invoke(f2);
Expand Down
2 changes: 1 addition & 1 deletion src/ZoneTree.FullTextSearch/ZoneTree.FullTextSearch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ZoneTree" Version="1.8.4" />
<PackageReference Include="ZoneTree" Version="1.8.5" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 6d1ec68

Please sign in to comment.