Commit 9ecc6055 authored by Morten Ofstad's avatar Morten Ofstad
Browse files

Merge branch feature/morten.ofstad/remapping with refs/heads/master into...

Merge branch feature/morten.ofstad/remapping with refs/heads/master into refs/merge-requests/545/train
parents 00ab7265 4619ed70
Pipeline #90490 passed with stages
in 23 minutes and 42 seconds
......@@ -770,9 +770,15 @@ public class MemoryVdsGeneratorTest {
for (DimensionsND dimGroup : DimensionsND.values()) {
VDSProduceStatus vdsProduceStatus = accessManager.getVDSProduceStatus(dimGroup, l.ordinal(), channel);
if (channel == 0 && LOD_LEVELS_NONE.equals(l) && DimensionsND.DIMENSIONS_012.equals(dimGroup))
assertEquals(VDSProduceStatus.NORMAL, vdsProduceStatus);
assertEquals(vdsProduceStatus, VDSProduceStatus.NORMAL);
else if (channel == 0 && LOD_LEVELS_NONE.equals(l) && DimensionsND.DIMENSIONS_01.equals(dimGroup))
assertEquals(vdsProduceStatus, VDSProduceStatus.REMAPPED);
else if (channel == 0 && LOD_LEVELS_NONE.equals(l) && DimensionsND.DIMENSIONS_02.equals(dimGroup))
assertEquals(vdsProduceStatus, VDSProduceStatus.REMAPPED);
else if (channel == 0 && LOD_LEVELS_NONE.equals(l) && DimensionsND.DIMENSIONS_12.equals(dimGroup))
assertEquals(vdsProduceStatus, VDSProduceStatus.REMAPPED);
else
assertEquals(VDSProduceStatus.UNAVAILABLE, vdsProduceStatus);
assertEquals(vdsProduceStatus, VDSProduceStatus.UNAVAILABLE);
}
}
}
......
......@@ -21,6 +21,8 @@
#include <OpenVDS/OpenVDS.h>
#include <OpenVDS/VolumeDataChannelDescriptor.h>
#include <stdexcept>
namespace OpenVDS
{
......@@ -102,8 +104,7 @@ inline int32_t GetVoxelFormatByteSize(VolumeDataChannelDescriptor::Format format
iRetval =1;
break;
default:
fprintf(stderr, "Unknown voxel format");
abort();
throw std::runtime_error("Unknown voxel format");
}
return iRetval;
......@@ -114,8 +115,7 @@ static uint32_t GetElementSize(VolumeDataChannelDescriptor::Format format, Volum
switch(format)
{
default:
fprintf(stderr, "Illegal format");
abort();
throw std::runtime_error("Illegal format");
case VolumeDataChannelDescriptor::Format_1Bit:
return 1;
case VolumeDataChannelDescriptor::Format_U8:
......
......@@ -854,10 +854,10 @@ Json::Value SerializeLayerStatusArray(VolumeDataLayoutImpl const &volumeDataLayo
if(volumeDataLayer->GetProduceStatus() != VolumeDataLayer::ProduceStatus_Unavailable)
{
std::string layerName = GetLayerName(*volumeDataLayer);
Json::Value layerStatusJson = SerializeLayerStatus(*volumeDataLayer, layerName);
MetadataStatus metadataStatus;
if(layerMetadataContainer.GetMetadataStatus(layerName, metadataStatus))
{
Json::Value layerStatusJson = SerializeLayerStatus(*volumeDataLayer, layerName);
Json::Value metadataStatusJson = SerializeMetadataStatus(metadataStatus);
for (const auto& key : metadataStatusJson.getMemberNames())
......@@ -866,8 +866,8 @@ Json::Value SerializeLayerStatusArray(VolumeDataLayoutImpl const &volumeDataLayo
}
layerStatusJson["hasChunkMetadataPages"] = true;
layerStatusArrayJson.append(layerStatusJson);
}
layerStatusArrayJson.append(layerStatusJson);
}
}
}
......
......@@ -678,8 +678,9 @@ void VolumeDataAccessManagerImpl::AddCopyPageJob(VolumeDataChunk& chunk, VolumeD
auto destFormat = PrivateGetLayout()->GetChannelFormat(chunk.layer->GetChannelIndex());
DataBlock destDataBlock;
std::vector<uint8_t> deserializedData;
sourceDataStore->DeserializeVolumeData(sourceChunk, serializedData, metadata, compressionInfo.GetCompressionMethod(), sourceChunk.layer->GetEffectiveWaveletAdaptiveLoadLevel(), destFormat, destDataBlock, deserializedData, error);
destination.RequestWritePage(chunk.index, destDataBlock, deserializedData);
uint64_t hash = VolumeDataHash::UNKNOWN;
sourceDataStore->DeserializeVolumeData(sourceChunk, serializedData, metadata, compressionInfo.GetCompressionMethod(), sourceChunk.layer->GetEffectiveWaveletAdaptiveLoadLevel(), destFormat, destDataBlock, deserializedData, hash, error);
destination.RequestWritePage(chunk.index, destDataBlock, deserializedData, hash);
}
destination.GetManager()->GetVolumeDataLayout()->CompletePendingWriteChunkRequests(int32_t(threadCount));
return error;
......@@ -727,6 +728,11 @@ void VolumeDataAccessManagerImpl::FlushCopyPageJobs()
}
int64_t VolumeDataAccessManagerImpl::AddRemapJob(VolumeDataPageImpl &targetPage, std::vector<VolumeDataChunk> const &sourceChunks)
{
return m_requestProcessor->RequestRemap(targetPage, sourceChunks);
}
void VolumeDataAccessManagerImpl::AddUploadError(Error const &error, const std::string &url)
{
std::unique_lock<std::mutex> lock(m_mutex);
......
......@@ -131,6 +131,8 @@ public:
void AddCopyPageJob(VolumeDataChunk& chunk, VolumeDataPageAccessorImpl& destination, VolumeDataPageAccessorImpl& source);
void FlushCopyPageJobs();
int64_t AddRemapJob(VolumeDataPageImpl &targetPage, std::vector<VolumeDataChunk> const &sourceChunks);
void AddUploadError(Error const &error, const std::string &url);
void FlushUploadQueue(bool writeUpdatedLayerStatus = true) override;
......
......@@ -46,7 +46,7 @@ VolumeDataLayer::VolumeDataLayer(VolumeDataPartition const &volumeDataPartition,
, m_nextChannelLayer(nullptr)
, m_lowerLOD(lowerLOD)
, m_higherLOD(nullptr)
, m_remapFromLayer(this)
, m_remapFromLayer(nullptr)
, m_produceStatus(ProduceStatus_Unavailable)
{
assert(volumeDataLayout);
......@@ -138,27 +138,36 @@ void VolumeDataLayer::GetChunksOverlappingChunk(VolumeDataChunk const &cVolumeDa
const VolumeDataLayer * VolumeDataLayer::GetLayerToRemapFrom() const
{
std::unique_lock<std::mutex>
lock(m_volumeDataLayout->m_remapInfoMutex);
if(!m_remapFromLayer)
{
m_remapFromLayer = m_volumeDataLayout->FindLayerToRemapFrom(this);
m_volumeDataLayout->m_hasRemapInfo = true;
assert(m_remapFromLayer);
}
return m_remapFromLayer;
}
//VolumeDataLayer::ProduceMethod VolumeDataLayer::getProduceMethod() const
//{
// if(m_channel != 0)
// {
// return m_primaryChannelLayer->m_produceMethod;
// }
// else
// {
// return m_produceMethod;
// }
//}
VolumeDataLayer::ProduceStatus VolumeDataLayer::GetProduceStatus() const
{
return m_produceStatus;
if(m_produceStatus == ProduceStatus::ProduceStatus_Unavailable && GetLayerToRemapFrom()->m_produceStatus == ProduceStatus_Normal)
{
// Automatic LOD creation is not implemented yet, so we have to return Unavailable in this case
if(GetLayerToRemapFrom()->GetLOD() != GetLOD())
{
return ProduceStatus_Unavailable;
}
return ProduceStatus_Remapped;
}
else
{
return m_produceStatus;
}
}
const VolumeDataChannelDescriptor & VolumeDataLayer::GetVolumeDataChannelDescriptor() const
{
return m_volumeDataLayout->GetVolumeDataChannelDescriptor(m_channel);
......@@ -328,7 +337,14 @@ float VolumeDataLayer::GetIntegerOffset() const
void VolumeDataLayer::SetProduceStatus(ProduceStatus produceStatus)
{
m_produceStatus = produceStatus;
if(m_produceStatus != produceStatus)
{
std::unique_lock<std::mutex>
lock(m_volumeDataLayout->m_remapInfoMutex);
m_produceStatus = produceStatus;
m_volumeDataLayout->InvalidateRemapInfoNoLock();
}
}
}
......@@ -48,14 +48,6 @@ public:
Virtual
};
enum ProduceMethod
{
// These are ordered, so greater values mean easier to produce
AlwaysRemap,
RemapFromCachedIfPossible,
NeverRemap
};
enum ProduceStatus
{
// These are ordered, so greater values mean easier to produce
......@@ -80,7 +72,6 @@ private:
VolumeDataLayer * m_higherLOD;
mutable const VolumeDataLayer * m_remapFromLayer;
//bool m_isAllowRemapFromRemap;
ProduceStatus m_produceStatus;
......
......@@ -280,6 +280,7 @@ VolumeDataLayoutImpl::VolumeDataLayoutImpl(VDS &vds,
, m_isZipLosslessChannels(isZipLosslessChannels)
, m_waveletAdaptiveLoadLevel(waveletAdaptiveLoadLevel)
, m_fullResolutionDimension(layoutDescriptor.IsForceFullResolutionDimension() ? layoutDescriptor.GetFullResolutionDimension() : -1)
, m_hasRemapInfo(false)
{
for(int32_t dimension = 0; dimension < ArraySize(m_dimensionNumSamples); dimension++)
......@@ -309,7 +310,7 @@ VolumeDataLayoutImpl::~VolumeDataLayoutImpl()
VolumeDataLayer::VolumeDataLayerID VolumeDataLayoutImpl::AddDataLayer(VolumeDataLayer *layer)
{
m_volumeDataLayers.emplace_back(layer, &deleteLayer);
m_volumeDataLayers.emplace_back(layer, [](VolumeDataLayer *layer) { delete layer; });
return VolumeDataLayer::VolumeDataLayerID(m_volumeDataLayers.size() - 1);
}
......@@ -642,6 +643,141 @@ void VolumeDataLayoutImpl::CreateLayers(DimensionGroup dimensionGroup, int32_t b
}
}
VolumeDataLayer const *
VolumeDataLayoutImpl::FindLayerToRemapFrom(VolumeDataLayer const *volumeDataLayer) const
{
assert(volumeDataLayer);
if(volumeDataLayer->GetLayerType() == VolumeDataLayer::Virtual)
{
return volumeDataLayer;
}
int channel = volumeDataLayer->GetChannelIndex();
int LOD = volumeDataLayer->GetLOD();
DimensionGroup
dimensionGroup = volumeDataLayer->GetOriginalDimensionGroup();
VolumeDataLayer const *
candidateLayer = volumeDataLayer;
bool
candidateIsSameLOD = false,
candidateIsSameDimensionGroup = false;
for(int layerID = 0; layerID < GetLayerCount(); layerID++)
{
VolumeDataLayer const *sourceLayer = GetVolumeDataLayerFromID(VolumeDataLayer::VolumeDataLayerID(layerID));
if (!sourceLayer || sourceLayer->GetLayerType() == VolumeDataLayer::Virtual || sourceLayer->GetChannelIndex() != channel) continue;
// Do not consider remapping from a layer we always have to remap to produce data in
if(sourceLayer->m_produceStatus != VolumeDataLayer::ProduceStatus_Normal)
{
continue;
}
DimensionGroup
sourceDimensionGroup = sourceLayer->GetOriginalDimensionGroup();
// Check if remapping is possible (dimension groups are sharing 2 dimensions)
if((LOD == 0 && !DimensionGroupUtil::IsRemappingPossible(sourceDimensionGroup, dimensionGroup)) || (LOD > 0 && sourceDimensionGroup != dimensionGroup))
{
continue;
}
// Check if LOD generation is possible
if(sourceLayer->GetLOD() != LOD)
{
// Can only generate LOD from the LOD directly below
if(sourceLayer->GetLOD() != LOD - 1)
{
continue;
}
// Can only generate LOD with renderable layers
if(volumeDataLayer->GetLayerType() != VolumeDataLayer::Renderable || sourceLayer->GetLayerType() != VolumeDataLayer::Renderable)
{
continue;
}
}
bool preferSourceLayer = false;
// 1) It is better to remap from a layer in the same LOD
if (!candidateIsSameLOD && sourceLayer->GetLOD() == LOD)
{
preferSourceLayer = true;
}
else if (candidateIsSameLOD == (sourceLayer->GetLOD() == LOD))
{
// 2) It is better to remap from a layer in the same dimension group
if (!candidateIsSameDimensionGroup && sourceDimensionGroup == dimensionGroup)
{
preferSourceLayer = true;
}
else if (candidateIsSameDimensionGroup == (sourceDimensionGroup == dimensionGroup))
{
// 3) All things being equal, it's better not to remap
if(volumeDataLayer == sourceLayer)
{
preferSourceLayer = true;
}
}
}
if (preferSourceLayer)
{
candidateIsSameLOD = (sourceLayer->GetLOD() == LOD);
candidateIsSameDimensionGroup = (sourceDimensionGroup == dimensionGroup);
candidateLayer = sourceLayer;
}
}
// If the base layer of the source for remapping is cached, we want to remap through the base layer
VolumeDataLayer *
baseLayer = candidateLayer->GetLayout()->GetBaseLayer(candidateLayer->GetOriginalDimensionGroup(), candidateLayer->GetChannelIndex());
while(baseLayer && baseLayer->GetLOD() < candidateLayer->GetLOD())
{
baseLayer = baseLayer->GetParentLayer();
}
if(baseLayer && baseLayer->m_produceStatus == VolumeDataLayer::ProduceStatus_Normal)
{
candidateLayer = baseLayer;
}
assert((candidateLayer == volumeDataLayer || candidateLayer->m_remapFromLayer != volumeDataLayer) && "We can't remap from a layer which remaps from this layer!");
return candidateLayer;
}
void
VolumeDataLayoutImpl::InvalidateRemapInfoNoLock() const
{
if(m_hasRemapInfo)
{
for(int layerID = 0; layerID < GetLayerCount(); layerID++)
{
VolumeDataLayer *volumeDataLayer = GetVolumeDataLayerFromID(VolumeDataLayer::VolumeDataLayerID(layerID));
volumeDataLayer->m_remapFromLayer = nullptr;
}
m_hasRemapInfo = false;
}
}
void
VolumeDataLayoutImpl::InvalidateRemapInfo() const
{
std::unique_lock<std::mutex>
lock(m_remapInfoMutex);
InvalidateRemapInfoNoLock();
}
bool VolumeDataLayoutImpl::IsMetadataIntAvailable(const char* category, const char* name) const { return m_vds.metadataContainer.IsMetadataIntAvailable(category, name); }
bool VolumeDataLayoutImpl::IsMetadataIntVector2Available(const char* category, const char* name) const { return m_vds.metadataContainer.IsMetadataIntVector2Available(category, name); }
bool VolumeDataLayoutImpl::IsMetadataIntVector3Available(const char* category, const char* name) const { return m_vds.metadataContainer.IsMetadataIntVector3Available(category, name); }
......
......@@ -36,15 +36,13 @@ struct VDS;
class VolumeDataLayoutDescriptor;
class VolumeDataLayoutImpl : public VolumeDataLayout
{
private:
static void deleteLayer(VolumeDataLayer *layer)
{
delete layer;
}
VDS &m_vds;
std::vector<std::unique_ptr<VolumeDataLayer, decltype(&deleteLayer)>> m_volumeDataLayers;
std::vector<VolumeDataChannelDescriptor> m_volumeDataChannelDescriptor;
friend class VolumeDataLayer;
VDS &m_vds;
std::vector<std::unique_ptr<VolumeDataLayer, void (*)(VolumeDataLayer *)>>
m_volumeDataLayers;
std::vector<VolumeDataChannelDescriptor>
m_volumeDataChannelDescriptor;
bool m_isReadOnly;
VolumeDataHash m_contentsHash;
int32_t m_dimensionality;
......@@ -73,6 +71,13 @@ private:
float m_dimensionCoordinateMax[Dimensionality_Max];
int32_t m_fullResolutionDimension;
mutable std::mutex
m_remapInfoMutex;
mutable bool m_hasRemapInfo;
VolumeDataLayer const *FindLayerToRemapFrom(VolumeDataLayer const *volumeDataLayer) const;
void InvalidateRemapInfoNoLock() const;
public:
VolumeDataLayoutImpl(VDS &vds,
const VolumeDataLayoutDescriptor &layoutDescriptor,
......@@ -182,6 +187,7 @@ public:
void SetWaveletAdaptiveLoadLevel(int waveletAdaptiveLoadLevel) { m_waveletAdaptiveLoadLevel = waveletAdaptiveLoadLevel; }
void CreateLayers(DimensionGroup dimensionGroup, int32_t brickSize, int32_t physicalLODLevels, VolumeDataLayer::ProduceStatus produceStatus);
void InvalidateRemapInfo() const;
bool IsDimensionLODDecimated(int32_t dimension) const { return dimension != m_fullResolutionDimension; }
int32_t GetFullResolutionDimension() const { return m_fullResolutionDimension; }
......
......@@ -49,6 +49,7 @@ VolumeDataPageAccessorImpl::VolumeDataPageAccessorImpl(VolumeDataAccessManagerIm
, m_lastUsed(std::chrono::steady_clock::now())
{
}
VolumeDataPageAccessorImpl::~VolumeDataPageAccessorImpl()
{
for (auto& page : m_pages)
......@@ -206,7 +207,8 @@ VolumeDataPage* VolumeDataPageAccessorImpl::CreatePage(int64_t chunk)
std::vector<uint8_t> page_data;
DataBlock dataBlock;
if (!VolumeDataStore::CreateConstantValueDataBlock(volumeDataChunk, m_layer->GetFormat(), m_layer->GetNoValue(), m_layer->GetComponents(), m_layer->IsUseNoValue() ? VolumeDataHash::NOVALUE : VolumeDataHash(0.0f), dataBlock, page_data, error))
VolumeDataHash volumeDataHash = m_layer->IsUseNoValue() ? VolumeDataHash::NOVALUE : VolumeDataHash(0.0f);
if (!VolumeDataStore::CreateConstantValueDataBlock(volumeDataChunk, m_layer->GetFormat(), m_layer->GetNoValue(), m_layer->GetComponents(), volumeDataHash, dataBlock, page_data, error))
{
pageListMutexLock.lock();
page->UnPin();
......@@ -214,29 +216,8 @@ VolumeDataPage* VolumeDataPageAccessorImpl::CreatePage(int64_t chunk)
return nullptr;
}
int pitchND[Dimensionality_Max] = {};
for(int chunkDimension = 0; chunkDimension < m_layer->GetChunkDimensionality(); chunkDimension++)
{
int dimension = DimensionGroupUtil::GetDimension(m_layer->GetChunkDimensionGroup(), chunkDimension);
assert(dimension >= 0 && dimension < Dimensionality_Max);
pitchND[dimension] = dataBlock.Pitch[chunkDimension];
// Convert pitch to bitpitch for 1-bit data
if(m_layer->GetFormat() == VolumeDataChannelDescriptor::Format_1Bit)
{
assert(chunkDimension > 0 || pitchND[dimension] == 1);
if(chunkDimension > 0)
{
pitchND[chunkDimension] *= 8;
}
}
}
pageListMutexLock.lock();
page->SetBufferData(dataBlock, pitchND, std::move(page_data));
page->SetBufferData(dataBlock, m_layer->GetChunkDimensionGroup(), m_layer->GetFormat() == VolumeDataFormat::Format_1Bit, std::move(page_data), uint64_t(volumeDataHash));
page->MakeDirty();
m_pageReadCondition.notify_all();
......@@ -297,7 +278,7 @@ VolumeDataPage* VolumeDataPageAccessorImpl::PrepareReadPage(int64_t chunk, Error
}
}
// Not found, we need to create a new page
// Not found, we need to create a new page,0
VolumeDataPageImpl *page = new VolumeDataPageImpl(this, chunk);
m_pages.push_front(page);
......@@ -305,9 +286,21 @@ VolumeDataPage* VolumeDataPageAccessorImpl::PrepareReadPage(int64_t chunk, Error
assert(page->IsPinned());
VolumeDataChunk volumeDataChunk = m_layer->GetChunkFromIndex(chunk);
if (!m_accessManager->GetVolumeDataStore()->PrepareReadChunk(volumeDataChunk, m_layer->GetEffectiveWaveletAdaptiveLoadLevel(), error))
VolumeDataLayer const *remapFromLayer = m_layer->GetLayerToRemapFrom();
if(remapFromLayer != m_layer)
{
page->SetError(error);
std::vector<VolumeDataChunk> volumeDataChunkRead;
remapFromLayer->GetChunksOverlappingChunk(volumeDataChunk, &volumeDataChunkRead);
page->SetJobID(m_accessManager->AddRemapJob(*page, volumeDataChunkRead));
}
else
{
if (!m_accessManager->GetVolumeDataStore()->PrepareReadChunk(volumeDataChunk, m_layer->GetEffectiveWaveletAdaptiveLoadLevel(), error))
{
page->SetError(error);
}
}
return page;
......@@ -329,48 +322,72 @@ bool VolumeDataPageAccessorImpl::ReadPreparedPaged(VolumeDataPage* page)
pageImpl->LeaveSettingData();
return true;
}
Error error;
VolumeDataChunk volumeDataChunk = m_layer->GetChunkFromIndex(pageImpl->GetChunkIndex());
std::vector<uint8_t> serialized_data;
std::vector<uint8_t> metadata;
CompressionInfo compressionInfo;
bool success = false;
if (!m_accessManager->GetVolumeDataStore()->ReadChunk(volumeDataChunk, m_layer->GetEffectiveWaveletAdaptiveLoadLevel(), serialized_data, metadata, compressionInfo, error))
int64_t jobID = pageImpl->JobID();
if(jobID != -1)
{
pageListMutexLock.lock();
pageImpl->SetError(error);
pageImpl->SetRequestPrepared(false);
pageImpl->LeaveSettingData();
m_pageReadCondition.notify_all();
//fprintf(stderr, "Failed when waiting for chunk: %s\n", error.string.c_str());
return false;
}
success = m_accessManager->WaitForCompletion(jobID);
std::vector<uint8_t> page_data;
DataBlock dataBlock;
if (!m_accessManager->GetVolumeDataStore()->DeserializeVolumeData(volumeDataChunk, serialized_data, metadata, compressionInfo.GetCompressionMethod(), compressionInfo.GetAdaptiveLevel(), m_layer->GetFormat(), dataBlock, page_data, error))
{
pageListMutexLock.lock();
pageImpl->SetError(error);
pageImpl->SetRequestPrepared(false);
pageImpl->LeaveSettingData();
m_pageReadCondition.notify_all();
//fprintf(stderr, "Failed when deserializing chunk: %s\n", error.string.c_str());
return false;
if(!success)
{
bool canceled = m_accessManager->IsCanceled(jobID);
(void)canceled;
assert(canceled);
int errorCode = 0;
const char* errorString = nullptr;
m_accessManager->GetCurrentDownloadError(&errorCode, &errorString);
error.code = errorCode;
error.string = errorString ? errorString : "";
pageListMutexLock.lock();
pageImpl->SetError(error);
pageImpl->SetRequestPrepared(false);
pageImpl->LeaveSettingData();
m_pageReadCondition.notify_all();
//fprintf(stderr, "Failed when waiting for chunk: %s\n", error.string.c_str());
return false;
}
}
else
{
VolumeDataChunk volumeDataChunk = m_layer->GetChunkFromIndex(pageImpl->GetChunkIndex());
std::vector<uint8_t> serialized_data;
std::vector<uint8_t> metadata;
CompressionInfo compressionInfo;
int pitch[Dimensionality_Max] = {};
if (!m_accessManager->GetVolumeDataStore()->ReadChunk(volumeDataChunk, m_layer->GetEffectiveWaveletAdaptiveLoadLevel(), serialized_data, metadata, compressionInfo, error))
{
pageListMutexLock.lock();
pageImpl->SetError(error);
pageImpl->SetRequestPrepared(false);
pageImpl->LeaveSettingData();
m_pageReadCondition.notify_all();
//fprintf(stderr, "Failed when waiting for chunk: %s\n", error.string.c_str());
return false;
}
for (int chunkDimension = 0; chunkDimension < m_layer->GetChunkDimensionality(); chunkDimension++)
{
int dimension = DimensionGroupUtil::GetDimension(m_layer->GetChunkDimensionGroup(), chunkDimension);
std::vector<uint8_t> page_data;
uint64_t page_hash = VolumeDataHash::UNKNOWN;
DataBlock dataBlock;
if (!m_accessManager->GetVolumeDataStore()->DeserializeVolumeData(volumeDataChunk, serialized_data, metadata, compressionInfo.GetCompressionMethod(), compressionInfo.GetAdaptiveLevel(), m_layer->GetFormat(), dataBlock, page_data, page_hash, error))
{
pageListMutexLock.lock();
pageImpl->SetError(error);
pageImpl->SetRequestPrepared(false);
pageImpl->LeaveSettingData();
m_pageReadCondition.notify_all();
//fprintf(stderr, "Failed when deserializing chunk: %s\n", error.string.c_str());
return false;
}
assert(dimension >= 0 && dimension < Dimensionality_Max);
pitch[dimension] = dataBlock.Pitch[chunkDimension];
pageListMutexLock.lock();
pageImpl->SetBufferData(dataBlock, m_layer->GetChunkDimensionGroup(), m_layer->GetFormat() == VolumeDataFormat::Format_1Bit, std::move(page_data), page_hash);
}