diff options
Diffstat (limited to 'pkg/blockchain/chainwriter/chainwriter.go')
-rw-r--r-- | pkg/blockchain/chainwriter/chainwriter.go | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/pkg/blockchain/chainwriter/chainwriter.go b/pkg/blockchain/chainwriter/chainwriter.go index 67a7d49..e1dd512 100644 --- a/pkg/blockchain/chainwriter/chainwriter.go +++ b/pkg/blockchain/chainwriter/chainwriter.go @@ -8,6 +8,7 @@ import ( "google.golang.org/protobuf/proto" "log" "os" + "strconv" ) // ChainWriter handles all I/O for the BlockChain. It stores and retrieves @@ -95,15 +96,66 @@ func (cw *ChainWriter) StoreBlock(bl *block.Block, undoBlock *UndoBlock, height // WriteBlock writes a serialized Block to Disk and returns // a FileInfo for storage information. func (cw *ChainWriter) WriteBlock(serializedBlock []byte) *FileInfo { - //TODO - return nil + // need to know the length of the block + length := uint32(len(serializedBlock)) + // if we don't have enough space for this block in the current file, + // we have to update our file by changing the current file number + // and resetting the start offset to zero (so we write at the beginning + // of the file again. + // (recall format from above: "data/block_0.txt") + if cw.CurrentBlockOffset+length >= cw.MaxBlockFileSize { + cw.CurrentBlockOffset = 0 + cw.CurrentBlockFileNumber++ + } + // create path to correct file, following format + // "DataDirectory/BlockFileName_CurrentBlockFileNumber.FileExtension" + // Ex: "data/block_0.txt" + fileName := cw.DataDirectory + "/" + cw.BlockFileName + "_" + strconv.Itoa(int(cw.CurrentBlockFileNumber)) + cw.FileExtension + // write serialized block to disk + writeToDisk(fileName, serializedBlock) + // create a file info object with the starting and ending offsets of the serialized block + fi := &FileInfo{ + FileName: fileName, + StartOffset: cw.CurrentBlockOffset, + EndOffset: cw.CurrentBlockOffset + length, + } + // update offset for next write + cw.CurrentBlockOffset += length + // return the file info + return fi } // WriteUndoBlock writes a serialized UndoBlock to Disk and returns // a FileInfo for storage information. func (cw *ChainWriter) WriteUndoBlock(serializedUndoBlock []byte) *FileInfo { - //TODO - return nil + // need to know the length of the block + length := uint32(len(serializedUndoBlock)) + // if we don't have enough space for this undo block in the current undo file, + // we have to update our undo file by changing the current undo file number + // and resetting the start undo offset to zero (so we write at the beginning + // of the undo file again. + // (recall format from above: "data/undo_0.txt") + if cw.CurrentUndoOffset+length >= cw.MaxUndoFileSize { + cw.CurrentUndoOffset = 0 + cw.CurrentUndoFileNumber++ + } + // create path to correct file, following format + // "DataDirectory/BlockFileName_CurrentBlockFileNumber.FileExtension" + // Ex: "data/undo_0.txt" + fileName := cw.DataDirectory + "/" + cw.UndoFileName + "_" + strconv.Itoa(int(cw.CurrentUndoFileNumber)) + cw.FileExtension + // write serialized undo block to disk + writeToDisk(fileName, serializedUndoBlock) + // create a file info object with the starting and ending undo offsets of the serialized + // undo block + fi := &FileInfo{ + FileName: fileName, + StartOffset: cw.CurrentUndoOffset, + EndOffset: cw.CurrentUndoOffset + length, + } + // update offset for next write + cw.CurrentUndoOffset += length + // return the file info + return fi } // ReadBlock returns a Block given a FileInfo. |