]>
Commit | Line | Data |
---|---|---|
43d1bbe4 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
43d1bbe4 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
43d1bbe4 FC |
7 | */ |
8 | ||
f7f3304a | 9 | #include "squid.h" |
43d1bbe4 | 10 | #include "base/TextException.h" |
675b8408 | 11 | #include "debug/Stream.h" |
a471b119 | 12 | #include "sbuf/MemBlob.h" |
f079ed87 | 13 | #include "sbuf/Stats.h" |
835f22bb | 14 | |
43d1bbe4 | 15 | #include <iostream> |
43d1bbe4 | 16 | |
43d1bbe4 FC |
17 | InstanceIdDefinitions(MemBlob, "blob"); |
18 | ||
43d1bbe4 FC |
19 | /* MemBlobStats */ |
20 | ||
412da427 FC |
21 | MemBlobStats& |
22 | MemBlobStats::operator += (const MemBlobStats& s) | |
23 | { | |
24 | alloc+=s.alloc; | |
25 | live+=s.live; | |
26 | append+=s.append; | |
27 | liveBytes+=s.liveBytes; | |
28 | ||
29 | return *this; | |
30 | } | |
31 | ||
43d1bbe4 FC |
32 | std::ostream& |
33 | MemBlobStats::dump(std::ostream &os) const | |
34 | { | |
35 | os << | |
f53969cc SM |
36 | "MemBlob created: " << alloc << |
37 | "\nMemBlob alive: " << live << | |
38 | "\nMemBlob append calls: " << append << | |
39 | "\nMemBlob currently allocated size: " << liveBytes << | |
40 | "\nlive MemBlob mean current allocation size: " << | |
41 | (static_cast<double>(liveBytes)/(live?live:1)) << std::endl; | |
43d1bbe4 FC |
42 | return os; |
43 | } | |
44 | ||
9e6c696c FC |
45 | static auto & |
46 | WriteableStats() | |
47 | { | |
48 | static const auto stats = new MemBlobStats(); | |
49 | return *stats; | |
50 | } | |
51 | ||
52 | const MemBlobStats & | |
53 | MemBlob::GetStats() | |
54 | { | |
55 | return WriteableStats(); | |
56 | } | |
57 | ||
43d1bbe4 FC |
58 | /* MemBlob */ |
59 | ||
60 | MemBlob::MemBlob(const MemBlob::size_type reserveSize) : | |
aee3523a | 61 | mem(nullptr), capacity(0), size(0) // will be set by memAlloc |
43d1bbe4 | 62 | { |
bf95c10a | 63 | debugs(MEMBLOB_DEBUGSECTION,9, "constructed, this=" |
43d1bbe4 FC |
64 | << static_cast<void*>(this) << " id=" << id |
65 | << " reserveSize=" << reserveSize); | |
66 | memAlloc(reserveSize); | |
67 | } | |
68 | ||
69 | MemBlob::MemBlob(const char *buffer, const MemBlob::size_type bufSize) : | |
aee3523a | 70 | mem(nullptr), capacity(0), size(0) // will be set by memAlloc |
43d1bbe4 | 71 | { |
bf95c10a | 72 | debugs(MEMBLOB_DEBUGSECTION,9, "constructed, this=" |
43d1bbe4 FC |
73 | << static_cast<void*>(this) << " id=" << id |
74 | << " buffer=" << static_cast<const void*>(buffer) | |
75 | << " bufSize=" << bufSize); | |
76 | memAlloc(bufSize); | |
77 | append(buffer, bufSize); | |
78 | } | |
79 | ||
80 | MemBlob::~MemBlob() | |
81 | { | |
835f22bb | 82 | if (mem || capacity) |
460f7f5e | 83 | memFreeBuf(capacity, mem); |
9e6c696c FC |
84 | auto &stats = WriteableStats(); |
85 | stats.liveBytes -= capacity; | |
86 | --stats.live; | |
f079ed87 | 87 | SBufStats::RecordMemBlobSizeAtDestruct(capacity); |
43d1bbe4 | 88 | |
bf95c10a | 89 | debugs(MEMBLOB_DEBUGSECTION,9, "destructed, this=" |
43d1bbe4 | 90 | << static_cast<void*>(this) << " id=" << id |
b59e6847 A |
91 | << " capacity=" << capacity |
92 | << " size=" << size); | |
43d1bbe4 FC |
93 | } |
94 | ||
43d1bbe4 FC |
95 | /** Allocate an available space area of at least minSize bytes in size. |
96 | * Must be called by constructors and only by constructors. | |
97 | */ | |
98 | void | |
99 | MemBlob::memAlloc(const size_type minSize) | |
100 | { | |
835f22bb | 101 | size_t actualAlloc = minSize; |
43d1bbe4 FC |
102 | |
103 | Must(!mem); | |
460f7f5e | 104 | mem = static_cast<char*>(memAllocBuf(actualAlloc, &actualAlloc)); |
43d1bbe4 FC |
105 | Must(mem); |
106 | ||
107 | capacity = actualAlloc; | |
108 | size = 0; | |
109 | debugs(MEMBLOB_DEBUGSECTION, 8, | |
110 | id << " memAlloc: requested=" << minSize << | |
111 | ", received=" << capacity); | |
9e6c696c FC |
112 | auto &stats = WriteableStats(); |
113 | ++stats.live; | |
114 | ++stats.alloc; | |
115 | stats.liveBytes += capacity; | |
43d1bbe4 FC |
116 | } |
117 | ||
6bba9bf1 AR |
118 | void |
119 | MemBlob::appended(const size_type n) | |
120 | { | |
121 | Must(willFit(n)); | |
122 | size += n; | |
9e6c696c | 123 | ++WriteableStats().append; |
6bba9bf1 AR |
124 | } |
125 | ||
43d1bbe4 FC |
126 | void |
127 | MemBlob::append(const char *source, const size_type n) | |
b59e6847 | 128 | { |
43d1bbe4 FC |
129 | if (n > 0) { // appending zero bytes is allowed but only affects the stats |
130 | Must(willFit(n)); | |
131 | Must(source); | |
07bdd852 | 132 | memmove(mem + size, source, n); |
43d1bbe4 FC |
133 | size += n; |
134 | } | |
9e6c696c | 135 | ++WriteableStats().append; |
43d1bbe4 FC |
136 | } |
137 | ||
963caaa7 AR |
138 | void |
139 | MemBlob::syncSize(const size_type n) | |
140 | { | |
141 | debugs(MEMBLOB_DEBUGSECTION, 7, n << " was: " << size); | |
142 | Must(LockCount() <= 1); | |
143 | Must(n <= size); | |
144 | size = n; | |
145 | } | |
146 | ||
147 | void | |
148 | MemBlob::consume(const size_type rawN) | |
149 | { | |
150 | if (rawN && size) { | |
151 | Must(LockCount() <= 1); | |
152 | const auto n = std::min(rawN, size); | |
153 | size -= n; | |
154 | if (size) | |
155 | memmove(mem, mem + n, size); | |
156 | } | |
157 | } | |
158 | ||
43d1bbe4 FC |
159 | std::ostream& |
160 | MemBlob::dump(std::ostream &os) const | |
161 | { | |
162 | os << "id @" << (void *)this | |
f53969cc SM |
163 | << "mem:" << static_cast<void*>(mem) |
164 | << ",capacity:" << capacity | |
165 | << ",size:" << size | |
166 | << ",refs:" << LockCount() << "; "; | |
43d1bbe4 FC |
167 | return os; |
168 | } | |
f53969cc | 169 |