Commit 7f47c285 authored by Jørgen Lind's avatar Jørgen Lind
Browse files

VolumeDataPageAccess implementation

parent 35b1c62f
......@@ -9,6 +9,8 @@ set(SOURCE_FILES
VDS/VolumeDataLayout.cpp
VDS/VolumeDataRegion.cpp
VDS/VolumeDataHash.cpp
VDS/VolumeDataPageAccessorImpl.cpp
VDS/VolumeDataPageImpl.cpp
VDS/DimensionGroup.cpp
VDS/ParseVDSJson.cpp)
......@@ -21,6 +23,8 @@ set (PRIVATE_HEADER_FILES
VDS/VolumeDataChunk.h
VDS/VolumeDataRegion.h
VDS/VolumeDataHash.h
VDS/VolumeDataPageAccessorImpl.h
VDS/VolumeDataPageImpl.h
VDS/DimensionGroup.h
VDS/Hash.h
Math/Vector.h
......
......@@ -198,5 +198,11 @@ bool DownloadJson(const std::string &region, const std::string& bucket, const st
}
return true;
}
bool downloadChunk(VDSHandle &handle, std::vector<uint8_t> &blob, int32_t (&pitch)[Dimensionality_Max], Error &error)
{
assert(false && "TODO: IMPLEMENT");
return false;
}
}
}
......@@ -20,6 +20,8 @@
#include <OpenVDS/openvds_export.h>
#include <OpenVDS/OpenVDS.h>
#include <VDS/DimensionGroup.h>
namespace OpenVDS
{
namespace S3
......@@ -27,5 +29,7 @@ namespace S3
OPENVDS_EXPORT void test_function();
bool DownloadJson(const std::string &region, const std::string& bucket, const std::string &key, std::string &json, Error &error);
bool downloadChunk(VDSHandle &handle, std::vector<uint8_t> &blob, int32_t (&pitch)[Dimensionality_Max]);
}
}
......@@ -24,9 +24,11 @@
#include <memory>
#include "VDS/VolumeDataLayout.h"
#include <OpenVDS/VolumeDataAccess.h>
#include "VDS/VolumeDataLayout.h"
#include "VDS/VolumeDataPageAccessorImpl.h"
namespace OpenVDS
{
VDSHandle *open(const OpenOptions &options, Error &error)
......@@ -72,8 +74,48 @@ void destroy(VDSHandle *handle)
delete handle;
}
VolumeDataPageAccessor *createVolumeDataPageAccessor(VolumeDataLayout *layout, DimensionsND dimension, int lod, int channel, int maxPages)
static VolumeDataLayer *getVolumeDataLayer(VolumeDataLayout *layout, DimensionsND dimension, int channel, int lod, bool isAllowFailure)
{
return nullptr;
if(!layout)
{
fprintf(stderr, "Volume data layout is NULL, this is usually because the VDS setup is invalid");
return nullptr;
}
if(channel > layout->getChannelCount())
{
fprintf(stderr, "Specified channel doesn't exist");
return nullptr;
}
VolumeDataLayer *layer = layout->getBaseLayer(DimensionGroupUtil::getDimensionGroupFromDimensionsND(dimension), channel);
if(!layer && !isAllowFailure)
{
fprintf(stderr, "Specified dimension group doesn't exist");
return nullptr;
}
while(layer && layer->getLod() < lod)
{
layer = layer->getParentLayer();
}
if((!layer || layer->getLayerType() == VolumeDataLayer::Virtual) && !isAllowFailure)
{
fprintf(stderr, "Specified LOD doesn't exist");
}
assert(layer || isAllowFailure);
return (layer->getLayerType() != VolumeDataLayer::Virtual) ? layer : nullptr;
}
VolumeDataPageAccessor *createVolumeDataPageAccessor(VolumeDataLayout *layout, DimensionsND dimension, int lod, int channel, int maxPages, Access access)
{
VolumeDataLayer* layer = getVolumeDataLayer(layout, dimension, channel, lod, true);
if (!layer) return NULL;
return new VolumeDataPageAccessorImpl(layer, maxPages, access == Access::Write);
}
}
......@@ -63,6 +63,11 @@ struct Error
std::string string;
};
enum class Access
{
Read = 1 << 0,
Write = 1 << 1
};
struct VDSHandle;
class VolumeDataLayout;
class VolumeDataPageAccessor;
......@@ -71,7 +76,7 @@ OPENVDS_EXPORT VDSHandle* open(const OpenOptions& options, Error &error);
OPENVDS_EXPORT VDSHandle* create(const OpenOptions& options, VolumeDataLayoutDescriptor const &layoutDescriptor, std::vector<VolumeDataAxisDescriptor> const &axisDescriptors, std::vector<VolumeDataChannelDescriptor> const &channelDescriptors, MetadataContainer const &metadataContainer, Error &error);
OPENVDS_EXPORT void destroy(VDSHandle *handle);
OPENVDS_EXPORT VolumeDataPageAccessor *createVolumeDataPageAccessor(VolumeDataLayout *layout, DimensionsND dimension, int lod, int channel, int maxPages);
OPENVDS_EXPORT VolumeDataPageAccessor *createVolumeDataPageAccessor(VolumeDataLayout *layout, DimensionsND dimension, int lod, int channel, int maxPages, Access access);
}
#endif //OPENVDS_H
......@@ -58,6 +58,8 @@ struct VDSHandle
std::unique_ptr<VolumeDataLayout>
volumeDataLayout;
std::vector<VolumeDataPageAccessor *>
pageAccessors;
};
}
......
......@@ -556,8 +556,6 @@ static bool parseProduceStatus(const std::string &json, VDSHandle &handle, Error
return false;
}
fprintf(stderr, "HELLO NEW WORLD!!!\n");
if (root.empty())
return true;
......
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
#include "VolumeDataPageAccessorImpl.h"
#include "VolumeDataLayer.h"
#include "VolumeDataPageImpl.h"
#include <IO/S3_Downloader.h>
namespace OpenVDS
{
static bool readChunkData(VDSHandle &handle, std::vector<uint8_t> &blob, int32_t (&pitch)[Dimensionality_Max])
{
blob.clear();
// This can probably be improved by looking up the data directly in the cache and not requesting it if it's valid,
// similar to the VolumeSamples code
for(auto &p : pitch)
p = 0;
return S3::downloadChunk(handle, blob, pitch);
}
VolumeDataPageAccessorImpl::VolumeDataPageAccessorImpl(VolumeDataLayer* layer, int maxPages, bool isReadWrite)
: m_layer(layer)
, m_maxPages(maxPages)
, m_isReadWrite(isReadWrite)
{
}
VolumeDataLayout const* VolumeDataPageAccessorImpl::getLayout() const
{
return m_layer->getLayout();
}
int VolumeDataPageAccessorImpl::getLod() const
{
return m_layer->getLod();
}
int VolumeDataPageAccessorImpl::getChannelIndex() const
{
return m_layer->getChannelIndex();
}
VolumeDataChannelDescriptor const& VolumeDataPageAccessorImpl::getChannelDescriptor() const
{
return m_layer->getVolumeDataChannelDescriptor();
}
void VolumeDataPageAccessorImpl::getNumSamples(int(&numSamples)[Dimensionality_Max]) const
{
for (int i = 0; i < Dimensionality_Max; i++)
{
numSamples[i] = m_layer->getDimensionNumSamples(i);
}
}
int64_t VolumeDataPageAccessorImpl::getChunkCount() const
{
return m_layer->getTotalChunkCount();
}
void VolumeDataPageAccessorImpl::getChunkMinMax(int64_t chunk, int(&min)[Dimensionality_Max], int(&max)[Dimensionality_Max]) const
{
m_layer->getChunkMinMax(chunk, min, max, true);
}
void VolumeDataPageAccessorImpl::getChunkMinMaxExcludingMargin(int64_t chunk, int(&min)[Dimensionality_Max], int(&max)[Dimensionality_Max]) const
{
m_layer->getChunkMinMax(chunk, min, max, false);
}
int64_t VolumeDataPageAccessorImpl::getChunkIndex(const int(&position)[Dimensionality_Max]) const
{
int32_t index_array[Dimensionality_Max];
for (int i = 0; i < Dimensionality_Max; i++)
{
index_array[i] = m_layer->voxelToIndex(position[i], i);
}
return m_layer->indexArrayToChunkIndex(index_array);
}
int VolumeDataPageAccessorImpl::addReference()
{
return ++m_references;
}
int VolumeDataPageAccessorImpl::removeReference()
{
return --m_references;
}
VolumeDataPage* VolumeDataPageAccessorImpl::readPageAtPosition(const int(&position)[Dimensionality_Max])
{
// std::lock_guard<std::mutex> pageMutexLocker(m_pagesMutex);
//
// if(!m_layer)
// {
// return NULL;
// }
//
// if (m_layer->getProduceStatus() == VolumeDataLayer::ProduceStatusUnavailable)
// {
// fprintf(stderr, "The accessed dimension group or channel is unavailable (check produce status on VDS before accessing data)");
// return nullptr;
// }
//
// int32_t indexArray[Dimensionality_Max];
//
// for(int32_t iDimension = 0; iDimension < Dimensionality_Max; iDimension++)
// {
// if(position[iDimension] < 0 || position[iDimension] >= m_layer->getDimensionNumSamples(iDimension))
// {
// return nullptr;
// }
// indexArray[iDimension] = m_layer->voxelToIndex(anPosition[iDimension], iDimension);
// }
//
// int64_t chunk = m_layer->indexArrayToChunkIndex(aiIndexArray);
//
// for(auto page_it = m_pages.begin(); page_it != m_pages.end(); ++page_it)
// {
// if(page_it->getChunkIndex() == chunk)
// {
// if (page_it !- m_pages.begin())
// {
// list.splice(m_pages.begin(), m_pages, page_it, std::next(page_it));
// }
// page_it->pin();
//
// while(page->isEmpty())
// {
// m_pageReadCondition.timedWait(1000);
//
// if(!m_volumeDataLayer)
// {
// page_it->unPin();
// return nullptr;
// }
// }
//
// m_pagesFound++;
// return *page_it;
// }
// }
//
// // Wait for commit to finish before inserting a new page
// while(m_isCommitInProgress)
// {
// m_commitFinishedCondition.TimedWait(1000);
// }
//
// if(!m_volumeDataLayer)
// {
// return nullptr;
// }
//
// // Not found, we need to create a new page
// VolumeDataPageImpl *page = new VolumeDataPageImpl(this, chunk);
//
// m_pages.push_front(page);
// m_currentPages++;
//
// assert(page->isPinned());
//
// std::vector<uint8_t> blob;
//
// int32_t pitch[Dimensionality_Max];
//
// Error error;
// if (!readChunkData(_pcHueVolumeDataLayer->GetChunkFromIndex(iChunk), &cHueBLOB, anPitch, error))
// {
// fprintf(stderr, "Failed to download chunk: %s\n", error.string.c_str());
// return nullptr;
// }
//
// pageMutexLocker = std::lock_guard<std::mutex>();
//
// HueJobStatus_e
// eHueJobStatus;
//
// // Run until job is complete (or cancelled)
// do
// {
// eHueJobStatus = HueJobIDList_c::StaticInstance().WaitForJob(iHueJobID, 10);
//
// if (eHueJobStatus == HUEJOBSTATUS_UNKNOWN && HueRootObj_c::StaticGetInstanceExists())
// {
// HueRootObj_c::StaticRun();
// }
// } while (eHueJobStatus == HUEJOBSTATUS_UNKNOWN);
//
// cPageListMutexLock.Lock(__FILE__, __LINE__);
//
// if (eHueJobStatus == HUEJOBSTATUS_COMPLETE)
// {
// HUEDEBUG_ASSERT(!cHueBLOB.IsEmpty());
// pcPage->SetBufferData(cHueBLOB, anPitch);
//
// _nPagesRead++;
// }
//
// _cPageReadCondition.Broadcast();
//
// if(!_pcHueVolumeDataLayer)
// {
// pcPage->UnPin();
// pcPage = NULL;
// }
//
// LimitPageListSize(_nMaxPages, cPageListMutexLock);
//
// return pcPage;
return nullptr;
}
void VolumeDataPageAccessorImpl::commit()
{
}
}
\ No newline at end of file
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
#ifndef VOLUMEDATAPAGEACCESSORIMPL_H
#define VOLUMEDATAPAGEACCESSORIMPL_H
#include "VolumeDataAccess.h"
#include <list>
#include <mutex>
namespace OpenVDS
{
class VolumeDataPageImpl;
class VolumeDataLayer;
class VolumeDataPageAccessorImpl : public VolumeDataPageAccessor
{
private:
VolumeDataLayer *m_layer;
int m_maxPages;
int m_references;
bool m_isReadWrite;
std::list<VolumeDataPageImpl *> m_pages;
std::mutex m_pagesMutex;
public:
VolumeDataPageAccessorImpl(VolumeDataLayer* layer, int maxPages, bool isReadWrite);
VolumeDataLayout const* getLayout() const override;
int getLod() const override;
int getChannelIndex() const override;
VolumeDataChannelDescriptor const& getChannelDescriptor() const override;
void getNumSamples(int(&numSamples)[Dimensionality_Max]) const override;
int64_t getChunkCount() const override;
void getChunkMinMax(int64_t chunk, int(&min)[Dimensionality_Max], int(&max)[Dimensionality_Max]) const override;
void getChunkMinMaxExcludingMargin(int64_t iChunk, int(&minExcludingMargin)[Dimensionality_Max], int(&maxExcludingMargin)[Dimensionality_Max]) const override;
int64_t getChunkIndex(const int(&position)[Dimensionality_Max]) const override;
int addReference() override;
int removeReference() override;
VolumeDataPage* readPageAtPosition(const int(&anPosition)[Dimensionality_Max]) override;
void commit() override;
};
}
#endif //VOLUMEDATAPAGEACCESSORIMPL_H
\ No newline at end of file
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
namespace OpenVDS
{
//VolumeDataPageImpl::VolumeDataPageImpl(VolumeDataPageAccessor* volumeDataPageAccessor, int64_t chunk)
// : m_volumeDataPageAccessor(volumeDataPageAccessor)
// , m_chunk(chunk)
// , m_blob()
// , m_pins(1)
// , m_buffer(nullptr)
// , m_isDirty(false)
// , m_chunksCopiedTo(0)
//{
// for (int32_t iDimension = 0; iDimension < Dimensionality_Max; iDimension++)
// {
// m_pitch[iDimension] = 0;
// m_writtenMin[iDimension] = 0;
// m_writtenMax[iDimension] = 0;
// }
//
// memset(m_copiedToChunkIndexes, 0, sizeof(m_copiedToChunkIndexes));
//}
}
\ No newline at end of file
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
#ifndef VOLUMEDATAPAGEIMPL_H
#define VOLUMEDATAPAGEIMPL_H
#include "VolumeDataPageAccessorImpl.h"
namespace OpenVDS
{
class VolumeDataPageImpl : public VolumeDataPage
{
private:
const VolumeDataPageAccessor * m_volumeDataPageAccessor;
int64_t m_chunk;
std::vector<uint8_t> m_blob;
int32_t _nPins;
void *m_buffer;
bool _isDirty;
int32_t m_pitch[Dimensionality_Max];
int32_t m_writtenMin[Dimensionality_Max];
int32_t m_writtenMax[Dimensionality_Max];
int64_t m_copiedToChunkIndexes[26];
int32_t m_chunksCopiedTo;
public:
VolumeDataPageImpl(VolumeDataPageImpl const &) = delete;
VolumeDataPageImpl(VolumeDataPageAccessor *volumeDataPageAccessor, int64_t chunk);
~VolumeDataPageImpl();
int64_t getChunkIndex() const { return m_chunk; }
// All these methods require the caller to hold a lock
bool IsPinned();
void Pin();
void UnPin();
bool IsEmpty();
bool IsDirty();
bool IsWritten();
void MakeDirty();
void SetBufferData(std::vector<uint8_t> const &blob, const int (&pitch)[Dimensionality_Max]);
//void WriteBack(VolumeDataLayer *volumeDataLayer, HueMutexLock_c &cPageListMutexLock);
void * GetBufferInternal(int (&anPitch)[Dimensionality_Max], bool isReadWrite);
bool IsCopyMarginNeeded(VolumeDataPage *targetPage);
void CopyMargin(VolumeDataPage *targetPage);
// Implementation of Hue::HueSpaceLib::VolumeDataPage interface, these methods aquire a lock (except the GetMinMax methods which don't need to)
void getMinMax(int (&min)[Dimensionality_Max], int (&max)[Dimensionality_Max]) const override;
void getMinMaxExcludingMargin(int (&minExcludingMargin)[Dimensionality_Max], int (&maxExcludingMargin)[Dimensionality_Max]) const override;
const void *getBuffer(int (&pitch)[Dimensionality_Max]) override; // Getting the buffer will block if the page is currently being read from the VolumeDataCache
void *getWritableBuffer(int (&pitch)[Dimensionality_Max]) override;
void updateWrittenRegion(const int (&writtenMin)[Dimensionality_Max], const int (&writtenMax)[Dimensionality_Max]) override;
void release() override;
};
}
#endif //VOLUMEDATAPAGEIMPL_H
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment