Skip to content

Commit 40d48cd

Browse files
committed
5.0.0
-Add LargeObservableCollection<T> and ReadOnlyLargeObservableCollection<T> -Interface redesign -Bug fixes -Improve Tests -Upgrade sln to slnx
1 parent 4e67335 commit 40d48cd

28 files changed

Lines changed: 5440 additions & 466 deletions

LargeCollections.DiskCache/DiskCache.cs

Lines changed: 101 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ public TValue this[TKey key]
186186
protected SqliteCommand[] _deleteItemCommands;
187187
protected SqliteParameter[] _deleteItemIdParameters;
188188

189+
protected SqliteCommand[] _queryIdAndItemCommands;
190+
protected SqliteParameter[] _queryIdAndItemIdParameters;
191+
189192
protected SqliteCommand[] _queryItemCommands;
190193
protected SqliteParameter[] _queryItemIdParameters;
191194

@@ -297,6 +300,8 @@ public DiskCache(
297300
_upsertItemItemParameters = new SqliteParameter[DegreeOfParallelism];
298301
_deleteItemCommands = new SqliteCommand[DegreeOfParallelism];
299302
_deleteItemIdParameters = new SqliteParameter[DegreeOfParallelism];
303+
_queryIdAndItemCommands = new SqliteCommand[DegreeOfParallelism];
304+
_queryIdAndItemIdParameters = new SqliteParameter[DegreeOfParallelism];
300305
_queryItemCommands = new SqliteCommand[DegreeOfParallelism];
301306
_queryItemIdParameters = new SqliteParameter[DegreeOfParallelism];
302307
_countItemsCommands = new SqliteCommand[DegreeOfParallelism];
@@ -360,14 +365,21 @@ public DiskCache(
360365
_upsertItemCommands[i].Prepare();
361366

362367
_deleteItemCommands[i] = _connections[i].CreateCommand();
363-
_deleteItemCommands[i].CommandText = $"DELETE FROM items WHERE id = @id;";
368+
_deleteItemCommands[i].CommandText = $"DELETE FROM items WHERE id = @id RETURNING item;";
364369
_deleteItemIdParameters[i] = new SqliteParameter("@id", _keyType);
365370
_deleteItemCommands[i].Parameters.Add(_deleteItemIdParameters[i]);
366371
_deleteItemCommands[i].Transaction = _transactions[i];
367372
_deleteItemCommands[i].Prepare();
368373

374+
_queryIdAndItemCommands[i] = _connections[i].CreateCommand();
375+
_queryIdAndItemCommands[i].CommandText = $"SELECT id, item FROM items WHERE id = @id;";
376+
_queryIdAndItemIdParameters[i] = new SqliteParameter("@id", _keyType);
377+
_queryIdAndItemCommands[i].Parameters.Add(_queryIdAndItemIdParameters[i]);
378+
_queryIdAndItemCommands[i].Transaction = _transactions[i];
379+
_queryIdAndItemCommands[i].Prepare();
380+
369381
_queryItemCommands[i] = _connections[i].CreateCommand();
370-
_queryItemCommands[i].CommandText = $"SELECT id, item FROM items WHERE id = @id;";
382+
_queryItemCommands[i].CommandText = $"SELECT item FROM items WHERE id = @id;";
371383
_queryItemIdParameters[i] = new SqliteParameter("@id", _keyType);
372384
_queryItemCommands[i].Parameters.Add(_queryItemIdParameters[i]);
373385
_queryItemCommands[i].Transaction = _transactions[i];
@@ -616,17 +628,17 @@ public bool TryGetValue(TKey key, out TValue value)
616628
{
617629
_queryItemIdParameters[index].Value = keyParameterValue;
618630

619-
using SqliteDataReader reader = _queryItemCommands[index].ExecuteReader();
631+
object item = _queryItemCommands[index].ExecuteScalar();
620632

621-
if (reader.Read())
633+
if (item != null)
622634
{
623635
if (typeof(TValue) == typeof(long) || typeof(TValue) == typeof(string) || typeof(TValue) == typeof(byte[]) || typeof(TValue) == typeof(double))
624636
{
625-
value = (TValue)reader.GetValue(1);
637+
value = (TValue)item;
626638
}
627639
else
628640
{
629-
byte[] serializedValue = (byte[])reader.GetValue(1);
641+
byte[] serializedValue = (byte[])item;
630642

631643
value = _deserializeValueFunction(serializedValue);
632644
}
@@ -668,6 +680,23 @@ public void AddRange(IEnumerable<KeyValuePair<TKey, TValue>> items)
668680
}
669681
}
670682

683+
#if NETSTANDARD2_1_OR_GREATER
684+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
685+
public void AddRange(ReadOnlySpan<KeyValuePair<TKey, TValue>> items)
686+
{
687+
if (IsReadOnly)
688+
{
689+
throw new InvalidOperationException("Modifications are not allowed when opened in read only mode.");
690+
}
691+
692+
for(int i = 0; i < items.Length; i++)
693+
{
694+
KeyValuePair<TKey, TValue> item = items[i];
695+
Set(item.Key, item.Value);
696+
}
697+
}
698+
#endif
699+
671700
[MethodImpl(MethodImplOptions.AggressiveInlining)]
672701
public void AddParallel(IEnumerable<KeyValuePair<TKey, TValue>>[] parallelItems)
673702
{
@@ -685,21 +714,53 @@ public void AddParallel(IEnumerable<KeyValuePair<TKey, TValue>>[] parallelItems)
685714
}
686715

687716
[MethodImpl(MethodImplOptions.AggressiveInlining)]
688-
public void Remove(TKey key)
717+
public bool Remove(TKey key)
718+
=> Remove(key, true, out _);
719+
720+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
721+
public bool Remove(TKey key, out TValue removedValue)
722+
=> Remove(key, false, out removedValue);
723+
724+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
725+
public bool Remove(KeyValuePair<TKey, TValue> item)
726+
=> Remove(item.Key, false, out _);
727+
728+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
729+
public bool Remove(KeyValuePair<TKey, TValue> item, out TValue removedValue)
730+
=> Remove(item.Key, false, out removedValue);
731+
732+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
733+
public bool Remove(KeyValuePair<TKey, TValue> item, out KeyValuePair<TKey, TValue> removedItem)
734+
{
735+
removedItem = default;
736+
737+
if (Remove(item.Key, false, out TValue removedValue))
738+
{
739+
removedItem = new KeyValuePair<TKey, TValue>(item.Key, removedValue);
740+
return true;
741+
}
742+
743+
return false;
744+
}
745+
746+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
747+
private bool Remove(TKey key, bool ignoreReturnedValue, out TValue removedValue)
689748
{
690749
if (IsReadOnly)
691750
{
692751
throw new InvalidOperationException("Modifications are not allowed when opened in read only mode.");
693752
}
694753

695-
int index = 0;
696-
object keyParameterValue = null;
697-
698754
if (key is null)
699755
{
700756
throw new ArgumentNullException(nameof(key));
701757
}
702758

759+
removedValue = default;
760+
761+
int index = 0;
762+
object keyParameterValue = null;
763+
703764
if (typeof(TKey) == typeof(long))
704765
{
705766
if (key is long longKey)
@@ -714,7 +775,7 @@ public void Remove(TKey key)
714775
{
715776
if (stringKey.Length == 0)
716777
{
717-
return;
778+
return false;
718779
}
719780

720781
index = GetParallelIndex(stringKey, DegreeOfParallelism);
@@ -727,7 +788,7 @@ public void Remove(TKey key)
727788
{
728789
if (bytesKey.Length == 0)
729790
{
730-
return;
791+
return false;
731792
}
732793
if (bytesKey.Length > DiskCacheConstants.MaxItemLength)
733794
{
@@ -742,7 +803,7 @@ public void Remove(TKey key)
742803
{
743804
if (_serializeKeyFunction is null)
744805
{
745-
return;
806+
return false;
746807
}
747808

748809
byte[] serializedKey = _serializeKeyFunction(key)
@@ -765,51 +826,28 @@ public void Remove(TKey key)
765826
{
766827
_deleteItemIdParameters[index].Value = keyParameterValue;
767828

768-
_deleteItemCommands[index].ExecuteNonQuery();
769-
}
770-
}
829+
object removedItem = _deleteItemCommands[index].ExecuteScalar();
771830

772-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
773-
public void Remove(IEnumerable<TKey> keys)
774-
{
775-
if (keys is null)
776-
{
777-
throw new ArgumentNullException(nameof(keys));
778-
}
779-
780-
foreach (TKey key in keys)
781-
{
782-
Remove(key);
783-
}
784-
}
785-
786-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
787-
public void Remove(KeyValuePair<TKey, TValue> item)
788-
{
789-
if (IsReadOnly)
790-
{
791-
throw new InvalidOperationException("Modifications are not allowed when opened in read only mode.");
792-
}
793-
794-
Remove(item.Key);
795-
}
796-
797-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
798-
public void Remove(IEnumerable<KeyValuePair<TKey, TValue>> items)
799-
{
800-
if (items is null)
801-
{
802-
throw new ArgumentNullException(nameof(items));
803-
}
831+
if (removedItem is null)
832+
{
833+
return false;
834+
}
835+
if (ignoreReturnedValue)
836+
{
837+
return true;
838+
}
804839

805-
if (IsReadOnly)
806-
{
807-
throw new InvalidOperationException("Modifications are not allowed when opened in read only mode.");
808-
}
840+
if (typeof(TValue) == typeof(long) || typeof(TValue) == typeof(string) || typeof(TValue) == typeof(byte[]) || typeof(TValue) == typeof(double))
841+
{
842+
removedValue = (TValue)removedItem;
843+
}
844+
else
845+
{
846+
byte[] serializedValue = (byte[])removedItem;
809847

810-
foreach (KeyValuePair<TKey, TValue> item in items)
811-
{
812-
Remove(item.Key);
848+
removedValue = _deserializeValueFunction(serializedValue);
849+
}
850+
return true;
813851
}
814852
}
815853

@@ -826,7 +864,7 @@ public void RemoveParallel(IEnumerable<TKey>[] parallelKeys)
826864
throw new InvalidOperationException("Modifications are not allowed when opened in read only mode.");
827865

828866
}
829-
parallelKeys.DoParallel(Remove);
867+
parallelKeys.DoParallel(key => Remove(key));
830868
}
831869

832870
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -988,6 +1026,12 @@ public virtual void Dispose()
9881026
_deleteItemCommands[i] = null;
9891027
}
9901028

1029+
if (_queryIdAndItemCommands is not null && _queryIdAndItemCommands[i] is not null)
1030+
{
1031+
_queryIdAndItemCommands[i].Dispose();
1032+
_queryIdAndItemCommands[i] = null;
1033+
}
1034+
9911035
if (_queryItemCommands is not null && _queryItemCommands[i] is not null)
9921036
{
9931037
_queryItemCommands[i].Dispose();
@@ -1041,6 +1085,7 @@ public virtual void Dispose()
10411085

10421086
_upsertItemCommands = null;
10431087
_deleteItemCommands = null;
1088+
_queryIdAndItemCommands = null;
10441089
_queryItemCommands = null;
10451090
_countItemsCommands = null;
10461091
_clearItemsCommands = null;

LargeCollections.DiskCache/LargeCollections.DiskCache.csproj

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,21 @@
2020
<PackageReadmeFile>README.md</PackageReadmeFile>
2121
<Title>LargeCollections.DiskCache</Title>
2222
<Product>LargeCollections.DiskCache</Product>
23-
<Version>4.0.0</Version>
24-
<AssemblyVersion>4.0.0</AssemblyVersion>
25-
<FileVersion>4.0.0</FileVersion>
23+
<Version>5.0.0</Version>
24+
<AssemblyVersion>5.0.0</AssemblyVersion>
25+
<FileVersion>5.0.0</FileVersion>
2626
<SignAssembly>False</SignAssembly>
2727
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
2828
<PackageId>DevAM.LargeCollections.DiskCache</PackageId>
2929
</PropertyGroup>
3030

3131
<ItemGroup>
32-
<None
33-
Include="../README.md"
34-
Pack="true"
35-
PackagePath="/"
36-
CopyToOutputDirectory="PreserveNewest">
32+
<None Include="../README.md" Pack="true" PackagePath="/" CopyToOutputDirectory="PreserveNewest">
3733
</None>
3834
</ItemGroup>
3935

4036
<ItemGroup>
41-
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
37+
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.9" />
4238
</ItemGroup>
4339

4440
<ItemGroup>

0 commit comments

Comments
 (0)