Loading...
Searching...
No Matches
util.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2022, The University of Memphis
4 *
5 * This file is part of PSync.
6 * See AUTHORS.md for complete list of PSync authors and contributors.
7 *
8 * PSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU Lesser General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * PSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License along with
17 * PSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * murmurHash3 was written by Austin Appleby, and is placed in the public
20 * domain. The author hereby disclaims copyright to this source code.
21 * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
22 */
23
24#include "PSync/detail/util.hpp"
25
26#include <ndn-cxx/encoding/buffer-stream.hpp>
27#include <ndn-cxx/util/backports.hpp>
28#include <ndn-cxx/util/exception.hpp>
29
30#include <boost/iostreams/copy.hpp>
31#include <boost/iostreams/device/array.hpp>
32#include <boost/iostreams/filtering_stream.hpp>
33#ifdef PSYNC_HAVE_ZLIB
34 #include <boost/iostreams/filter/zlib.hpp>
35#endif
36#ifdef PSYNC_HAVE_GZIP
37 #include <boost/iostreams/filter/gzip.hpp>
38#endif
39#ifdef PSYNC_HAVE_BZIP2
40 #include <boost/iostreams/filter/bzip2.hpp>
41#endif
42#ifdef PSYNC_HAVE_LZMA
43 #include <boost/iostreams/filter/lzma.hpp>
44#endif
45#ifdef PSYNC_HAVE_ZSTD
46 #include <boost/iostreams/filter/zstd.hpp>
47#endif
48
49namespace psync::detail {
50
51static inline uint32_t
52ROTL32(uint32_t x, int8_t r)
53{
54 return (x << r) | (x >> (32 - r));
55}
56
57uint32_t
58murmurHash3(const void* key, size_t len, uint32_t seed)
59{
60 const uint8_t * data = (const uint8_t*)key;
61 const int nblocks = len / 4;
62
63 uint32_t h1 = seed;
64
65 const uint32_t c1 = 0xcc9e2d51;
66 const uint32_t c2 = 0x1b873593;
67
68 //----------
69 // body
70
71 const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
72
73 for (int i = -nblocks; i; i++)
74 {
75 uint32_t k1 = blocks[i];
76
77 k1 *= c1;
78 k1 = ROTL32(k1,15);
79 k1 *= c2;
80
81 h1 ^= k1;
82 h1 = ROTL32(h1,13);
83 h1 = h1*5+0xe6546b64;
84 }
85
86 //----------
87 // tail
88
89 const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
90
91 uint32_t k1 = 0;
92
93 switch (len & 3)
94 {
95 case 3: k1 ^= tail[2] << 16;
96 [[fallthrough]];
97 case 2: k1 ^= tail[1] << 8;
98 [[fallthrough]];
99 case 1: k1 ^= tail[0];
100 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
101 }
102
103 //----------
104 // finalization
105
106 h1 ^= len;
107 h1 ^= h1 >> 16;
108 h1 *= 0x85ebca6b;
109 h1 ^= h1 >> 13;
110 h1 *= 0xc2b2ae35;
111 h1 ^= h1 >> 16;
112
113 return h1;
114}
115
116uint32_t
117murmurHash3(uint32_t seed, const ndn::Name& name)
118{
119 const auto& wire = name.wireEncode();
120 return murmurHash3(wire.value(), wire.value_size(), seed);
121}
122
123std::shared_ptr<ndn::Buffer>
124compress(CompressionScheme scheme, ndn::span<const uint8_t> buffer)
125{
126 namespace bio = boost::iostreams;
127
128 bio::filtering_istreambuf in;
129
130 switch (scheme) {
132 break;
133
135#ifdef PSYNC_HAVE_ZLIB
136 in.push(bio::zlib_compressor(bio::zlib::best_compression));
137 break;
138#else
139 NDN_THROW(CompressionError("ZLIB compression not supported!"));
140#endif
141
143#ifdef PSYNC_HAVE_GZIP
144 in.push(bio::gzip_compressor(bio::gzip::best_compression));
145 break;
146#else
147 NDN_THROW(CompressionError("GZIP compression not supported!"));
148#endif
149
151#ifdef PSYNC_HAVE_BZIP2
152 in.push(bio::bzip2_compressor());
153 break;
154#else
155 NDN_THROW(CompressionError("BZIP2 compression not supported!"));
156#endif
157
159#ifdef PSYNC_HAVE_LZMA
160 in.push(bio::lzma_compressor(bio::lzma::best_compression));
161 break;
162#else
163 NDN_THROW(CompressionError("LZMA compression not supported!"));
164#endif
165
167#ifdef PSYNC_HAVE_ZSTD
168 in.push(bio::zstd_compressor(bio::zstd::best_compression));
169 break;
170#else
171 NDN_THROW(CompressionError("ZSTD compression not supported!"));
172#endif
173 }
174
175 in.push(bio::array_source(reinterpret_cast<const char*>(buffer.data()), buffer.size()));
176 ndn::OBufferStream out;
177 bio::copy(in, out);
178
179 return out.buf();
180}
181
182std::shared_ptr<ndn::Buffer>
183decompress(CompressionScheme scheme, ndn::span<const uint8_t> buffer)
184{
185 namespace bio = boost::iostreams;
186
187 bio::filtering_istreambuf in;
188
189 switch (scheme) {
191 break;
192
194#ifdef PSYNC_HAVE_ZLIB
195 in.push(bio::zlib_decompressor());
196 break;
197#else
198 NDN_THROW(CompressionError("ZLIB decompression not supported!"));
199#endif
200
202#ifdef PSYNC_HAVE_GZIP
203 in.push(bio::gzip_decompressor());
204 break;
205#else
206 NDN_THROW(CompressionError("GZIP compression not supported!"));
207#endif
208
210#ifdef PSYNC_HAVE_BZIP2
211 in.push(bio::bzip2_decompressor());
212 break;
213#else
214 NDN_THROW(CompressionError("BZIP2 compression not supported!"));
215#endif
216
218#ifdef PSYNC_HAVE_LZMA
219 in.push(bio::lzma_decompressor());
220 break;
221#else
222 NDN_THROW(CompressionError("LZMA compression not supported!"));
223#endif
224
226#ifdef PSYNC_HAVE_ZSTD
227 in.push(bio::zstd_decompressor());
228 break;
229#else
230 NDN_THROW(CompressionError("ZSTD compression not supported!"));
231#endif
232 }
233
234 in.push(bio::array_source(reinterpret_cast<const char*>(buffer.data()), buffer.size()));
235 ndn::OBufferStream out;
236 bio::copy(in, out);
237
238 return out.buf();
239}
240
241} // namespace psync::detail
uint32_t murmurHash3(const void *key, size_t len, uint32_t seed)
Definition util.cpp:58
std::shared_ptr< ndn::Buffer > compress(CompressionScheme scheme, ndn::span< const uint8_t > buffer)
Definition util.cpp:124
std::shared_ptr< ndn::Buffer > decompress(CompressionScheme scheme, ndn::span< const uint8_t > buffer)
Definition util.cpp:183
CompressionScheme
Definition common.hpp:43