Skip to content

Commit

Permalink
Minor performance enhancements.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkCiliaVincenti committed Nov 26, 2022
1 parent ccd55b8 commit 21ef48b
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 8 deletions.
8 changes: 4 additions & 4 deletions AsyncKeyedLock/AsyncKeyedLock.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
<RepositoryUrl>https://github.com/MarkCiliaVincenti/AsyncKeyedLock.git</RepositoryUrl>
<PackageProjectUrl>https://github.com/MarkCiliaVincenti/AsyncKeyedLock</PackageProjectUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>5.0.2-rc</Version>
<Version>5.0.3</Version>
<PackageIcon>logo.png</PackageIcon>
<PackageReleaseNotes>Performance improvements and allowing for object pooling.</PackageReleaseNotes>
<PackageReleaseNotes>Minor performance enhancements.</PackageReleaseNotes>
<Description>An asynchronous .NET Standard 2.0 library that allows you to lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number.</Description>
<Copyright>© 2022 Mark Cilia Vincenti</Copyright>
<PackageTags>async,lock,key,semaphore,dictionary,pooling,duplicate</PackageTags>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<AssemblyVersion>5.0.1.9</AssemblyVersion>
<FileVersion>5.0.1.9</FileVersion>
<AssemblyVersion>5.0.3.0</AssemblyVersion>
<FileVersion>5.0.3.0</FileVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<IsPackable>true</IsPackable>
<IsTrimmable>true</IsTrimmable>
Expand Down
5 changes: 4 additions & 1 deletion AsyncKeyedLock/AsyncKeyedLockPool.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;

namespace AsyncKeyedLock
{
Expand All @@ -12,12 +13,13 @@ public AsyncKeyedLockPool(Func<TKey, AsyncKeyedLockReleaser<TKey>> objectGenerat
{
_objects = new BlockingCollection<AsyncKeyedLockReleaser<TKey>>(new ConcurrentBag<AsyncKeyedLockReleaser<TKey>>(), capacity);
_objectGenerator = objectGenerator;
for (int i = 0; i < capacity; i++)
for (int i = 0; i < capacity; ++i)
{
_objects.Add(_objectGenerator(default));
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AsyncKeyedLockReleaser<TKey> GetObject(TKey key)
{
if (_objects.TryTake(out var item))
Expand All @@ -28,6 +30,7 @@ public AsyncKeyedLockReleaser<TKey> GetObject(TKey key)
return _objectGenerator(key);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PutObject(AsyncKeyedLockReleaser<TKey> item)
{
_objects.TryAdd(item);
Expand Down
2 changes: 1 addition & 1 deletion AsyncKeyedLock/AsyncKeyedLockReleaser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal bool TryIncrement()
{
if (Monitor.TryEnter(this))
{
_referenceCount++;
++_referenceCount;
Monitor.Exit(this);
return true;
}
Expand Down
5 changes: 4 additions & 1 deletion AsyncKeyedLock/AsyncKeyedLocker.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncKeyedLock
{
/// <summary>
/// AsyncKeyedLock class, originally inspired by <see href="https://stackoverflow.com/questions/31138179/asynchronous-locking-based-on-a-key/31194647#31194647">Stephen Cleary's solution</see>.
/// Represents a lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number.
/// </summary>
public sealed class AsyncKeyedLocker : AsyncKeyedLocker<object>
{
Expand Down Expand Up @@ -196,7 +197,9 @@ public AsyncKeyedLocker(AsyncKeyedLockOptions options, int concurrencyLevel, int
/// </summary>
/// <param name="key">The key for which a releaser should be obtained.</param>
/// <returns>A created or retrieved <see cref="AsyncKeyedLockReleaser{TKey}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AsyncKeyedLockReleaser<TKey> GetOrAdd(TKey key) => _dictionary.GetOrAdd(key);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Release(AsyncKeyedLockReleaser<TKey> releaser) => _dictionary.Release(releaser);


Expand Down
3 changes: 3 additions & 0 deletions AsyncKeyedLock/AsyncKeyedLockerDictionary.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;

namespace AsyncKeyedLock
Expand Down Expand Up @@ -66,6 +67,7 @@ public AsyncKeyedLockerDictionary(AsyncKeyedLockOptions options, int concurrency
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AsyncKeyedLockReleaser<TKey> GetOrAdd(TKey key)
{
if (TryGetValue(key, out var referenceCounter) && referenceCounter.TryIncrement())
Expand Down Expand Up @@ -110,6 +112,7 @@ public AsyncKeyedLockReleaser<TKey> GetOrAdd(TKey key)
return referenceCounter;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Release(AsyncKeyedLockReleaser<TKey> referenceCounter)
{
Monitor.Enter(referenceCounter);
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ bool isInUse = asyncKeyedLocker.IsInUse(myObject);
```

## Credits
This library was originally inspired by [Stephen Cleary's solution](https://stackoverflow.com/questions/31138179/asynchronous-locking-based-on-a-key/31194647#31194647).
This library was originally inspired by [Stephen Cleary's solution](https://stackoverflow.com/questions/31138179/asynchronous-locking-based-on-a-key/31194647#31194647), but has gone through a lot of changes since.

0 comments on commit 21ef48b

Please sign in to comment.