summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-container-pool.h
blob: 57ae9c2706c52d6dcd55504e1b1b810363eb82a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef SLANG_CONTAINER_POOL_H
#define SLANG_CONTAINER_POOL_H

#include "../core/slang-dictionary.h"
#include "../core/slang-list.h"
#include "../core/slang-virtual-object-pool.h"

// A pool to allow reuse of common types of containers to avoid
// frequent resizing and rehashing.

namespace Slang
{
static const int kContainerPoolSize = 1024;

template<typename T>
struct ObjectPool
{
    ObjectPool(int maxElementCount)
    {
        m_pool.initPool(maxElementCount);
        m_objects.setCount(maxElementCount);
    }

    T* getObject()
    {
        auto id = m_pool.alloc(1);
        if (id == -1)
            SLANG_UNEXPECTED("container pool allocation failure.");
        return &m_objects[id];
    }

    void freeObject(T* object)
    {
        auto id = (int)(object - m_objects.getBuffer());
        m_pool.free(id, 1);
    }

    VirtualObjectPool m_pool;
    List<T> m_objects;
};

struct ContainerPool
{
    ObjectPool<List<void*>> m_listPool;
    ObjectPool<Dictionary<void*, void*>> m_dictionaryPool;
    ObjectPool<HashSet<void*>> m_hashSetPool;

    ContainerPool()
        : m_listPool(kContainerPoolSize)
        , m_dictionaryPool(kContainerPoolSize)
        , m_hashSetPool(kContainerPoolSize)
    {
    }

    template<typename T>
    List<T*>* getList()
    {
        return (List<T*>*)m_listPool.getObject();
    }

    template<typename T, typename U>
    Dictionary<T*, U*>* getDictionary()
    {
        return (Dictionary<T*, U*>*)m_dictionaryPool.getObject();
    }

    template<typename T>
    HashSet<T*>* getHashSet()
    {
        return (HashSet<T*>*)m_hashSetPool.getObject();
    }

    template<typename T>
    void free(List<T*>* list)
    {
        list->clear();
        m_listPool.freeObject((List<void*>*)list);
    }

    template<typename T, typename U>
    void free(Dictionary<T*, U*>* dict)
    {
        dict->clear();
        m_dictionaryPool.freeObject((Dictionary<void*, void*>*)dict);
    }

    template<typename T>
    void free(HashSet<T*>* set)
    {
        set->clear();
        m_hashSetPool.freeObject((HashSet<void*>*)set);
    }
};
} // namespace Slang

#endif