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-2020, 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 
49 namespace psync {
50 namespace detail {
51 
52 namespace bio = boost::iostreams;
53 
54 static inline uint32_t
55 ROTL32(uint32_t x, int8_t r)
56 {
57  return (x << r) | (x >> (32 - r));
58 }
59 
60 uint32_t
61 murmurHash3(const void* key, size_t len, uint32_t seed)
62 {
63  const uint8_t * data = (const uint8_t*)key;
64  const int nblocks = len / 4;
65 
66  uint32_t h1 = seed;
67 
68  const uint32_t c1 = 0xcc9e2d51;
69  const uint32_t c2 = 0x1b873593;
70 
71  //----------
72  // body
73 
74  const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
75 
76  for (int i = -nblocks; i; i++)
77  {
78  uint32_t k1 = blocks[i];
79 
80  k1 *= c1;
81  k1 = ROTL32(k1,15);
82  k1 *= c2;
83 
84  h1 ^= k1;
85  h1 = ROTL32(h1,13);
86  h1 = h1*5+0xe6546b64;
87  }
88 
89  //----------
90  // tail
91 
92  const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
93 
94  uint32_t k1 = 0;
95 
96  switch (len & 3)
97  {
98  case 3: k1 ^= tail[2] << 16;
99  NDN_CXX_FALLTHROUGH;
100  case 2: k1 ^= tail[1] << 8;
101  NDN_CXX_FALLTHROUGH;
102  case 1: k1 ^= tail[0];
103  k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
104  }
105 
106  //----------
107  // finalization
108 
109  h1 ^= len;
110  h1 ^= h1 >> 16;
111  h1 *= 0x85ebca6b;
112  h1 ^= h1 >> 13;
113  h1 *= 0xc2b2ae35;
114  h1 ^= h1 >> 16;
115 
116  return h1;
117 }
118 
119 std::shared_ptr<ndn::Buffer>
120 compress(CompressionScheme scheme, const uint8_t* buffer, size_t bufferSize)
121 {
122  ndn::OBufferStream out;
123  bio::filtering_streambuf<bio::input> in;
124 
125  switch (scheme) {
127 #ifdef PSYNC_HAVE_ZLIB
128  in.push(bio::zlib_compressor(bio::zlib::best_compression));
129  break;
130 #else
131  NDN_THROW(CompressionError("ZLIB compression not supported!"));
132 #endif
133 
135 #ifdef PSYNC_HAVE_GZIP
136  in.push(bio::gzip_compressor(bio::gzip::best_compression));
137  break;
138 #else
139  NDN_THROW(CompressionError("GZIP compression not supported!"));
140 #endif
141 
143 #ifdef PSYNC_HAVE_BZIP2
144  in.push(bio::bzip2_compressor());
145  break;
146 #else
147  NDN_THROW(CompressionError("BZIP2 compression not supported!"));
148 #endif
149 
151 #ifdef PSYNC_HAVE_LZMA
152  in.push(bio::lzma_compressor(bio::lzma::best_compression));
153  break;
154 #else
155  NDN_THROW(CompressionError("LZMA compression not supported!"));
156 #endif
157 
159 #ifdef PSYNC_HAVE_ZSTD
160  in.push(bio::zstd_compressor(bio::zstd::best_compression));
161  break;
162 #else
163  NDN_THROW(CompressionError("ZSTD compression not supported!"));
164 #endif
165 
167  break;
168  }
169  in.push(bio::array_source(reinterpret_cast<const char*>(buffer), bufferSize));
170  bio::copy(in, out);
171 
172  return out.buf();
173 }
174 
175 std::shared_ptr<ndn::Buffer>
176 decompress(CompressionScheme scheme, const uint8_t* buffer, size_t bufferSize)
177 {
178  ndn::OBufferStream out;
179  bio::filtering_streambuf<bio::input> in;
180 
181  switch (scheme) {
183 #ifdef PSYNC_HAVE_ZLIB
184  in.push(bio::zlib_decompressor());
185  break;
186 #else
187  NDN_THROW(CompressionError("ZLIB decompression not supported!"));
188 #endif
189 
191 #ifdef PSYNC_HAVE_GZIP
192  in.push(bio::gzip_decompressor());
193  break;
194 #else
195  NDN_THROW(CompressionError("GZIP compression not supported!"));
196 #endif
197 
199 #ifdef PSYNC_HAVE_BZIP2
200  in.push(bio::bzip2_decompressor());
201  break;
202 #else
203  NDN_THROW(CompressionError("BZIP2 compression not supported!"));
204 #endif
205 
207 #ifdef PSYNC_HAVE_LZMA
208  in.push(bio::lzma_decompressor());
209  break;
210 #else
211  NDN_THROW(CompressionError("LZMA compression not supported!"));
212 #endif
213 
215 #ifdef PSYNC_HAVE_ZSTD
216  in.push(bio::zstd_decompressor());
217  break;
218 #else
219  NDN_THROW(CompressionError("ZSTD compression not supported!"));
220 #endif
221 
223  break;
224  }
225  in.push(bio::array_source(reinterpret_cast<const char*>(buffer), bufferSize));
226  bio::copy(in, out);
227 
228  return out.buf();
229 }
230 
231 } // namespace detail
232 } // namespace psync
Definition: common.hpp:33
std::shared_ptr< ndn::Buffer > decompress(CompressionScheme scheme, const uint8_t *buffer, size_t bufferSize)
Definition: util.cpp:176
static uint32_t ROTL32(uint32_t x, int8_t r)
Definition: util.cpp:55
CompressionScheme
Definition: common.hpp:35
std::shared_ptr< ndn::Buffer > compress(CompressionScheme scheme, const uint8_t *buffer, size_t bufferSize)
Definition: util.cpp:120
uint32_t murmurHash3(const void *key, size_t len, uint32_t seed)
Definition: util.cpp:61