SwapMetaOut.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
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.
7  */
8 
9 #include "squid.h"
10 #include "md5.h"
11 #include "MemObject.h"
12 #include "sbuf/Stream.h"
13 #include "SquidMath.h"
14 #include "Store.h"
15 #include "store/SwapMeta.h"
16 #include "store/SwapMetaOut.h"
17 
18 namespace Store {
19 
21 static void
22 PackField(std::ostream &os, const SwapMetaType type, const size_t length, const void *value)
23 {
24  // Outside of packing/unpacking code, we correctly use SwapMetaType for
25  // valid swap meta types, but we store these values as RawSwapMetaType.
26  const auto rawType = NaturalCast<RawSwapMetaType>(type);
27 
28  if (length > SwapMetaFieldValueLengthMax)
29  throw TextException("swap meta field value too big to store", Here());
30 
31  // Outside of packing/unpacking code, we correctly use size_t for value
32  // sizes, we still store these values using RawSwapMetaLength.
33  const auto rawLength = NaturalCast<RawSwapMetaLength>(length);
34 
35  CheckSwapMetaSerialization(rawType, rawLength, value);
36 
37  if (!os.write(&rawType, sizeof(rawType)) ||
38  !os.write(reinterpret_cast<const char*>(&rawLength), sizeof(rawLength)) ||
39  (length && !os.write(static_cast<const char*>(value), length)))
40  throw TextException("cannot pack a swap meta field", Here());
41 }
42 
44 static void
45 PackFields(const StoreEntry &entry, std::ostream &os)
46 {
47  const auto &emem = entry.mem();
48  const auto objsize = emem.expectedReplySize();
49 
50  SBuf url;
51  if (emem.request)
52  url = emem.request->storeId();
53  else
54  url = entry.url();
55 
56  debugs(20, 3, entry << " URL: " << url);
57 
59 
61 
62  // XXX: Performance regression, c_str() may reallocate.
63  // XXX: do TLV without the c_str() termination. check readers first though
64  PackField(os, STORE_META_URL, url.length() + 1U, url.c_str());
65 
66  if (objsize >= 0)
67  PackField(os, STORE_META_OBJSIZE, sizeof(objsize), &objsize);
68 
69  const auto &vary = emem.vary_headers;
70  if (!vary.isEmpty())
71  PackField(os, STORE_META_VARY_HEADERS, vary.length(), vary.rawContent());
72 }
73 
74 } // namespace Store
75 
76 AllocedBuf
77 Store::PackSwapMeta(const StoreEntry &entry, size_t &totalLength)
78 {
79  SBufStream os;
80  PackFields(entry, os);
81  const auto metas = os.buf();
82 
83  // TODO: Optimize this allocation away by returning (and swapping out) SBuf.
84  const auto bufSize = NaturalSum<size_t>(sizeof(SwapMetaMagic), sizeof(RawSwapMetaPrefixLength), metas.length()).value();
85  AllocedBuf buf(xmalloc(bufSize));
86  const auto bufStart = static_cast<char*>(buf.get());
87 
88  auto pos = bufStart; // buf writing position
89 
90  *pos = SwapMetaMagic;
91  pos += sizeof(SwapMetaMagic);
92 
93  const auto metaSize = NaturalCast<RawSwapMetaLength>(bufSize);
94  memcpy(pos, &metaSize, sizeof(metaSize));
95  pos += sizeof(metaSize);
96 
97  Assure(pos + metas.length() == bufStart + bufSize); // paranoid
98  memcpy(pos, metas.rawContent(), metas.length());
99  pos += metas.length();
100 
101  totalLength = bufSize;
102  return buf;
103 }
104 
#define Here()
source code location of the caller
Definition: Here.h:15
AllocedBuf PackSwapMeta(const StoreEntry &, size_t &size)
Definition: SwapMetaOut.cc:77
time_t timestamp
Definition: Store.h:223
#define xmalloc
static void PackFields(const StoreEntry &entry, std::ostream &os)
writes all swap meta fields of the given Store entry to the given stream
Definition: SwapMetaOut.cc:45
const char * url() const
Definition: store.cc:1566
MemObject & mem()
Definition: Store.h:47
Definition: SBuf.h:93
int64_t expectedReplySize() const
Definition: MemObject.cc:238
@ STORE_META_URL
Definition: SwapMeta.h:65
static void PackField(std::ostream &os, const SwapMetaType type, const size_t length, const void *value)
writes a single swap meta field to the given stream
Definition: SwapMetaOut.cc:22
@ STORE_META_STD_LFS
Definition: SwapMeta.h:87
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
void CheckSwapMetaSerialization(RawSwapMetaType, RawSwapMetaLength, const void *)
Definition: SwapMeta.cc:13
@ STORE_META_OBJSIZE
Definition: SwapMeta.h:90
SBuf buf()
bytes written so far
Definition: Stream.h:41
#define Assure(condition)
Definition: Assure.h:35
const char * c_str()
Definition: SBuf.cc:516
@ STORE_META_KEY_MD5
Definition: SwapMeta.h:61
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
const char SwapMetaMagic
the start of the swap meta section
Definition: SwapMeta.h:113
int RawSwapMetaPrefixLength
Definition: SwapMeta.h:119
const size_t SwapMetaFieldValueLengthMax
Definition: SwapMeta.h:107
an std::runtime_error with thrower location info
Definition: TextException.h:20
SwapMetaType
Definition: SwapMeta.h:52
@ STORE_META_VARY_HEADERS
Stores Vary request headers.
Definition: SwapMeta.h:83
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const auto STORE_HDR_METASIZE
Definition: SwapMeta.h:226

 

Introduction

Documentation

Support

Miscellaneous