]> git.stg.codes - stg.git/blob - stglibs/dotconfpp.lib/mempool.cpp
У трафкаунтері виправлена втрата файлового дескриптора при обробці
[stg.git] / stglibs / dotconfpp.lib / mempool.cpp
1 /*  Copyright (C) 2003 Aleksey Krivoshey <voodoo@foss.kharkov.ua>
2 *
3 *   This program is free software; you can redistribute it and/or modify
4 *   it under the terms of the GNU General Public License as published by
5 *   the Free Software Foundation; either version 2 of the License, or
6 *   (at your option) any later version.
7 *
8 *   This program is distributed in the hope that it will be useful,
9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *   GNU General Public License for more details.
12 *
13 *   You should have received a copy of the GNU General Public License
14 *   along with this program; if not, write to the Free Software
15 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17
18
19 #include "mempool.h"
20
21 AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size):
22     pool(NULL), pos(0), size(_size)
23 {
24     pool = ::malloc(size);
25 }
26
27 AsyncDNSMemPool::PoolChunk::~PoolChunk()
28 {
29     ::free(pool);
30 }
31
32 AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize):
33     chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
34     poolUsage(0), poolUsageCounter(0)
35 {
36 }
37
38 AsyncDNSMemPool::~AsyncDNSMemPool()
39 {    
40     for(size_t i = 0; i<chunksCount; i++){
41         delete chunks[i];
42     }
43     ::free(chunks);
44 }
45
46 int AsyncDNSMemPool::initialize()
47 {
48     chunksCount = 1;
49     chunks = (PoolChunk**)::malloc(sizeof(PoolChunk*));
50     if(chunks == NULL)
51         return -1;
52
53     chunks[chunksCount-1] = new PoolChunk(defaultSize);
54
55     return 0;
56 }
57
58 void AsyncDNSMemPool::addNewChunk(size_t size)
59 {
60     chunksCount++;
61     chunks = (PoolChunk**)::realloc(chunks, chunksCount*sizeof(PoolChunk*));
62     if(size <= defaultSize)
63         chunks[chunksCount-1] = new PoolChunk(defaultSize);
64     else
65         chunks[chunksCount-1] = new PoolChunk(size);
66 }
67
68 void * AsyncDNSMemPool::alloc(size_t size)
69 {
70     PoolChunk * chunk = NULL;
71     for(size_t i = 0; i<chunksCount; i++){
72         chunk = chunks[i];
73         if((chunk->size - chunk->pos) >= size){
74             chunk->pos += size;
75             return ((u_int8_t*)chunk->pool) + chunk->pos - size;
76         }
77     }
78     addNewChunk(size);
79     chunks[chunksCount-1]->pos = size;
80     return chunks[chunksCount-1]->pool;
81 }
82
83 void AsyncDNSMemPool::free()
84 {    
85     size_t pu = 0;
86     size_t psz = 0;
87     poolUsageCounter++;
88
89     for(size_t i = 0; i<chunksCount; i++){
90         pu += chunks[i]->pos;
91         psz += chunks[i]->size;
92         chunks[i]->pos = 0;
93     }
94     poolUsage=(poolUsage>pu)?poolUsage:pu;
95
96     if(poolUsageCounter >= 10 && chunksCount > 1){
97         psz -= chunks[chunksCount-1]->size;
98         if(poolUsage < psz){
99             chunksCount--;
100             delete chunks[chunksCount];
101         }
102         poolUsage = 0;
103         poolUsageCounter = 0;
104     }
105 }
106
107 void * AsyncDNSMemPool::calloc(size_t size)
108 {
109     return ::memset(this->alloc(size), 0, size);
110 }
111
112 char * AsyncDNSMemPool::strdup(const char *str)
113 {
114     return ::strcpy((char*)this->alloc(strlen(str)+1), str);
115 }
116