File: Allocator3D.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (228 lines) | stat: -rw-r--r-- 9,333 bytes parent folder | download | duplicates (2)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 * Copyright (C) 2021 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2021 Vladimir Sadovnikov <sadko4u@gmail.com>
 *
 * This file is part of lsp-dsp-units
 * Created on: 9 авг. 2021 г.
 *
 * lsp-dsp-units is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * lsp-dsp-units is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with lsp-dsp-units. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef LSP_PLUG_IN_DSP_UNITS_3D_ALLOCATOR3D_H_
#define LSP_PLUG_IN_DSP_UNITS_3D_ALLOCATOR3D_H_

#include <lsp-plug.in/dsp-units/version.h>
#include <lsp-plug.in/common/types.h>

namespace lsp
{
    namespace dspu
    {
        /**
         * Fixed-pointer allocator, allocates data grouped into partitions or 'chunks'
         * to avoid huge memory fragmentation
         */
        class LSP_DSP_UNITS_PUBLIC BasicAllocator3D
        {
            private:
                BasicAllocator3D(const BasicAllocator3D &);
                BasicAllocator3D & operator = (const BasicAllocator3D &);

            protected:
                size_t      nChunks;        // Number of chunks in vChunks array
                size_t      nShift;         // Chunk identifier shift
                size_t      nMask;          // Chunk item mask
                size_t      nSizeOf;        // Size of record (in bytes)
                size_t      nAllocated;     // Number of allocated items
                uint8_t   **vChunks;        // List of all chunks
                uint8_t    *pCurr;          // Current chunk
                size_t      nLeft;          // Number of left items

            protected:
                uint8_t    *get_chunk(size_t id);
                void       *do_alloc();
                void        do_clear();
                ssize_t     do_ialloc(void **p);
                void       *do_get(size_t idx);
                void        do_destroy();
                size_t      do_alloc_n(void **ptr, size_t n);
                void        do_swap(BasicAllocator3D *alloc);
                bool        do_validate(const void *ptr) const;
                ssize_t     calc_index_of(const void *ptr) const;

            public:
                explicit BasicAllocator3D(size_t sz_of, size_t c_size);
                ~BasicAllocator3D();
        };

        template <class T>
            class Allocator3D: public BasicAllocator3D
            {
                public:
                    /**
                     * Constructor
                     * @param csize chunk size, will be rounded to be power of 2
                     */
                    explicit Allocator3D(size_t csize): BasicAllocator3D(sizeof(T), csize) {}

                public:
                    /**
                     * Allocate single item
                     * @return pointer to allocated single item or NULL
                     */
                    inline T *alloc() { return reinterpret_cast<T *>(do_alloc()); }

                    /**
                     * Allocate single item
                     * @return pointer to allocated single item or negative error status
                     */
                    inline ssize_t ialloc(T **dst) { return do_ialloc(reinterpret_cast<void **>(dst)); }

                    /**
                     * Allocate single item and initialize with value
                     * @param src value to initialize
                     * @return pointer to allocated item or NULL
                     */
                    inline T *alloc(const T *src)
                    {
                        T *res = reinterpret_cast<T *>(do_alloc());
                        if (res != NULL)
                            *res = *src;
                        return res;
                    }

                    /**
                     * Allocate single item
                     * @return pointer to allocated single item or NULL
                     */
                    inline ssize_t ialloc(T **dst, const T *src) {
                        size_t res = do_ialloc(reinterpret_cast<void **>(dst));
                        if (*dst != NULL)
                            **dst = *src;
                        return res;
                    }

                    /**
                     * Allocate single item and initialize with value
                     * @param src value to initialize
                     * @return pointer to allocated item or NULL
                     */
                    inline T *alloc(const T &src)
                    {
                        T *res = reinterpret_cast<T *>(do_alloc());
                        if (res != NULL)
                            *res = src;
                        return res;
                    }

                    /**
                     * Allocate single item
                     * @return pointer to allocated single item or NULL
                     */
                    inline ssize_t ialloc(T **dst, const T &src) {
                        size_t res = do_ialloc(reinterpret_cast<void **>(dst));
                        if (*dst != NULL)
                            **dst = src;
                        return res;
                    }

                    /**
                     * Allocate set of items
                     * @param retval pointer to store pointers to allocated elements
                     * @param n number of elements to allocate
                     * @return actual number of allocated items
                     */
                    inline size_t alloc_n(T **retval, size_t n) { return do_alloc_n(reinterpret_cast<void **>(retval), n); }

                    /**
                     * Get number of allocated items
                     * @return number of allocated items
                     */
                    inline size_t size() const { return nAllocated; }

                    /**
                     * Get number of elements per one chunk
                     * @return number of elements per one chunk
                     */
                    inline size_t chunk_size() const { return 1 << nShift; }

                    /**
                     * Get number of allocated chunks
                     * @return number of allocated chunks
                     */
                    inline size_t chunks() const { return nChunks; }

                    /**
                     * Get chunk pointer
                     * @param id chunk identifier
                     * @return chunk pointer
                     */
                    inline T *chunk(size_t id) { return (id < nChunks) ? reinterpret_cast<T *>(vChunks[id]) : NULL; }

                    /**
                     * Get element at specified index
                     * @param idx element at specified index
                     * @return element at specified index or NULL if index is invalid
                     */
                    inline T *get(size_t idx) { return reinterpret_cast<T *>(do_get(idx)); }

                    /**
                     * Get element at specified index
                     * @param idx element at specified index
                     * @return element at specified index or NULL if index is invalid
                     */
                    inline T * operator[] (size_t idx) { return do_get(idx); }

                    /**
                     * Swap internal contents with another allocator
                     * @param src allocator to perform swapping
                     */
                    inline void swap(Allocator3D<T> *src) { do_swap(src); };

                    /** Drop all allocated data
                     *
                     */
                    inline void destroy() { do_destroy(); };

                    /** Drop all allocated data (similar to destroy)
                     *
                     */
                    inline void flush() { do_destroy(); };

                    /** Drop all allocated data (currently similar to destroy)
                     *
                     */
                    inline void clear() { do_clear(); };

                    /**
                     * Ensure that the specified pointer is right pointer, NULL pointers
                     * also return positive result
                     * @param ptr pointer
                     * @return true if pointer is right and belongs to this allocator
                     */
                    inline bool validate(const void *ptr) const { return do_validate(ptr); };

                    /**
                     * Get index of the item in allocator
                     * @param ptr pointer to the item
                     * @return index of the item or negative value on error
                     */
                    inline ssize_t index_of(const void *ptr) const { return calc_index_of(ptr); }
            };
    }
}



#endif /* LSP_PLUG_IN_DSP_UNITS_3D_ALLOCATOR3D_H_ */