diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/DiskBuffer.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/DiskBuffer.h index 4dac5bcda1cc7d7fc60c8935c182363f692a747c..319ce47d32dcfdb1062c7499bf508b975122ee61 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/DiskBuffer.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/DiskBuffer.h @@ -94,6 +94,7 @@ namespace Kernel // For reporting and saving void getFreeSpaceVector(std::vector<uint64_t> & free) const; + void setFreeSpaceVector(std::vector<uint64_t> & free); std::string getMemoryStr() const; diff --git a/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp b/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp index a1685c661acb2778a196898584901669cfa070e0..aab35b1fc7be44bea9875c558e8c78bcaa511c86 100644 --- a/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp +++ b/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp @@ -415,6 +415,28 @@ namespace Kernel } } + /** Sets the free space map. Should only be used when loading a file. + * @param[in] free :: vector containing free space index to set */ + void DiskBuffer::setFreeSpaceVector(std::vector<uint64_t> & free) + { + m_free.clear(); + + if (free.size() % 2 != 0) + throw std::length_error("Free vector size is not a factor of 2."); + + for (std::vector<uint64_t>::iterator it = free.begin(); it != free.end(); it += 2) + { + std::vector<uint64_t>::iterator it_next = boost::next(it); + + if (*it == 0 && *it_next == 0) { + continue; // Not really a free space block! + } + + FreeBlock newBlock(*it, *it_next); + m_free.insert(newBlock); + } + } + /// @return a string describing the memory buffers, for debugging. std::string DiskBuffer::getMemoryStr() const { diff --git a/Code/Mantid/Framework/Kernel/test/DiskBufferTest.h b/Code/Mantid/Framework/Kernel/test/DiskBufferTest.h index 127116322965de195ce3360033f6130e6be400a4..8a5fb9bdefcdd6bd9c43cb2bd82a67a7faa6a922 100644 --- a/Code/Mantid/Framework/Kernel/test/DiskBufferTest.h +++ b/Code/Mantid/Framework/Kernel/test/DiskBufferTest.h @@ -525,6 +525,48 @@ public: TS_ASSERT_EQUALS( dbuf.allocate(55), 1000 ); TS_ASSERT_EQUALS( dbuf.getFileLength(), 1055 ); } + + //// Test for setting the DiskBuffer + void test_set_free_space_blocks() + { + DiskBuffer dbuf(0); + DiskBuffer::freeSpace_t &map = dbuf.getFreeSpaceMap(); + + uint64_t freeSpaceBlocksArray[] = {1,3,6,5}; + std::vector<uint64_t> freeSpaceBlocksVector(freeSpaceBlocksArray, freeSpaceBlocksArray + sizeof(freeSpaceBlocksArray) / sizeof(uint64_t)); + dbuf.setFreeSpaceVector(freeSpaceBlocksVector); + + TS_ASSERT_EQUALS(map.size(), 2); + + std::vector<uint64_t> assignedVector; + dbuf.getFreeSpaceVector(assignedVector); + TS_ASSERT_EQUALS(assignedVector, freeSpaceBlocksVector); + } + + //// Test for setting the DiskBuffer with an invalid vector + void test_set_free_space_blocks_with_odd_sized_vector_throws_exception() + { + DiskBuffer dbuf(0); + + uint64_t freeSpaceBlocksArray[] = {1,3,6}; + std::vector<uint64_t> freeSpaceBlocksVector(freeSpaceBlocksArray, freeSpaceBlocksArray + sizeof(freeSpaceBlocksArray) / sizeof(uint64_t)); + + TS_ASSERT_THROWS(dbuf.setFreeSpaceVector(freeSpaceBlocksVector), std::length_error); + } + + //// Test for setting the DiskBuffer with a zero sized vector + void test_set_free_space_blocks_with_zero_sized_vector() + { + DiskBuffer dbuf(0); + DiskBuffer::freeSpace_t &map = dbuf.getFreeSpaceMap(); + + std::vector<uint64_t> freeSpaceBlocksVector; + + dbuf.setFreeSpaceVector(freeSpaceBlocksVector); + + TS_ASSERT_EQUALS(map.size(), 0); + } + ////-------------------------------------------------------------------------------- ////-------------------------------------------------------------------------------- ////-------------------------------------------------------------------------------- @@ -878,5 +920,5 @@ public: }; - #endif /* MANTID_KERNEL_DISKBUFFERTEST_H_ */ + diff --git a/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp b/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp index 6757d18ea860c07d683889258a250f561760c1e1..49d76247cdb18432c3c60ef822266cca746814dc 100644 --- a/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp +++ b/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp @@ -281,7 +281,6 @@ namespace MDEvents /** Load free space blocks from the data file or create the NeXus place to read/write them*/ void BoxControllerNeXusIO::getDiskBufferFileData() { - std::vector<uint64_t> freeSpaceBlocks; this->getFreeSpaceVector(freeSpaceBlocks); if (freeSpaceBlocks.empty()) @@ -297,10 +296,9 @@ namespace MDEvents m_File->getEntries(groupEntries); if(groupEntries.find(g_DBDataName)!=groupEntries.end()) // data exist, open it { - if(!m_ReadOnly) - m_File->writeUpdatedData(g_DBDataName, freeSpaceBlocks, free_dims); - //else TODO: we are not currently able to read and set free space blocks into memory !!! - // m_File->readData("free_space_blocks",freeSpaceBlocks); + // Read the free space blocks in from the existing file + m_File->readData(g_DBDataName, freeSpaceBlocks); + this->setFreeSpaceVector(freeSpaceBlocks); } else // create and open the group { @@ -471,7 +469,7 @@ void BoxControllerNeXusIO::loadBlock(std::vector<double> & Block, const uint64_t std::vector<int64_t> free_dims(2,2); free_dims[0] = int64_t(freeSpaceBlocks.size()/2); - m_File->writeUpdatedData("free_space_blocks", freeSpaceBlocks, free_dims); + m_File->writeUpdatedData(g_DBDataName, freeSpaceBlocks, free_dims); } } diff --git a/Code/Mantid/Framework/MDEvents/test/BoxControllerNeXusIOTest.h b/Code/Mantid/Framework/MDEvents/test/BoxControllerNeXusIOTest.h index 99233da0bd7dcce14bc746d5d583cdaf0dc35c4b..4e514e0cc368790630ba6373b452ad85ee128a1a 100644 --- a/Code/Mantid/Framework/MDEvents/test/BoxControllerNeXusIOTest.h +++ b/Code/Mantid/Framework/MDEvents/test/BoxControllerNeXusIOTest.h @@ -109,6 +109,39 @@ void setUp() Poco::File(FullPathFile).remove(); } + void test_free_space_index_is_written_out_and_read_in() + { + MDEvents::BoxControllerNeXusIO *pSaver(NULL); + TS_ASSERT_THROWS_NOTHING(pSaver=new MDEvents::BoxControllerNeXusIO(sc.get())); + std::string FullPathFile; + + TS_ASSERT_THROWS_NOTHING(pSaver->openFile(this->xxfFileName,"w")); + TS_ASSERT_THROWS_NOTHING(FullPathFile = pSaver->getFileName()); + + std::vector<uint64_t> freeSpaceVectorToSet; + for (uint64_t i = 0; i < 20; i++) { + freeSpaceVectorToSet.push_back(i); + } + pSaver->setFreeSpaceVector(freeSpaceVectorToSet); + + TS_ASSERT_THROWS_NOTHING(pSaver->closeFile()); + + TS_ASSERT(!pSaver->isOpened()); + + TS_ASSERT_THROWS_NOTHING(pSaver->openFile(this->xxfFileName,"w")); + + std::vector<uint64_t> freeSpaceVectorToGet; + pSaver->getFreeSpaceVector(freeSpaceVectorToGet); + + TS_ASSERT_EQUALS(freeSpaceVectorToSet, freeSpaceVectorToGet); + + TS_ASSERT_THROWS_NOTHING(pSaver->closeFile()); + + delete pSaver; + if(Poco::File(FullPathFile).exists()) + Poco::File(FullPathFile).remove(); + } + //--------------------------------------------------------------------------------------------------------- // tests to read/write double/vs float events template<typename FROM,typename TO> @@ -205,4 +238,4 @@ void test_WriteFloatReadReadDouble() this->WriteReadRead<float,double>(); } }; -#endif \ No newline at end of file +#endif