首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确判断循环池中的活动实例?

如何正确判断循环池中的活动实例?
EN

Stack Overflow用户
提问于 2021-03-19 16:55:24
回答 1查看 26关注 0票数 0

我有一个循环池实现

代码语言:javascript
复制
public class CircularPool<T> where T : class, new()
{
    private readonly Queue<T> instances;
    
    public CircularPool(int size)
    {
        instances = new Queue<T>(size);
        
        for (var i = 0; i < size; ++i)
        {
            instances.Enqueue(new T());
        }
    }

    public T GetInstance()
    {
        var instance = instances.Dequeue();
        instances.Enqueue(instance); // Circular pool
        return instance;
    }

    public void ReturnInstance(T instance)
    {
        // What does returning look like?
        // Could use IsActive flag?
    }

    public IEnumerable<T> GetActiveInstances()
    {
        return instances;  // TODO: Only want the active ones
    }
}

我希望能够跟踪池中当前正在使用的实例,这样我就可以迭代它们并执行各种操作

代码语言:javascript
复制
var pool = new CircularPool<Foo>(5);
var fooInstanceA = pool.GetInstance();
var fooInstanceB = pool.GetInstance();
var fooInstanceC = pool.GetInstance();

pool.ReturnInstance(fooInstanceB);

foreach (var activeInstance in pool.GetActiveInstances())
{
    // Do stuff with active instances (fooInstanceA then fooInstanceC)
}

如何正确获取按年限排序的活动实例?

假设这是一个循环池,那么如果在没有调用ReturnInstance的情况下调用GetInstance的次数超过池的大小,那么将返回最老的活动实例,并成为最年轻的活动实例。这应该相应地反映在GetActiveInstances中。

另外,在循环池的上下文中,ReturnInstance应该是什么样子?

EN

回答 1

Stack Overflow用户

发布于 2021-03-19 17:17:50

我们可以对所有实例使用数组T[],对活动实例使用HashSet<T>

代码语言:javascript
复制
public class CircularPool<T> where T : class, new() {
  private readonly T[] m_All;
  private readonly HashSet<T> m_InUse;

  private int m_Index; // Index to start looking for a free instance

  public CircularPool(int size) {
    if (size <= 0)
      throw new ArgumentOutOfRangeException(nameof(size));

    m_InUse = new HashSet<T>(size);
    m_All = Enumerable.Range(0, size).Select(_ => new T()).ToArray();
  }

  public bool TryGetInstance(out T availableInstance) {
    for (int i = 0; i < m_All.Length; ++i) {
      int index = (i + m_Index) % m_All.Length;

      if (m_InUse.Add(m_All[index])) {
        availableInstance = m_All[index];
        m_Index = index + 1;

        return true;
      }
    }

    availableInstance = default(T); // no available instances found
    return false;
  }

  public T GetInstance() => TryGetInstance(out var result)
    ? result
    : throw new InvalidOperationException("There are no available instances.");

  public bool ReturnInstance(T instance) => m_InUse.Remove(instance);

  public IEnumerable<T> GetActiveInstances() => m_InUse;

  public IEnumerable<T> GetAvailableInstances() => 
    m_All.Where(item => !m_All.Contains(item));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66705134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档