-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added bassic object pools * Refactor DigestionAgent to use HashSetPool for indices
- Loading branch information
Showing
8 changed files
with
431 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | ||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=objectpools/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.ObjectPool; | ||
|
||
namespace MzLibUtil; | ||
|
||
// Example Usage: | ||
// var pool = new DictionaryPool<int, int>(); | ||
// var dictionary = pool.Get(); | ||
// try { | ||
// dictionary.Add(1,1); | ||
// Do Work | ||
// } | ||
// finally { | ||
// pool.Return(dictionary); | ||
// } | ||
|
||
/// <summary> | ||
/// Provides a pool for <see cref="Dictionary{TKey, TValue}"/> instances to reduce memory allocations. | ||
/// This class uses the <see cref="ObjectPool{T}"/> from Microsoft.Extensions.ObjectPool | ||
/// to manage the pooling of <see cref="Dictionary{TKey, TValue}"/> objects. | ||
/// </summary> | ||
/// <typeparam name="TKey">The type of keys in the <see cref="Dictionary{TKey, TValue}"/>.</typeparam> | ||
/// <typeparam name="TValue">The type of values in the <see cref="Dictionary{TKey, TValue}"/>.</typeparam> | ||
/// <remarks> | ||
/// This class is not thread-safe and should not be shared between threads. | ||
/// This class should be pulled from outside a try finally loop and finally should return the Dictionary to the pool to ensure proper pooling in the case of a caught exception. | ||
/// </remarks> | ||
public class DictionaryPool<TKey, TValue> where TKey : notnull | ||
{ | ||
private readonly ObjectPool<Dictionary<TKey, TValue>> _pool; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DictionaryPool{TKey, TValue}"/> class. | ||
/// </summary> | ||
/// <param name="initialCapacity">Initial capacity for the pooled Dictionary instances.</param> | ||
public DictionaryPool(int initialCapacity = 16) | ||
{ | ||
var policy = new DictionaryPooledObjectPolicy<TKey, TValue>(initialCapacity); | ||
var provider = new DefaultObjectPoolProvider { MaximumRetained = Environment.ProcessorCount * 2 }; | ||
_pool = provider.Create(policy); | ||
} | ||
|
||
/// <summary> | ||
/// Retrieves a Dictionary instance from the pool. | ||
/// </summary> | ||
/// <returns>A Dictionary instance.</returns> | ||
public Dictionary<TKey, TValue> Get() => _pool.Get(); | ||
|
||
/// <summary> | ||
/// Returns a Dictionary instance back to the pool. | ||
/// </summary> | ||
/// <param name="dictionary">The Dictionary instance to return.</param> | ||
public void Return(Dictionary<TKey, TValue> dictionary) | ||
{ | ||
if (dictionary == null) throw new ArgumentNullException(nameof(dictionary)); | ||
dictionary.Clear(); // Ensure the Dictionary is clean before returning it to the pool | ||
_pool.Return(dictionary); | ||
} | ||
|
||
/// <summary> | ||
/// Policy for pooling Dictionary instances with a specified initial capacity. | ||
/// </summary> | ||
/// <typeparam name="TKeyItem">The type of keys in the Dictionary.</typeparam> | ||
/// <typeparam name="TValueItem">The type of values in the Dictionary.</typeparam> | ||
/// <param name="initialCapacity">The initial capacity for the pooled Dictionary instances.</param> | ||
private class DictionaryPooledObjectPolicy<TKeyItem, TValueItem>(int initialCapacity) | ||
: PooledObjectPolicy<Dictionary<TKeyItem, TValueItem>> | ||
where TKeyItem : notnull | ||
{ | ||
private int InitialCapacity { get; } = initialCapacity; | ||
|
||
/// <summary> | ||
/// Creates a new Dictionary instance with the specified initial capacity. | ||
/// </summary> | ||
/// <returns>A new Dictionary instance.</returns> | ||
public override Dictionary<TKeyItem, TValueItem> Create() | ||
{ | ||
return new Dictionary<TKeyItem, TValueItem>(capacity: InitialCapacity); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a Dictionary instance to the pool after clearing it. | ||
/// </summary> | ||
/// <param name="obj">The Dictionary instance to return.</param> | ||
/// <returns>True if the Dictionary instance can be reused; otherwise, false.</returns> | ||
public override bool Return(Dictionary<TKeyItem, TValueItem> obj) | ||
{ | ||
// Ensure the Dictionary can be safely reused | ||
obj.Clear(); | ||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.ObjectPool; | ||
|
||
namespace MzLibUtil; | ||
|
||
|
||
// Example Usage: | ||
// var pool = new HashSetPool<int>(); | ||
// var hashSet = pool.Get(); | ||
// try { | ||
// hashSet.Add(1); | ||
// Do Work | ||
// } | ||
// finally { | ||
// pool.Return(hashSet); | ||
// } | ||
|
||
/// <summary> | ||
/// Provides a pool for <see cref="HashSet{T}"/> instances to reduce memory allocations. | ||
/// This class uses the <see cref="ObjectPool{T}"/> from Microsoft.Extensions.ObjectPool | ||
/// to manage the pooling of <see cref="HashSet{T}"/> objects. | ||
/// </summary> | ||
/// <typeparam name="T">The type of elements in the <see cref="HashSet{T}"/>.</typeparam> | ||
/// <remarks> | ||
/// This class is not thread-safe and should not be shared between threads. | ||
/// This class should be pulled from outside a try finally loop and finally should return the HashSet to the pool to ensure proper pooling in the case of a caught exception | ||
/// See example found in DigestionAgent.GetDigestionSiteIndices() for proper usage | ||
/// </remarks> | ||
public class HashSetPool<T> | ||
{ | ||
private readonly ObjectPool<HashSet<T>> _pool; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="HashSetPool{T}"/> class. | ||
/// </summary> | ||
/// <param name="initialCapacity">Initial capacity for the pooled HashSet instances.</param> | ||
public HashSetPool(int initialCapacity = 16) | ||
{ | ||
var policy = new HashSetPooledObjectPolicy<T>(initialCapacity); | ||
_pool = new DefaultObjectPool<HashSet<T>>(policy); | ||
} | ||
|
||
/// <summary> | ||
/// Retrieves a <see cref="HashSet{T}"/> instance from the pool. | ||
/// </summary> | ||
/// <returns>A <see cref="HashSet{T}"/> instance.</returns> | ||
public HashSet<T> Get() => _pool.Get(); | ||
|
||
/// <summary> | ||
/// Returns a <see cref="HashSet{T}"/> instance back to the pool. | ||
/// </summary> | ||
/// <param name="hashSet">The <see cref="HashSet{T}"/> instance to return.</param> | ||
public void Return(HashSet<T> hashSet) | ||
{ | ||
if (hashSet == null) throw new ArgumentNullException(nameof(hashSet)); | ||
hashSet.Clear(); // Ensure the HashSet is clean before returning it to the pool | ||
_pool.Return(hashSet); | ||
} | ||
|
||
/// <summary> | ||
/// Defines the policy for creating and returning <see cref="HashSet{T}"/> instances to the pool. | ||
/// </summary> | ||
/// <typeparam name="TItem">The type of elements in the <see cref="HashSet{T}"/>.</typeparam> | ||
private class HashSetPooledObjectPolicy<TItem>(int initialCapacity) : PooledObjectPolicy<HashSet<TItem>> | ||
{ | ||
/// <summary> | ||
/// Creates a new <see cref="HashSet{T}"/> instance with the specified initial capacity. | ||
/// </summary> | ||
/// <returns>A new <see cref="HashSet{T}"/> instance.</returns> | ||
public override HashSet<TItem> Create() | ||
{ | ||
return new HashSet<TItem>(capacity: initialCapacity); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a <see cref="HashSet{T}"/> instance to the pool after clearing it. | ||
/// </summary> | ||
/// <param name="obj">The <see cref="HashSet{T}"/> instance to return.</param> | ||
/// <returns>Always returns true.</returns> | ||
public override bool Return(HashSet<TItem> obj) | ||
{ | ||
// Ensure the HashSet can be safely reused | ||
obj.Clear(); | ||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.ObjectPool; | ||
|
||
namespace MzLibUtil; | ||
|
||
// Example Usage: | ||
// var pool = new ListPool<int>(); | ||
// var list = pool.Get(); | ||
// try { | ||
// list.Add(1); | ||
// Do Work | ||
// } | ||
// finally { | ||
// pool.Return(list); | ||
// } | ||
|
||
/// <summary> | ||
/// Provides a pool for <see cref="List{T}"/> instances to reduce memory allocations. | ||
/// This class uses the <see cref="ObjectPool{T}"/> from Microsoft.Extensions.ObjectPool | ||
/// to manage the pooling of <see cref="List{T}"/> objects. | ||
/// </summary> | ||
/// <typeparam name="T">The type of elements in the <see cref="List{T}"/>.</typeparam> | ||
/// <remarks> | ||
/// This class is not thread-safe and should not be shared between threads. | ||
/// This class should be pulled from outside a try finally loop and finally should return the List to the pool to ensure proper pooling in the case of a caught exception. | ||
/// </remarks> | ||
public class ListPool<T> | ||
{ | ||
private readonly ObjectPool<List<T>> _pool; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ListPool{T}"/> class. | ||
/// </summary> | ||
/// <param name="initialCapacity">Initial capacity for the pooled HashSet instances.</param> | ||
public ListPool(int initialCapacity = 16) | ||
{ | ||
var policy = new ListPooledObjectPolicy<T>(initialCapacity); | ||
var provider = new DefaultObjectPoolProvider { MaximumRetained = Environment.ProcessorCount * 2 }; | ||
_pool = provider.Create(policy); | ||
} | ||
|
||
/// <summary> | ||
/// Retrieves a HashSet instance from the pool. | ||
/// </summary> | ||
/// <returns>A HashSet instance.</returns> | ||
public List<T> Get() => _pool.Get(); | ||
|
||
/// <summary> | ||
/// Returns a HashSet instance back to the pool. | ||
/// </summary> | ||
/// <param name="list">The HashSet instance to return.</param> | ||
public void Return(List<T> list) | ||
{ | ||
if (list == null) throw new ArgumentNullException(nameof(list)); | ||
list.Clear(); // Ensure the HashSet is clean before returning it to the pool | ||
_pool.Return(list); | ||
} | ||
|
||
/// <summary> | ||
/// Policy for pooling List instances with a specified initial capacity. | ||
/// </summary> | ||
/// <typeparam name="TItem">The type of elements in the List.</typeparam> | ||
/// <param name="initialCapacity">The initial capacity for the pooled List instances.</param> | ||
private class ListPooledObjectPolicy<TItem>(int initialCapacity) : PooledObjectPolicy<List<TItem>> | ||
{ | ||
private int InitialCapacity { get; } = initialCapacity; | ||
|
||
/// <summary> | ||
/// Creates a new List instance with the specified initial capacity. | ||
/// </summary> | ||
/// <returns>A new List instance.</returns> | ||
public override List<TItem> Create() | ||
{ | ||
return new List<TItem>(capacity: InitialCapacity); | ||
} | ||
|
||
/// <summary> | ||
/// Resets the List instance to a clean state before returning it to the pool. | ||
/// </summary> | ||
/// <param name="obj">The List instance to reset and return.</param> | ||
/// <returns>True if the List instance can be returned to the pool; otherwise, false.</returns> | ||
public override bool Return(List<TItem> obj) | ||
{ | ||
// Ensure the List can be safely reused | ||
obj.Clear(); | ||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.