]>
| Commit | Line | Data |
|---|---|---|
| 43d1bbe4 | 1 | /* |
| 1f7b830e | 2 | * Copyright (C) 1996-2025 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 | ||
| 7704fc9a | 60 | MemBlob::MemBlob(const size_type reserveSize) |
| 43d1bbe4 | 61 | { |
| bf95c10a | 62 | debugs(MEMBLOB_DEBUGSECTION,9, "constructed, this=" |
| 43d1bbe4 FC |
63 | << static_cast<void*>(this) << " id=" << id |
| 64 | << " reserveSize=" << reserveSize); | |
| 65 | memAlloc(reserveSize); | |
| 66 | } | |
| 67 | ||
| 7704fc9a | 68 | MemBlob::MemBlob(const_pointer buffer, const size_type bufSize) |
| 43d1bbe4 | 69 | { |
| bf95c10a | 70 | debugs(MEMBLOB_DEBUGSECTION,9, "constructed, this=" |
| 43d1bbe4 FC |
71 | << static_cast<void*>(this) << " id=" << id |
| 72 | << " buffer=" << static_cast<const void*>(buffer) | |
| 73 | << " bufSize=" << bufSize); | |
| 74 | memAlloc(bufSize); | |
| 75 | append(buffer, bufSize); | |
| 76 | } | |
| 77 | ||
| 78 | MemBlob::~MemBlob() | |
| 79 | { | |
| 835f22bb | 80 | if (mem || capacity) |
| 460f7f5e | 81 | memFreeBuf(capacity, mem); |
| 9e6c696c FC |
82 | auto &stats = WriteableStats(); |
| 83 | stats.liveBytes -= capacity; | |
| 84 | --stats.live; | |
| f079ed87 | 85 | SBufStats::RecordMemBlobSizeAtDestruct(capacity); |
| 43d1bbe4 | 86 | |
| bf95c10a | 87 | debugs(MEMBLOB_DEBUGSECTION,9, "destructed, this=" |
| 43d1bbe4 | 88 | << static_cast<void*>(this) << " id=" << id |
| b59e6847 A |
89 | << " capacity=" << capacity |
| 90 | << " size=" << size); | |
| 43d1bbe4 FC |
91 | } |
| 92 | ||
| 43d1bbe4 FC |
93 | /** Allocate an available space area of at least minSize bytes in size. |
| 94 | * Must be called by constructors and only by constructors. | |
| 95 | */ | |
| 96 | void | |
| 97 | MemBlob::memAlloc(const size_type minSize) | |
| 98 | { | |
| 835f22bb | 99 | size_t actualAlloc = minSize; |
| 43d1bbe4 FC |
100 | |
| 101 | Must(!mem); | |
| 7704fc9a | 102 | mem = static_cast<value_type *>(memAllocBuf(actualAlloc, &actualAlloc)); |
| 43d1bbe4 FC |
103 | Must(mem); |
| 104 | ||
| 105 | capacity = actualAlloc; | |
| 106 | size = 0; | |
| 107 | debugs(MEMBLOB_DEBUGSECTION, 8, | |
| 108 | id << " memAlloc: requested=" << minSize << | |
| 109 | ", received=" << capacity); | |
| 9e6c696c FC |
110 | auto &stats = WriteableStats(); |
| 111 | ++stats.live; | |
| 112 | ++stats.alloc; | |
| 113 | stats.liveBytes += capacity; | |
| 43d1bbe4 FC |
114 | } |
| 115 | ||
| 6bba9bf1 AR |
116 | void |
| 117 | MemBlob::appended(const size_type n) | |
| 118 | { | |
| 119 | Must(willFit(n)); | |
| 120 | size += n; | |
| 9e6c696c | 121 | ++WriteableStats().append; |
| 6bba9bf1 AR |
122 | } |
| 123 | ||
| 43d1bbe4 | 124 | void |
| 7704fc9a | 125 | MemBlob::append(const_pointer source, const size_type n) |
| b59e6847 | 126 | { |
| 43d1bbe4 FC |
127 | if (n > 0) { // appending zero bytes is allowed but only affects the stats |
| 128 | Must(willFit(n)); | |
| 129 | Must(source); | |
| 07bdd852 | 130 | memmove(mem + size, source, n); |
| 43d1bbe4 FC |
131 | size += n; |
| 132 | } | |
| 9e6c696c | 133 | ++WriteableStats().append; |
| 43d1bbe4 FC |
134 | } |
| 135 | ||
| 963caaa7 AR |
136 | void |
| 137 | MemBlob::syncSize(const size_type n) | |
| 138 | { | |
| 139 | debugs(MEMBLOB_DEBUGSECTION, 7, n << " was: " << size); | |
| 140 | Must(LockCount() <= 1); | |
| 141 | Must(n <= size); | |
| 142 | size = n; | |
| 143 | } | |
| 144 | ||
| 145 | void | |
| 146 | MemBlob::consume(const size_type rawN) | |
| 147 | { | |
| 148 | if (rawN && size) { | |
| 149 | Must(LockCount() <= 1); | |
| 150 | const auto n = std::min(rawN, size); | |
| 151 | size -= n; | |
| 152 | if (size) | |
| 153 | memmove(mem, mem + n, size); | |
| 154 | } | |
| 155 | } | |
| 156 | ||
| 43d1bbe4 FC |
157 | std::ostream& |
| 158 | MemBlob::dump(std::ostream &os) const | |
| 159 | { | |
| 160 | os << "id @" << (void *)this | |
| f53969cc SM |
161 | << "mem:" << static_cast<void*>(mem) |
| 162 | << ",capacity:" << capacity | |
| 163 | << ",size:" << size | |
| 164 | << ",refs:" << LockCount() << "; "; | |
| 43d1bbe4 FC |
165 | return os; |
| 166 | } | |
| f53969cc | 167 |