GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/unittest/TestStreamCompression.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 189 190 99.5%
Functions: 5 5 100.0%
Branches: 231 1148 20.1%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include <openvdb/points/StreamCompression.h>
5 #include <openvdb/io/Compression.h> // io::COMPRESS_BLOSC
6
7 #include <gtest/gtest.h>
8
9 #ifdef __clang__
10 #pragma GCC diagnostic push
11 #pragma GCC diagnostic ignored "-Wunused-macros"
12 #endif
13 // Boost.Interprocess uses a header-only portion of Boost.DateTime
14 #define BOOST_DATE_TIME_NO_LIB
15 #ifdef __clang__
16 #pragma GCC diagnostic pop
17 #endif
18 #include <boost/interprocess/file_mapping.hpp>
19 #include <boost/interprocess/mapped_region.hpp>
20 #include <boost/iostreams/device/array.hpp>
21 #include <boost/iostreams/stream.hpp>
22 #include <boost/uuid/uuid_generators.hpp>
23 #include <boost/uuid/uuid_io.hpp>
24 #include <boost/version.hpp> // for BOOST_VERSION
25
26 #ifdef _WIN32
27 #include <boost/interprocess/detail/os_file_functions.hpp> // open_existing_file(), close_file()
28 // boost::interprocess::detail was renamed to boost::interprocess::ipcdetail in Boost 1.48.
29 // Ensure that both namespaces exist.
30 namespace boost { namespace interprocess { namespace detail {} namespace ipcdetail {} } }
31 #include <windows.h>
32 #else
33 #include <sys/types.h> // for struct stat
34 #include <sys/stat.h> // for stat()
35 #include <unistd.h> // for unlink()
36 #endif
37
38 #include <atomic>
39 #include <fstream>
40 #include <numeric> // for std::iota()
41
42 #ifdef OPENVDB_USE_BLOSC
43 #include <blosc.h>
44 // A Blosc optimization introduced in 1.11.0 uses a slightly smaller block size for
45 // HCR codecs (LZ4, ZLIB, ZSTD), which otherwise fails a few regression test cases
46 #if BLOSC_VERSION_MAJOR > 1 || (BLOSC_VERSION_MAJOR == 1 && BLOSC_VERSION_MINOR > 10)
47 #define BLOSC_HCR_BLOCKSIZE_OPTIMIZATION
48 #endif
49 // Blosc 1.14+ writes backwards-compatible data by default.
50 // http://blosc.org/posts/new-forward-compat-policy/
51 #if BLOSC_VERSION_MAJOR > 1 || (BLOSC_VERSION_MAJOR == 1 && BLOSC_VERSION_MINOR >= 14)
52 #define BLOSC_BACKWARDS_COMPATIBLE
53 #endif
54 #endif
55
56 /// @brief io::MappedFile has a private constructor, so this unit tests uses a matching proxy
57 class ProxyMappedFile
58 {
59 public:
60 1 explicit ProxyMappedFile(const std::string& filename)
61
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 : mImpl(new Impl(filename)) { }
62
63 private:
64 class Impl
65 {
66 public:
67 1 Impl(const std::string& filename)
68 1 : mMap(filename.c_str(), boost::interprocess::read_only)
69
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 , mRegion(mMap, boost::interprocess::read_only)
70 {
71 mLastWriteTime = 0;
72 const char* regionFilename = mMap.get_name();
73 #ifdef _WIN32
74 using namespace boost::interprocess::detail;
75 using namespace boost::interprocess::ipcdetail;
76 using openvdb::Index64;
77
78 if (void* fh = open_existing_file(regionFilename, boost::interprocess::read_only)) {
79 FILETIME mtime;
80 if (GetFileTime(fh, nullptr, nullptr, &mtime)) {
81 mLastWriteTime = (Index64(mtime.dwHighDateTime) << 32) | mtime.dwLowDateTime;
82 }
83 close_file(fh);
84 }
85 #else
86 struct stat info;
87
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (0 == ::stat(regionFilename, &info)) {
88 1 mLastWriteTime = openvdb::Index64(info.st_mtime);
89 }
90 #endif
91 1 }
92
93 using Notifier = std::function<void(std::string /*filename*/)>;
94 boost::interprocess::file_mapping mMap;
95 boost::interprocess::mapped_region mRegion;
96 bool mAutoDelete = false;
97 Notifier mNotifier;
98 mutable std::atomic<openvdb::Index64> mLastWriteTime;
99 }; // class Impl
100 std::unique_ptr<Impl> mImpl;
101 }; // class ProxyMappedFile
102
103 using namespace openvdb;
104 using namespace openvdb::compression;
105
106 2 class TestStreamCompression: public ::testing::Test
107 {
108 public:
109 void testPagedStreams();
110 }; // class TestStreamCompression
111
112
113 ////////////////////////////////////////
114
115
116
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 TEST_F(TestStreamCompression, testBlosc)
117 {
118 // ensure that the library and unit tests are both built with or without Blosc enabled
119 #ifdef OPENVDB_USE_BLOSC
120
1/16
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1 EXPECT_TRUE(bloscCanCompress());
121 #else
122 EXPECT_TRUE(!bloscCanCompress());
123 #endif
124
125 const int count = 256;
126
127 { // valid buffer
128 // compress
129 1 std::unique_ptr<int[]> uncompressedBuffer(new int[count]);
130
131
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 1 times.
257 for (int i = 0; i < count; i++) {
132 256 uncompressedBuffer.get()[i] = i / 2;
133 }
134
135 1 size_t uncompressedBytes = count * sizeof(int);
136 size_t compressedBytes;
137
138
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 size_t testCompressedBytes = bloscCompressedSize(
139 1 reinterpret_cast<char*>(uncompressedBuffer.get()), uncompressedBytes);
140
141 std::unique_ptr<char[]> compressedBuffer = bloscCompress(
142
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<char*>(uncompressedBuffer.get()), uncompressedBytes, compressedBytes);
143
144 #ifdef OPENVDB_USE_BLOSC
145
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(compressedBytes < uncompressedBytes);
146
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(compressedBuffer);
147
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
1 EXPECT_EQ(testCompressedBytes, compressedBytes);
148
149 // uncompressedSize
150
151
3/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_EQ(uncompressedBytes, bloscUncompressedSize(compressedBuffer.get()));
152
153 // decompress
154
155 std::unique_ptr<char[]> newUncompressedBuffer =
156
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bloscDecompress(compressedBuffer.get(), uncompressedBytes);
157
158 // incorrect number of expected bytes
159
4/22
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
2 EXPECT_THROW(newUncompressedBuffer =
160 bloscDecompress(compressedBuffer.get(), 1), openvdb::RuntimeError);
161
162
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(newUncompressedBuffer);
163 #else
164 EXPECT_TRUE(!compressedBuffer);
165 EXPECT_EQ(testCompressedBytes, size_t(0));
166
167 // uncompressedSize
168
169 EXPECT_THROW(bloscUncompressedSize(compressedBuffer.get()), openvdb::RuntimeError);
170
171 // decompress
172
173 std::unique_ptr<char[]> newUncompressedBuffer;
174 EXPECT_THROW(
175 newUncompressedBuffer = bloscDecompress(compressedBuffer.get(), uncompressedBytes),
176 openvdb::RuntimeError);
177
178 EXPECT_TRUE(!newUncompressedBuffer);
179 #endif
180 }
181
182 { // one value (below minimum bytes)
183 1 std::unique_ptr<int[]> uncompressedBuffer(new int[1]);
184 1 uncompressedBuffer.get()[0] = 10;
185
186 size_t compressedBytes;
187
188 std::unique_ptr<char[]> compressedBuffer = bloscCompress(
189
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<char*>(uncompressedBuffer.get()), sizeof(int), compressedBytes);
190
191
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(!compressedBuffer);
192
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_EQ(compressedBytes, size_t(0));
193 }
194
195 { // padded buffer
196 1 std::unique_ptr<char[]> largeBuffer(new char[2048]);
197
198
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1 times.
256 for (int paddedCount = 1; paddedCount < 256; paddedCount++) {
199
200
1/2
✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
255 std::unique_ptr<char[]> newTest(new char[paddedCount]);
201
2/2
✓ Branch 0 taken 32640 times.
✓ Branch 1 taken 255 times.
32895 for (int i = 0; i < paddedCount; i++) newTest.get()[i] = char(0);
202
203 #ifdef OPENVDB_USE_BLOSC
204 size_t compressedBytes;
205 std::unique_ptr<char[]> compressedBuffer = bloscCompress(
206
1/2
✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
255 newTest.get(), paddedCount, compressedBytes);
207
208 // compress into a large buffer to check for any padding issues
209 size_t compressedSizeBytes;
210
1/2
✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
255 bloscCompress(largeBuffer.get(), compressedSizeBytes, size_t(2048),
211 newTest.get(), paddedCount);
212
213 // regardless of compression, these numbers should always match
214
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 255 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
255 EXPECT_EQ(compressedSizeBytes, compressedBytes);
215
216 // no compression performed due to buffer being too small
217
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 207 times.
255 if (paddedCount <= BLOSC_MINIMUM_BYTES) {
218
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
48 EXPECT_TRUE(!compressedBuffer);
219 }
220 else {
221
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 207 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
207 EXPECT_TRUE(compressedBuffer);
222
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 207 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
207 EXPECT_TRUE(compressedBytes > 0);
223
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 207 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
207 EXPECT_TRUE(int(compressedBytes) < paddedCount);
224
225 std::unique_ptr<char[]> uncompressedBuffer = bloscDecompress(
226
1/2
✓ Branch 1 taken 207 times.
✗ Branch 2 not taken.
207 compressedBuffer.get(), paddedCount);
227
228
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 207 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
207 EXPECT_TRUE(uncompressedBuffer);
229
230
2/2
✓ Branch 0 taken 31464 times.
✓ Branch 1 taken 207 times.
31671 for (int i = 0; i < paddedCount; i++) {
231
2/16
✓ Branch 1 taken 31464 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 31464 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
31464 EXPECT_EQ((uncompressedBuffer.get())[i], newTest[i]);
232 }
233 }
234 #endif
235 }
236 }
237
238 { // invalid buffer (out of range)
239
240 // compress
241
242 std::vector<int> smallBuffer;
243
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 smallBuffer.resize(count);
244
245
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 1 times.
257 for (int i = 0; i < count; i++) smallBuffer[i] = i;
246
247 size_t invalidBytes = INT_MAX - 1;
248
249
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 size_t testCompressedBytes = bloscCompressedSize(
250 1 reinterpret_cast<char*>(&smallBuffer[0]), invalidBytes);
251
252
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_EQ(testCompressedBytes, size_t(0));
253
254 std::unique_ptr<char[]> buffer = bloscCompress(
255
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<char*>(&smallBuffer[0]), invalidBytes, testCompressedBytes);
256
257
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(!buffer);
258
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_EQ(testCompressedBytes, size_t(0));
259
260 // decompress
261
262 #ifdef OPENVDB_USE_BLOSC
263 std::unique_ptr<char[]> compressedBuffer = bloscCompress(
264
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<char*>(&smallBuffer[0]), count * sizeof(int), testCompressedBytes);
265
266
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
2 EXPECT_THROW(buffer = bloscDecompress(
267 reinterpret_cast<char*>(compressedBuffer.get()), invalidBytes - 16),
268 openvdb::RuntimeError);
269
270
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(!buffer);
271
272
4/22
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
2 EXPECT_THROW(bloscDecompress(
273 reinterpret_cast<char*>(compressedBuffer.get()), count * sizeof(int) + 1),
274 openvdb::RuntimeError);
275 #endif
276 }
277
278 { // uncompressible buffer
279 const int uncompressedCount = 32;
280
281 std::vector<int> values;
282
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 values.reserve(uncompressedCount); // 128 bytes
283
284 // insert a sequence of 32 integer values that cannot be compressed using Blosc
285
286
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1 times.
33 for (int i = 0; i < uncompressedCount; i++) {
287
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if ((i%2) == 0) {
288
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 values.push_back(i * 12340);
289 } else {
290
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 values.push_back(i * 56780);
291 }
292 }
293
294
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 std::unique_ptr<int[]> uncompressedBuffer(new int[values.size()]);
295
296
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1 times.
33 for (size_t i = 0; i < values.size(); i++) uncompressedBuffer.get()[i] = values[i];
297
298 1 size_t uncompressedBytes = values.size() * sizeof(int);
299 size_t compressedBytes;
300
301 std::unique_ptr<char[]> compressedBuffer = bloscCompress(
302
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<char*>(uncompressedBuffer.get()), uncompressedBytes, compressedBytes);
303
304
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(!compressedBuffer);
305
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_EQ(compressedBytes, size_t(0));
306 }
307 1 }
308
309
310 void
311 1 TestStreamCompression::testPagedStreams()
312 {
313 { // one small value
314 2 std::ostringstream ostr(std::ios_base::binary);
315
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(ostr);
316
317 1 int foo = 5;
318
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&foo), sizeof(int));
319
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(0));
320
321
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.flush();
322
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(sizeof(int)));
323 }
324
325 { // small values up to page threshold
326 2 std::ostringstream ostr(std::ios_base::binary);
327
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(ostr);
328
329
2/2
✓ Branch 0 taken 1048576 times.
✓ Branch 1 taken 1 times.
1048577 for (int i = 0; i < PageSize; i++) {
330 1048576 uint8_t oneByte = 255;
331
1/2
✓ Branch 1 taken 1048576 times.
✗ Branch 2 not taken.
1048576 ostream.write(reinterpret_cast<const char*>(&oneByte), sizeof(uint8_t));
332 }
333
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(0));
334
335 std::vector<uint8_t> values;
336
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 values.assign(PageSize, uint8_t(255));
337
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 size_t compressedSize = compression::bloscCompressedSize(
338 reinterpret_cast<const char*>(&values[0]), PageSize);
339
340 1 uint8_t oneMoreByte(255);
341
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&oneMoreByte), sizeof(char));
342
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (compressedSize == 0) {
344 EXPECT_EQ(ostr.tellp(), std::streampos(PageSize));
345 }
346 else {
347
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(compressedSize));
348 }
349 }
350
351 { // one large block at exactly page threshold
352 2 std::ostringstream ostr(std::ios_base::binary);
353
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(ostr);
354
355 std::vector<uint8_t> values;
356
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 values.assign(PageSize, uint8_t(255));
357
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&values[0]), values.size());
358
359
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(0));
360 }
361
362 { // two large blocks at page threshold + 1 byte
363 2 std::ostringstream ostr(std::ios_base::binary);
364
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(ostr);
365
366 std::vector<uint8_t> values;
367
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 values.assign(PageSize + 1, uint8_t(255));
368
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&values[0]), values.size());
369
370
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 size_t compressedSize = compression::bloscCompressedSize(
371 reinterpret_cast<const char*>(&values[0]), values.size());
372
373 #ifndef OPENVDB_USE_BLOSC
374 compressedSize = values.size();
375 #endif
376
377
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(compressedSize));
378
379
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&values[0]), values.size());
380
381
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(compressedSize * 2));
382
383 1 uint8_t oneMoreByte(255);
384
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&oneMoreByte), sizeof(uint8_t));
385
386
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.flush();
387
388
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ostr.tellp(), std::streampos(compressedSize * 2 + 1));
389 }
390
391 { // one full page
392 2 std::stringstream ss(std::ios_base::out | std::ios_base::in | std::ios_base::binary);
393
394 // write
395
396
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostreamSizeOnly(ss);
397 ostreamSizeOnly.setSizeOnly(true);
398
399
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ss.tellp(), std::streampos(0));
400
401 std::vector<uint8_t> values;
402
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 values.resize(PageSize);
403 1 std::iota(values.begin(), values.end(), 0); // ascending integer values
404
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostreamSizeOnly.write(reinterpret_cast<const char*>(&values[0]), values.size());
405
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostreamSizeOnly.flush();
406
407 #ifdef OPENVDB_USE_BLOSC
408 // two integers - compressed size and uncompressed size
409
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ss.tellp(), std::streampos(sizeof(int)*2));
410 #else
411 // one integer - uncompressed size
412 EXPECT_EQ(ss.tellp(), std::streampos(sizeof(int)));
413 #endif
414
415
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(ss);
416
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&values[0]), values.size());
417
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.flush();
418
419 #ifndef OPENVDB_USE_BLOSC
420 EXPECT_EQ(ss.tellp(), std::streampos(PageSize+sizeof(int)));
421 #endif
422
423 // read
424
425
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ss.tellg(), std::streampos(0));
426
427
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PagedInputStream istream(ss);
428 istream.setSizeOnly(true);
429
430
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PageHandle::Ptr handle = istream.createHandle(values.size());
431
432 #ifdef OPENVDB_USE_BLOSC
433 // two integers - compressed size and uncompressed size
434
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(ss.tellg(), std::streampos(sizeof(int)*2));
435 #else
436 // one integer - uncompressed size
437 EXPECT_EQ(ss.tellg(), std::streampos(sizeof(int)));
438 #endif
439
440
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 istream.read(handle, values.size(), false);
441
442 #ifndef OPENVDB_USE_BLOSC
443 EXPECT_EQ(ss.tellg(), std::streampos(PageSize+sizeof(int)));
444 #endif
445
446
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 std::unique_ptr<uint8_t[]> newValues(reinterpret_cast<uint8_t*>(handle->read().release()));
447
448
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(newValues);
449
450
2/2
✓ Branch 0 taken 1048576 times.
✓ Branch 1 taken 1 times.
1048577 for (size_t i = 0; i < values.size(); i++) {
451
2/16
✓ Branch 1 taken 1048576 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1048576 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1048576 EXPECT_EQ(values[i], newValues.get()[i]);
452 }
453 }
454
455 std::string tempDir;
456
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 if (const char* dir = std::getenv("TMPDIR")) tempDir = dir;
457 #ifdef _WIN32
458 if (tempDir.empty()) {
459 char tempDirBuffer[MAX_PATH+1];
460 int tempDirLen = GetTempPath(MAX_PATH+1, tempDirBuffer);
461 EXPECT_TRUE(tempDirLen > 0 && tempDirLen <= MAX_PATH);
462 tempDir = tempDirBuffer;
463 }
464 #else
465
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 if (tempDir.empty()) tempDir = P_tmpdir;
466 #endif
467
468 {
469
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::string filename = tempDir + "/openvdb_page1";
470
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 io::StreamMetadata::Ptr streamMetadata(new io::StreamMetadata);
471
472 { // ascending values up to 10 million written in blocks of PageSize/3
473
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 std::ofstream fileout(filename.c_str(), std::ios_base::binary);
474
475
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 io::setStreamMetadataPtr(fileout, streamMetadata);
476
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 io::setDataCompression(fileout, openvdb::io::COMPRESS_BLOSC);
477
478 std::vector<uint8_t> values;
479
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 values.resize(10*1000*1000);
480 1 std::iota(values.begin(), values.end(), 0); // ascending integer values
481
482 // write page sizes
483
484
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostreamSizeOnly(fileout);
485 ostreamSizeOnly.setSizeOnly(true);
486
487
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(fileout.tellp(), std::streampos(0));
488
489 int increment = PageSize/3;
490
491
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 for (size_t i = 0; i < values.size(); i += increment) {
492
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if (size_t(i+increment) > values.size()) {
493 ostreamSizeOnly.write(
494
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 reinterpret_cast<const char*>(&values[0]+i), values.size() - i);
495 }
496 else {
497
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ostreamSizeOnly.write(reinterpret_cast<const char*>(&values[0]+i), increment);
498 }
499 }
500
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostreamSizeOnly.flush();
501
502 #ifdef OPENVDB_USE_BLOSC
503
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 int pages = static_cast<int>(fileout.tellp() / (sizeof(int)*2));
504 #else
505 int pages = static_cast<int>(fileout.tellp() / (sizeof(int)));
506 #endif
507
508
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(pages, 10);
509
510 // write
511
512
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 PagedOutputStream ostream(fileout);
513
514
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 for (size_t i = 0; i < values.size(); i += increment) {
515
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if (size_t(i+increment) > values.size()) {
516
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.write(reinterpret_cast<const char*>(&values[0]+i), values.size() - i);
517 }
518 else {
519
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ostream.write(reinterpret_cast<const char*>(&values[0]+i), increment);
520 }
521 }
522
523
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ostream.flush();
524
525 #ifndef OPENVDB_USE_BLOSC
526 EXPECT_EQ(fileout.tellp(), std::streampos(values.size()+sizeof(int)*pages));
527 #endif
528
529 // abuse File being a friend of MappedFile to get around the private constructor
530
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 ProxyMappedFile* proxy = new ProxyMappedFile(filename);
531 SharedPtr<io::MappedFile> mappedFile(reinterpret_cast<io::MappedFile*>(proxy));
532
533 // read
534
535
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 std::ifstream filein(filename.c_str(), std::ios_base::in | std::ios_base::binary);
536
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 io::setStreamMetadataPtr(filein, streamMetadata);
537
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 io::setMappedFilePtr(filein, mappedFile);
538
539
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(filein.tellg(), std::streampos(0));
540
541
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PagedInputStream istreamSizeOnly(filein);
542 istreamSizeOnly.setSizeOnly(true);
543
544 1 std::vector<PageHandle::Ptr> handles;
545
546
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 for (size_t i = 0; i < values.size(); i += increment) {
547
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if (size_t(i+increment) > values.size()) {
548
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 handles.push_back(istreamSizeOnly.createHandle(values.size() - i));
549 }
550 else {
551
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
56 handles.push_back(istreamSizeOnly.createHandle(increment));
552 }
553 }
554
555 #ifdef OPENVDB_USE_BLOSC
556 // two integers - compressed size and uncompressed size
557
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 EXPECT_EQ(filein.tellg(), std::streampos(pages*sizeof(int)*2));
558 #else
559 // one integer - uncompressed size
560 EXPECT_EQ(filein.tellg(), std::streampos(pages*sizeof(int)));
561 #endif
562
563
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PagedInputStream istream(filein);
564
565 int pageHandle = 0;
566
567
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 for (size_t i = 0; i < values.size(); i += increment) {
568
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if (size_t(i+increment) > values.size()) {
569
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 istream.read(handles[pageHandle++], values.size() - i);
570 }
571 else {
572
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 istream.read(handles[pageHandle++], increment);
573 }
574 }
575
576 // first three handles live in the same page
577
578
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Page& page0 = handles[0]->page();
579
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Page& page1 = handles[1]->page();
580
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Page& page2 = handles[2]->page();
581
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Page& page3 = handles[3]->page();
582
583
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(page0.isOutOfCore());
584
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(page1.isOutOfCore());
585
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(page2.isOutOfCore());
586
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(page3.isOutOfCore());
587
588
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 handles[0]->read();
589
590 // store the Page shared_ptr
591
592 Page::Ptr page = handles[0]->mPage;
593
594 // verify use count is four (one plus three handles)
595
596
3/18
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_EQ(page.use_count(), long(4));
597
598 // on reading from the first handle, all pages referenced
599 // in the first three handles are in-core
600
601
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(!page0.isOutOfCore());
602
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(!page1.isOutOfCore());
603
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(!page2.isOutOfCore());
604
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
1 EXPECT_TRUE(page3.isOutOfCore());
605
606
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
2 handles[1]->read();
607
608
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(handles[0]->mPage);
609
610
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 handles[2]->read();
611
612 handles.erase(handles.begin());
613 handles.erase(handles.begin());
614 handles.erase(handles.begin());
615
616 // after all three handles have been read,
617 // page should have just one use count (itself)
618
619
3/20
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
2 EXPECT_EQ(page.use_count(), long(1));
620 }
621 1 std::remove(filename.c_str());
622 }
623 1 }
624
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestStreamCompression, testPagedStreams) { testPagedStreams(); }
625