2015-04-18 14:47:12 +02:00
# include "NewBlock.h"
# include "CachingBlockStore.h"
2015-07-22 13:42:07 +02:00
# include <messmer/cpp-utils/assert/assert.h>
2015-04-18 14:47:12 +02:00
2015-04-25 02:48:41 +02:00
using cpputils : : Data ;
2015-07-21 14:50:52 +02:00
using boost : : none ;
2015-04-18 14:47:12 +02:00
namespace blockstore {
namespace caching {
NewBlock : : NewBlock ( const Key & key , Data data , CachingBlockStore * blockStore )
: Block ( key ) ,
_blockStore ( blockStore ) ,
_data ( std : : move ( data ) ) ,
2015-07-21 14:50:52 +02:00
_baseBlock ( none ) ,
2015-04-18 14:47:12 +02:00
_dataChanged ( true ) {
}
NewBlock : : ~ NewBlock ( ) {
writeToBaseBlockIfChanged ( ) ;
}
const void * NewBlock : : data ( ) const {
return _data . data ( ) ;
}
void NewBlock : : write ( const void * source , uint64_t offset , uint64_t size ) {
2015-07-22 13:42:07 +02:00
ASSERT ( offset < = _data . size ( ) & & offset + size < = _data . size ( ) , " Write outside of valid area " ) ;
2015-04-18 14:47:12 +02:00
std : : memcpy ( ( uint8_t * ) _data . data ( ) + offset , source , size ) ;
_dataChanged = true ;
}
void NewBlock : : writeToBaseBlockIfChanged ( ) {
if ( _dataChanged ) {
2015-07-21 14:50:52 +02:00
if ( _baseBlock = = none ) {
2015-04-18 14:47:12 +02:00
//TODO _data.copy() necessary?
2015-07-20 18:57:48 +02:00
auto newBase = _blockStore - > tryCreateInBaseStore ( key ( ) , _data . copy ( ) ) ;
2015-07-22 13:42:07 +02:00
ASSERT ( newBase ! = boost : : none , " Couldn't create base block " ) ; //TODO What if tryCreate fails due to a duplicate key? We should ensure we don't use duplicate keys.
2015-07-21 14:50:52 +02:00
_baseBlock = std : : move ( * newBase ) ;
2015-04-18 14:47:12 +02:00
} else {
2015-07-21 14:50:52 +02:00
( * _baseBlock ) - > write ( _data . data ( ) , 0 , _data . size ( ) ) ;
2015-04-18 14:47:12 +02:00
}
_dataChanged = false ;
}
}
void NewBlock : : remove ( ) {
2015-07-21 14:50:52 +02:00
if ( _baseBlock ! = none ) {
_blockStore - > removeFromBaseStore ( std : : move ( * _baseBlock ) ) ;
2015-04-18 14:47:12 +02:00
}
_dataChanged = false ;
}
void NewBlock : : flush ( ) {
writeToBaseBlockIfChanged ( ) ;
2015-07-22 13:42:07 +02:00
ASSERT ( _baseBlock ! = none , " At this point, the base block should already have been created but wasn't " ) ;
2015-07-21 14:50:52 +02:00
( * _baseBlock ) - > flush ( ) ;
2015-04-18 14:47:12 +02:00
}
size_t NewBlock : : size ( ) const {
return _data . size ( ) ;
}
bool NewBlock : : alreadyExistsInBaseStore ( ) const {
2015-07-21 14:50:52 +02:00
return _baseBlock ! = none ;
2015-04-18 14:47:12 +02:00
}
}
}