]>
Commit | Line | Data |
---|---|---|
43d1bbe4 FC |
1 | /* |
2 | * MemBlob.cc (C) 2009 Francesco Chemolli <kinkie@squid-cache.org> | |
3 | * | |
4 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
5 | * ---------------------------------------------------------- | |
6 | * | |
7 | * Squid is the result of efforts by numerous individuals from | |
8 | * the Internet community; see the CONTRIBUTORS file for full | |
9 | * details. Many organizations have provided support for Squid's | |
10 | * development; see the SPONSORS file for full details. Squid is | |
11 | * Copyrighted (C) 2001 by the Regents of the University of | |
12 | * California; see the COPYRIGHT file for full details. Squid | |
13 | * incorporates software developed and/or copyrighted by other | |
14 | * sources; see the CREDITS file for full details. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
29 | */ | |
30 | ||
31 | ||
32 | #include "config.h" | |
33 | #include "base/TextException.h" | |
34 | #include "Debug.h" | |
35 | #include "MemBlob.h" | |
36 | #if HAVE_IOSTREAM | |
37 | #include <iostream> | |
38 | #endif | |
39 | ||
40 | #define MEMBLOB_USES_MEM_POOLS 0 | |
41 | ||
42 | #if MEMBLOB_USES_MEM_POOLS | |
43 | #include "protos.h" | |
44 | #endif | |
45 | ||
46 | MemBlobStats MemBlob::Stats; | |
47 | InstanceIdDefinitions(MemBlob, "blob"); | |
48 | ||
49 | ||
50 | /* MemBlobStats */ | |
51 | ||
52 | MemBlobStats::MemBlobStats(): alloc(0), live(0), append(0) | |
53 | {} | |
54 | ||
55 | std::ostream& | |
56 | MemBlobStats::dump(std::ostream &os) const | |
57 | { | |
58 | os << | |
59 | "MemBlob created: " << alloc << | |
60 | "\nMemBlob alive: " << live << | |
61 | "\nMemBlob append calls: " << append << | |
62 | "\nMemBlob currently allocated size: " << liveBytes << | |
63 | "\nlive MemBlob mean current allocation size: " << | |
64 | (static_cast<double>(liveBytes)/(live?live:1)) << std::endl; | |
65 | return os; | |
66 | } | |
67 | ||
68 | ||
69 | /* MemBlob */ | |
70 | ||
71 | MemBlob::MemBlob(const MemBlob::size_type reserveSize) : | |
72 | mem(NULL), capacity(0), size(0) // will be set by memAlloc | |
73 | { | |
74 | debugs(MEMBLOB_DEBUGSECTION,9, HERE << "constructed, this=" | |
75 | << static_cast<void*>(this) << " id=" << id | |
76 | << " reserveSize=" << reserveSize); | |
77 | memAlloc(reserveSize); | |
78 | } | |
79 | ||
80 | MemBlob::MemBlob(const char *buffer, const MemBlob::size_type bufSize) : | |
81 | mem(NULL), capacity(0), size(0) // will be set by memAlloc | |
82 | { | |
83 | debugs(MEMBLOB_DEBUGSECTION,9, HERE << "constructed, this=" | |
84 | << static_cast<void*>(this) << " id=" << id | |
85 | << " buffer=" << static_cast<const void*>(buffer) | |
86 | << " bufSize=" << bufSize); | |
87 | memAlloc(bufSize); | |
88 | append(buffer, bufSize); | |
89 | } | |
90 | ||
91 | MemBlob::~MemBlob() | |
92 | { | |
93 | #if MEMBLOB_USES_MEM_POOLS | |
94 | //no mempools for now | |
95 | // \todo reinstate mempools use | |
96 | memFreeString(capacity,mem); | |
97 | #else | |
98 | xfree(mem); | |
99 | #endif | |
100 | Stats.liveBytes -= capacity; | |
101 | --Stats.live; | |
102 | ||
103 | debugs(MEMBLOB_DEBUGSECTION,9, HERE << "destructed, this=" | |
104 | << static_cast<void*>(this) << " id=" << id | |
b59e6847 A |
105 | << " capacity=" << capacity |
106 | << " size=" << size); | |
43d1bbe4 FC |
107 | } |
108 | ||
109 | /** | |
110 | * Given the requested minimum size, return a rounded allocation size | |
111 | * for the backing store. | |
112 | * This is a stopgap call, this job is eventually expected to be handled | |
113 | * by MemPools via memAllocString. | |
114 | */ | |
115 | MemBlob::size_type | |
abbb7c72 | 116 | MemBlob::calcAllocSize(const size_type sz) const |
43d1bbe4 | 117 | { |
abbb7c72 AJ |
118 | if (sz <= 36) return 36; |
119 | if (sz <= 128) return 128; | |
120 | if (sz <= 512) return 512; | |
121 | if (sz <= 4096) return RoundTo(sz, 512); | |
43d1bbe4 FC |
122 | // XXX: recover squidSystemPageSize functionality. It's easy for |
123 | // the main squid, harder for tests | |
124 | #if 0 | |
abbb7c72 | 125 | return RoundTo(sz, squidSystemPageSize); |
43d1bbe4 | 126 | #else |
abbb7c72 | 127 | return RoundTo(sz, 4096); |
43d1bbe4 FC |
128 | #endif |
129 | } | |
130 | ||
131 | /** Allocate an available space area of at least minSize bytes in size. | |
132 | * Must be called by constructors and only by constructors. | |
133 | */ | |
134 | void | |
135 | MemBlob::memAlloc(const size_type minSize) | |
136 | { | |
137 | size_t actualAlloc = calcAllocSize(minSize); | |
138 | ||
139 | Must(!mem); | |
140 | #if MEMBLOB_USES_MEM_POOLS | |
141 | // XXX: for now, do without mempools. In order to do it, MemPools | |
142 | // need to be singletons so that initialization order can be enforced | |
143 | mem = static_cast<char*>(memAllocString(minSize, &actualAlloc)); | |
144 | #else | |
145 | // \todo reinstate mempools use | |
146 | mem = static_cast<char*>(xmalloc(actualAlloc)); | |
147 | #endif | |
148 | Must(mem); | |
149 | ||
150 | capacity = actualAlloc; | |
151 | size = 0; | |
152 | debugs(MEMBLOB_DEBUGSECTION, 8, | |
153 | id << " memAlloc: requested=" << minSize << | |
154 | ", received=" << capacity); | |
155 | ++Stats.live; | |
156 | ++Stats.alloc; | |
157 | Stats.liveBytes += capacity; | |
158 | } | |
159 | ||
160 | void | |
161 | MemBlob::append(const char *source, const size_type n) | |
b59e6847 | 162 | { |
43d1bbe4 FC |
163 | if (n > 0) { // appending zero bytes is allowed but only affects the stats |
164 | Must(willFit(n)); | |
165 | Must(source); | |
166 | /// \note memcpy() is safe because we copy to an unused area | |
167 | memcpy(mem + size, source, n); | |
168 | size += n; | |
169 | } | |
170 | ++Stats.append; | |
171 | } | |
172 | ||
173 | ||
174 | const MemBlobStats& | |
175 | MemBlob::GetStats() | |
176 | { | |
177 | return Stats; | |
178 | } | |
179 | ||
180 | std::ostream& | |
181 | MemBlob::dump(std::ostream &os) const | |
182 | { | |
183 | os << "id @" << (void *)this | |
184 | << "mem:" << static_cast<void*>(mem) | |
185 | << ",capacity:" << capacity | |
186 | << ",size:" << size | |
187 | << ",refs:" << RefCountCount() << "; "; | |
188 | return os; | |
189 | } |