Skip to content

Commit 2e1904a

Browse files
authored
Merge pull request #823 from danrbailey/optionaldelayedload
Make Delayed Loading and Boost IOStreams Optional
2 parents c5a1313 + 567740e commit 2e1904a

25 files changed

+279
-46
lines changed

.github/workflows/weekly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ jobs:
109109
matrix:
110110
config:
111111
- { name: 'all', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=ON -DUSE_ZLIB=ON -DUSE_EXR=ON -DUSE_PNG=ON' }
112-
- { name: 'lite', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=OFF -DUSE_ZLIB=OFF -DUSE_EXR=OFF -DUSE_PNG=OFF' }
112+
- { name: 'lite', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=OFF -DUSE_ZLIB=OFF -DUSE_EXR=OFF -DUSE_PNG=OFF -DOPENVDB_USE_DELAYED_LOADING=OFF' }
113113
- { name: 'half', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DUSE_BLOSC=OFF -DUSE_IMATH_HALF=ON' }
114114
- { name: 'sse', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DOPENVDB_SIMD=SSE42' }
115115
- { name: 'avx', build: 'Release', components: 'core,python,bin,view,render,test', cmake: '-DOPENVDB_SIMD=AVX' }

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ option(OPENVDB_BUILD_AX_UNITTESTS "Build the OpenVDB AX unit tests" OFF)
7979
option(OPENVDB_BUILD_NANOVDB "Build the NanoVDB library. Turns ON if USE_NANOVDB is ON." ${USE_NANOVDB})
8080

8181
option(OPENVDB_BUILD_MAYA_PLUGIN "Build the Maya plugin" OFF)
82+
option(OPENVDB_USE_DELAYED_LOADING "Build the core OpenVDB library with delayed-loading." ON)
8283
option(OPENVDB_ENABLE_RPATH "Build with RPATH information" ON)
8384
option(OPENVDB_CXX_STRICT "Enable or disable pre-defined compiler warnings" OFF)
8485

@@ -247,6 +248,7 @@ mark_as_advanced(
247248
OPENVDB_BUILD_HOUDINI_ABITESTS
248249
OPENVDB_CXX_STRICT
249250
OPENVDB_ENABLE_RPATH
251+
OPENVDB_USE_DELAYED_LOADING
250252
OPENVDB_FUTURE_DEPRECATION
251253
OPENVDB_SIMD
252254
OPENVDB_USE_DEPRECATED_ABI_7

cmake/FindOpenVDB.cmake

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ This will define the following variables:
6464
True if the OpenVDB Library has been built with log4cplus support
6565
``OpenVDB_USES_IMATH_HALF``
6666
True if the OpenVDB Library has been built with Imath half support
67+
``OpenVDB_USES_DELAYED_LOADING``
68+
True if the OpenVDB Library has been built with delayed-loading
6769
``OpenVDB_ABI``
6870
Set if this module was able to determine the ABI number the located
6971
OpenVDB Library was built against. Unset otherwise.
@@ -555,6 +557,7 @@ set(OpenVDB_USES_BLOSC ${USE_BLOSC})
555557
set(OpenVDB_USES_ZLIB ${USE_ZLIB})
556558
set(OpenVDB_USES_LOG4CPLUS ${USE_LOG4CPLUS})
557559
set(OpenVDB_USES_IMATH_HALF ${USE_IMATH_HALF})
560+
set(OpenVDB_USES_DELAYED_LOADING ${OPENVDB_USE_DELAYED_LOADING})
558561
set(OpenVDB_DEFINITIONS)
559562

560563
if(WIN32)
@@ -587,6 +590,7 @@ if(_OPENVDB_HAS_NEW_VERSION_HEADER)
587590
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_IMATH_HALF" OpenVDB_USES_IMATH_HALF)
588591
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_BLOSC" OpenVDB_USES_BLOSC)
589592
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_ZLIB" OpenVDB_USES_ZLIB)
593+
OPENVDB_GET_VERSION_DEFINE(${_OPENVDB_VERSION_HEADER} "OPENVDB_USE_DELAYED_LOADING" OpenVDB_USES_DELAYED_LOADING)
590594
elseif(NOT OPENVDB_USE_STATIC_LIBS)
591595
# Use GetPrerequisites to see which libraries this OpenVDB lib has linked to
592596
# which we can query for optional deps. This basically runs ldd/otoll/objdump
@@ -633,6 +637,11 @@ elseif(NOT OPENVDB_USE_STATIC_LIBS)
633637
if(NOT ${_HAS_DEP} EQUAL -1)
634638
set(OpenVDB_USES_IMATH_HALF ON)
635639
endif()
640+
641+
string(FIND ${PREREQUISITE} "boost_iostreams" _HAS_DEP)
642+
if(NOT ${_HAS_DEP} EQUAL -1)
643+
set(OpenVDB_USES_DELAYED_LOADING ON)
644+
endif()
636645
endforeach()
637646

638647
unset(_OPENVDB_PREREQUISITE_LIST)
@@ -675,7 +684,12 @@ endif()
675684
# namespaced headers are correctly prioritized. Otherwise other include paths
676685
# from shared installs (including houdini) may pull in the wrong headers
677686

678-
set(_OPENVDB_VISIBLE_DEPENDENCIES Boost::iostreams)
687+
set(_OPENVDB_VISIBLE_DEPENDENCIES "")
688+
689+
if(OpenVDB_USES_DELAYED_LOADING)
690+
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES Boost::iostreams)
691+
list(APPEND OpenVDB_DEFINITIONS OPENVDB_USE_DELAYED_LOADING)
692+
endif()
679693

680694
if(OpenVDB_USES_IMATH_HALF)
681695
list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES $<TARGET_NAME_IF_EXISTS:IlmBase::Half> $<TARGET_NAME_IF_EXISTS:Imath::Imath>)

doc/changes.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2479,7 +2479,7 @@ Houdini:
24792479
modified or deleted, so for safety,
24802480
@vdblink::io::File::open() File::open@endlink automatically makes
24812481
private copies of source files that are smaller than a user-specified limit
2482-
(see @vdblink::io::File::setCopyMaxBytes() File::setCopyMaxBytes@endlink).
2482+
(see io::File::setCopyMaxBytes()).
24832483
The limit can be set to zero to disable copying, but if it cannot be
24842484
guaranteed that a file will not be modified, then it is best not to enable
24852485
delayed loading for that file.

doc/dependencies.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Reference Platform, but for those that do, their specified versions are
3737

3838
Component | Requirements | Optional
3939
----------------------- | ------------------------------------------------- | --------
40-
OpenVDB Core Library | CMake, C++17 compiler, TBB::tbb, Boost::iostream | Blosc, ZLib, Log4cplus, IlmBase::Half
40+
OpenVDB Core Library | CMake, C++17 compiler, TBB::tbb | Blosc, ZLib, Log4cplus, IlmBase::Half, Boost::iostream
4141
OpenVDB Print | Core Library dependencies | -
4242
OpenVDB LOD | Core Library dependencies | -
4343
OpenVDB Render | Core Library dependencies | OpenEXR, IlmBase, libpng

openvdb/openvdb/CMakeLists.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ if(OPENVDB_CORE_SHARED AND NOT Boost_USE_STATIC_LIBS)
117117
set(Boost_USE_STATIC_LIBS OFF)
118118
endif()
119119

120-
find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS iostreams)
120+
if(OPENVDB_USE_DELAYED_LOADING)
121+
find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS iostreams)
122+
endif()
123+
121124
if(OPENVDB_FUTURE_DEPRECATION AND FUTURE_MINIMUM_BOOST_VERSION)
122125
# The X.Y.Z boost version value isn't available until CMake 3.14
123126
set(FULL_BOOST_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
@@ -250,7 +253,9 @@ endif()
250253
# if it's in a shared place (like /usr/local) it doesn't accidently pull in
251254
# other headers.
252255

253-
list(APPEND OPENVDB_CORE_DEPENDENT_LIBS Boost::iostreams)
256+
if(OPENVDB_USE_DELAYED_LOADING)
257+
list(APPEND OPENVDB_CORE_DEPENDENT_LIBS Boost::iostreams)
258+
endif()
254259

255260
if(WIN32)
256261
# Boost headers contain #pragma commands on Windows which causes Boost
@@ -639,6 +644,9 @@ endif()
639644
if(USE_LOG4CPLUS)
640645
list(APPEND OPENVDB_CORE_PUBLIC_DEFINES -DOPENVDB_USE_LOG4CPLUS)
641646
endif()
647+
if(OPENVDB_USE_DELAYED_LOADING)
648+
list(APPEND OPENVDB_CORE_PUBLIC_DEFINES -DOPENVDB_USE_DELAYED_LOADING)
649+
endif()
642650

643651
##########################################################################
644652

openvdb/openvdb/io/Archive.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <openvdb/util/logging.h>
1414
#include <openvdb/openvdb.h>
1515

16+
#ifdef OPENVDB_USE_DELAYED_LOADING
1617
// Boost.Interprocess uses a header-only portion of Boost.DateTime
1718
#ifdef __clang__
1819
#pragma clang diagnostic push
@@ -26,10 +27,6 @@
2627
#include <boost/interprocess/mapped_region.hpp>
2728
#include <boost/iostreams/device/array.hpp>
2829
#include <boost/iostreams/stream.hpp>
29-
#include <boost/uuid/uuid_generators.hpp>
30-
#include <boost/uuid/uuid_io.hpp>
31-
32-
#include <atomic>
3330

3431
#ifdef _WIN32
3532
#include <boost/interprocess/detail/os_file_functions.hpp> // open_existing_file(), close_file()
@@ -43,6 +40,13 @@ namespace boost { namespace interprocess { namespace detail {} namespace ipcdeta
4340
#include <sys/stat.h> // for stat()
4441
#include <unistd.h> // for unlink()
4542
#endif
43+
#endif // OPENVDB_USE_DELAYED_LOADING
44+
45+
#include <boost/uuid/uuid_generators.hpp>
46+
#include <boost/uuid/uuid_io.hpp>
47+
48+
#include <atomic>
49+
4650
#include <algorithm> // for std::find_if()
4751
#include <cerrno> // for errno
4852
#include <cstdlib> // for getenv()
@@ -437,6 +441,9 @@ operator<<(std::ostream& os, const StreamMetadata::AuxDataMap& auxData)
437441
////////////////////////////////////////
438442

439443

444+
#ifdef OPENVDB_USE_DELAYED_LOADING
445+
446+
440447
// Memory-mapping a VDB file permits threaded input (and output, potentially,
441448
// though that might not be practical for compressed files or files containing
442449
// multiple grids). In particular, a memory-mapped file can be loaded lazily,
@@ -575,6 +582,9 @@ MappedFile::clearNotifier()
575582
}
576583

577584

585+
#endif // OPENVDB_USE_DELAYED_LOADING
586+
587+
578588
////////////////////////////////////////
579589

580590

@@ -894,6 +904,7 @@ setGridBackgroundValuePtr(std::ios_base& strm, const void* background)
894904
}
895905

896906

907+
#ifdef OPENVDB_USE_DELAYED_LOADING
897908
MappedFile::Ptr
898909
getMappedFilePtr(std::ios_base& strm)
899910
{
@@ -909,6 +920,7 @@ setMappedFilePtr(std::ios_base& strm, io::MappedFile::Ptr& mappedFile)
909920
{
910921
strm.pword(sStreamState.mappedFile) = &mappedFile;
911922
}
923+
#endif // OPENVDB_USE_DELAYED_LOADING
912924

913925

914926
StreamMetadata::Ptr
@@ -1098,7 +1110,11 @@ Archive::connectInstance(const GridDescriptor& gd, const NamedGridMap& grids) co
10981110
bool
10991111
Archive::isDelayedLoadingEnabled()
11001112
{
1113+
#ifdef OPENVDB_USE_DELAYED_LOADING
11011114
return (nullptr == std::getenv("OPENVDB_DISABLE_DELAYED_LOAD"));
1115+
#else
1116+
return false;
1117+
#endif
11021118
}
11031119

11041120

openvdb/openvdb/io/File.cc

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@
99
#include <openvdb/Exceptions.h>
1010
#include <openvdb/util/logging.h>
1111
#include <cstdint>
12+
13+
#ifdef OPENVDB_USE_DELAYED_LOADING
1214
#include <boost/iostreams/copy.hpp>
1315
#ifndef _WIN32
1416
#include <sys/types.h>
15-
#include <sys/stat.h>
1617
#include <unistd.h>
1718
#endif
19+
#endif // OPENVDB_USE_DELAYED_LOADING
20+
21+
#include <sys/stat.h> // stat()
22+
1823
#include <cassert>
1924
#include <cstdlib> // for getenv(), strtoul()
2025
#include <cstring> // for strerror_r()
@@ -81,25 +86,27 @@ struct File::Impl
8186
std::string mFilename;
8287
// The file-level metadata
8388
MetaMap::Ptr mMeta;
84-
// The memory-mapped file
85-
MappedFile::Ptr mFileMapping;
86-
// The buffer for the input stream, if it is a memory-mapped file
87-
SharedPtr<std::streambuf> mStreamBuf;
8889
// The file stream that is open for reading
8990
std::unique_ptr<std::istream> mInStream;
9091
// File-level stream metadata (file format, compression, etc.)
9192
StreamMetadata::Ptr mStreamMetadata;
9293
// Flag indicating if we have read in the global information (header,
9394
// metadata, and grid descriptors) for this VDB file
9495
bool mIsOpen;
95-
// File size limit for copying during delayed loading
96-
Index64 mCopyMaxBytes;
9796
// Grid descriptors for all grids stored in the file, indexed by grid name
9897
NameMap mGridDescriptors;
9998
// All grids, indexed by unique name (used only when mHasGridOffsets is false)
10099
Archive::NamedGridMap mNamedGrids;
101100
// All grids stored in the file (used only when mHasGridOffsets is false)
102101
GridPtrVecPtr mGrids;
102+
#ifdef OPENVDB_USE_DELAYED_LOADING
103+
// The memory-mapped file
104+
MappedFile::Ptr mFileMapping;
105+
// The buffer for the input stream, if it is a memory-mapped file
106+
SharedPtr<std::streambuf> mStreamBuf;
107+
// File size limit for copying during delayed loading
108+
Index64 mCopyMaxBytes;
109+
#endif
103110
}; // class File::Impl
104111

105112

@@ -110,7 +117,9 @@ File::File(const std::string& filename): mImpl(new Impl)
110117
{
111118
mImpl->mFilename = filename;
112119
mImpl->mIsOpen = false;
120+
#ifdef OPENVDB_USE_DELAYED_LOADING
113121
mImpl->mCopyMaxBytes = Impl::getDefaultCopyMaxBytes();
122+
#endif
114123
setInputHasGridOffsets(true);
115124
}
116125

@@ -137,7 +146,9 @@ File::operator=(const File& other)
137146
mImpl->mFilename = otherImpl.mFilename;
138147
mImpl->mMeta = otherImpl.mMeta;
139148
mImpl->mIsOpen = false; // don't want two file objects reading from the same stream
149+
#ifdef OPENVDB_USE_DELAYED_LOADING
140150
mImpl->mCopyMaxBytes = otherImpl.mCopyMaxBytes;
151+
#endif
141152
mImpl->mGridDescriptors = otherImpl.mGridDescriptors;
142153
mImpl->mNamedGrids = otherImpl.mNamedGrids;
143154
mImpl->mGrids = otherImpl.mGrids;
@@ -241,6 +252,7 @@ File::getSize() const
241252
}
242253

243254

255+
#ifdef OPENVDB_USE_DELAYED_LOADING
244256
Index64
245257
File::copyMaxBytes() const
246258
{
@@ -253,6 +265,7 @@ File::setCopyMaxBytes(Index64 bytes)
253265
{
254266
mImpl->mCopyMaxBytes = bytes;
255267
}
268+
#endif
256269

257270

258271
////////////////////////////////////////
@@ -266,7 +279,11 @@ File::isOpen() const
266279

267280

268281
bool
282+
#ifdef OPENVDB_USE_DELAYED_LOADING
269283
File::open(bool delayLoad, const MappedFile::Notifier& notifier)
284+
#else
285+
File::open(bool /*delayLoad = true*/)
286+
#endif // OPENVDB_USE_DELAYED_LOADING
270287
{
271288
if (isOpen()) {
272289
OPENVDB_THROW(IoError, filename() << " is already open");
@@ -276,10 +293,13 @@ File::open(bool delayLoad, const MappedFile::Notifier& notifier)
276293
// Open the file.
277294
std::unique_ptr<std::istream> newStream;
278295
SharedPtr<std::streambuf> newStreamBuf;
296+
#ifdef OPENVDB_USE_DELAYED_LOADING
279297
MappedFile::Ptr newFileMapping;
280298
if (!delayLoad || !Archive::isDelayedLoadingEnabled()) {
299+
#endif
281300
newStream.reset(new std::ifstream(
282301
filename().c_str(), std::ios_base::in | std::ios_base::binary));
302+
#ifdef OPENVDB_USE_DELAYED_LOADING
283303
} else {
284304
bool isTempFile = false;
285305
std::string fname = filename();
@@ -318,6 +338,7 @@ File::open(bool delayLoad, const MappedFile::Notifier& notifier)
318338
OPENVDB_THROW(IoError, ostr.str());
319339
}
320340
}
341+
#endif // OPENVDB_USE_DELAYED_LOADING
321342

322343
if (newStream->fail()) {
323344
OPENVDB_THROW(IoError, "could not open file " << filename());
@@ -335,9 +356,11 @@ File::open(bool delayLoad, const MappedFile::Notifier& notifier)
335356
throw;
336357
}
337358

359+
#ifdef OPENVDB_USE_DELAYED_LOADING
338360
mImpl->mFileMapping = newFileMapping;
339361
if (mImpl->mFileMapping) mImpl->mFileMapping->setNotifier(notifier);
340362
mImpl->mStreamBuf = newStreamBuf;
363+
#endif
341364
mImpl->mInStream.swap(newStream);
342365

343366
// Tag the input stream with the file format and library version numbers
@@ -348,7 +371,9 @@ File::open(bool delayLoad, const MappedFile::Notifier& notifier)
348371
Archive::setFormatVersion(inputStream());
349372
Archive::setLibraryVersion(inputStream());
350373
Archive::setDataCompression(inputStream());
374+
#ifdef OPENVDB_USE_DELAYED_LOADING
351375
io::setMappedFilePtr(inputStream(), mImpl->mFileMapping);
376+
#endif
352377

353378
// Read in the VDB metadata.
354379
mImpl->mMeta = MetaMap::Ptr(new MetaMap);
@@ -396,9 +421,11 @@ File::close()
396421
mImpl->mGrids.reset();
397422
mImpl->mNamedGrids.clear();
398423
mImpl->mInStream.reset();
399-
mImpl->mStreamBuf.reset();
400424
mImpl->mStreamMetadata.reset();
425+
#ifdef OPENVDB_USE_DELAYED_LOADING
426+
mImpl->mStreamBuf.reset();
401427
mImpl->mFileMapping.reset();
428+
#endif
402429

403430
mImpl->mIsOpen = false;
404431
setInputHasGridOffsets(true);

openvdb/openvdb/io/File.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class OPENVDB_API File: public Archive
5454
/// @details The file does not necessarily exist on disk yet.
5555
const std::string& filename() const;
5656

57+
#ifdef OPENVDB_USE_DELAYED_LOADING
5758
/// @brief Open the file, read the file header and the file-level metadata,
5859
/// and populate the grid descriptors, but do not load any grids into memory.
5960
/// @details If @a delayLoad is true, map the file into memory and enable delayed loading
@@ -64,6 +65,9 @@ class OPENVDB_API File: public Archive
6465
/// @return @c true if the file's UUID has changed since it was last read.
6566
/// @see setCopyMaxBytes
6667
bool open(bool delayLoad = true, const MappedFile::Notifier& = MappedFile::Notifier());
68+
#else
69+
bool open(bool /*delayLoad*/ = false);
70+
#endif
6771

6872
/// Return @c true if the file has been opened for reading.
6973
bool isOpen() const;
@@ -75,6 +79,7 @@ class OPENVDB_API File: public Archive
7579
/// @throw IoError if the file size cannot be determined.
7680
Index64 getSize() const;
7781

82+
#ifdef OPENVDB_USE_DELAYED_LOADING
7883
/// @brief Return the size in bytes above which this file will not be
7984
/// automatically copied during delayed loading.
8085
Index64 copyMaxBytes() const;
@@ -90,6 +95,7 @@ class OPENVDB_API File: public Archive
9095
/// by setting the environment variable @c OPENVDB_DELAYED_LOAD_COPY_MAX_BYTES
9196
/// to the desired number of bytes.
9297
void setCopyMaxBytes(Index64 bytes);
98+
#endif
9399

94100
/// Return @c true if a grid of the given name exists in this file.
95101
bool hasGrid(const Name&) const;

0 commit comments

Comments
 (0)