mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
116 lines
2.5 KiB
C++
116 lines
2.5 KiB
C++
#include "ExtentIterator.h"
|
|
|
|
namespace
|
|
{
|
|
int64 roundUp(int64 numToRound, int64 multiple)
|
|
{
|
|
return ((numToRound + multiple - 1) / multiple) * multiple;
|
|
}
|
|
|
|
int64 roundDown(int64 numToRound, int64 multiple)
|
|
{
|
|
return ((numToRound / multiple) * multiple);
|
|
}
|
|
}
|
|
|
|
ExtentIterator::ExtentIterator(IFile * sparse_extents_f, bool take_file_ownership, int64 blocksize)
|
|
: sparse_extents_f(sparse_extents_f),
|
|
num_sparse_extents(-1),
|
|
next_sparse_extent_num(0),
|
|
take_file_ownership(take_file_ownership),
|
|
blocksize(blocksize)
|
|
{
|
|
if (sparse_extents_f != NULL)
|
|
{
|
|
sparse_extents_f->Seek(0);
|
|
}
|
|
}
|
|
|
|
ExtentIterator::~ExtentIterator()
|
|
{
|
|
if (!take_file_ownership)
|
|
{
|
|
sparse_extents_f.release();
|
|
}
|
|
}
|
|
|
|
IFsFile::SSparseExtent ExtentIterator::nextExtent()
|
|
{
|
|
if (num_sparse_extents == -1)
|
|
{
|
|
if (sparse_extents_f.get() == NULL
|
|
|| sparse_extents_f->Read(reinterpret_cast<char*>(&num_sparse_extents), sizeof(num_sparse_extents)) != sizeof(num_sparse_extents))
|
|
{
|
|
num_sparse_extents = 0;
|
|
}
|
|
}
|
|
|
|
IFsFile::SSparseExtent ret;
|
|
while (next_sparse_extent_num < num_sparse_extents
|
|
&& ret.offset==-1)
|
|
{
|
|
if (sparse_extents_f->Read(reinterpret_cast<char*>(&ret), sizeof(IFsFile::SSparseExtent)) != sizeof(IFsFile::SSparseExtent))
|
|
{
|
|
num_sparse_extents = 0;
|
|
return IFsFile::SSparseExtent();
|
|
}
|
|
else
|
|
{
|
|
++next_sparse_extent_num;
|
|
|
|
int64 ret_end = roundDown(ret.offset + ret.size, blocksize);
|
|
ret.offset = roundUp(ret.offset, blocksize);
|
|
|
|
if (ret.offset < ret_end)
|
|
{
|
|
ret.size = ret_end - ret.offset;
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
return IFsFile::SSparseExtent();
|
|
}
|
|
|
|
void ExtentIterator::reset()
|
|
{
|
|
num_sparse_extents = -1;
|
|
next_sparse_extent_num = 0;
|
|
if (sparse_extents_f.get() != NULL)
|
|
{
|
|
sparse_extents_f->Seek(0);
|
|
}
|
|
}
|
|
|
|
FsExtentIterator::FsExtentIterator(IFsFile * backing_file, int64 blocksize)
|
|
: backing_file(backing_file), blocksize(blocksize)
|
|
{
|
|
backing_file->resetSparseExtentIter();
|
|
}
|
|
|
|
IFsFile::SSparseExtent FsExtentIterator::nextExtent()
|
|
{
|
|
while (true)
|
|
{
|
|
IFsFile::SSparseExtent next = backing_file->nextSparseExtent();
|
|
|
|
if (next.offset == -1)
|
|
{
|
|
return next;
|
|
}
|
|
|
|
int64 next_end = roundDown(next.offset + next.size, blocksize);
|
|
next.offset = roundUp(next.offset, blocksize);
|
|
if (next.offset < next_end)
|
|
{
|
|
next.size = next_end - next.offset;
|
|
return next;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FsExtentIterator::reset()
|
|
{
|
|
backing_file->resetSparseExtentIter();
|
|
}
|