mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
re-wrote ftfileprovider / ftfilecreator to be more simple and robust.
re-wrote associated tests to be more robust. added new fttransfermoduletest.cc git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@760 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
26661ffb1c
commit
ef9bb372b4
@ -12,10 +12,10 @@ RSOBJ = ftdata.o ftfileprovider.o ftfilecreator.o ftextralist.o \
|
|||||||
ftcontroller.o pqitestor.o
|
ftcontroller.o pqitestor.o
|
||||||
|
|
||||||
|
|
||||||
TESTOBJ = ftfileprovidertest.o ftfilecreatortest.o ftextralisttest.o ftdataplextest.o ftserver1test.o ftserver2test.o
|
TESTOBJ = ftfileprovidertest.o ftfilecreatortest.o ftextralisttest.o ftdataplextest.o ftserver1test.o ftserver2test.o fttransfermoduletest.o
|
||||||
|
|
||||||
|
|
||||||
TESTS = ftfileprovidertest ftfilecreatortest ftextralisttest ftdataplextest ftserver1test ftserver2test
|
TESTS = ftfileprovidertest ftfilecreatortest ftextralisttest ftdataplextest ftserver1test ftserver2test fttransfermoduletest
|
||||||
|
|
||||||
all: librs tests
|
all: librs tests
|
||||||
|
|
||||||
@ -25,6 +25,9 @@ ftfilecreatortest : ftfilecreatortest.o
|
|||||||
ftfileprovidertest : ftfileprovidertest.o
|
ftfileprovidertest : ftfileprovidertest.o
|
||||||
$(CC) $(CFLAGS) -o ftfileprovidertest ftfileprovidertest.o $(LIBS)
|
$(CC) $(CFLAGS) -o ftfileprovidertest ftfileprovidertest.o $(LIBS)
|
||||||
|
|
||||||
|
fttransfermoduletest : fttransfermoduletest.o
|
||||||
|
$(CC) $(CFLAGS) -o fttransfermoduletest fttransfermoduletest.o $(LIBS)
|
||||||
|
|
||||||
ftextralisttest : ftextralisttest.o
|
ftextralisttest : ftextralisttest.o
|
||||||
$(CC) $(CFLAGS) -o ftextralisttest ftextralisttest.o $(LIBS)
|
$(CC) $(CFLAGS) -o ftextralisttest ftextralisttest.o $(LIBS)
|
||||||
|
|
||||||
|
@ -220,8 +220,7 @@ bool ftController::FileRequest(std::string fname, std::string hash,
|
|||||||
|
|
||||||
/* add in new item for download */
|
/* add in new item for download */
|
||||||
std::string savepath = mDownloadPath + "/" + fname;
|
std::string savepath = mDownloadPath + "/" + fname;
|
||||||
std::string chunker = "default";
|
ftFileCreator *fc = new ftFileCreator(savepath, size, hash, 0);
|
||||||
ftFileCreator *fc = new ftFileCreator(savepath, size, hash, chunker);
|
|
||||||
ftTransferModule *tm = new ftTransferModule(fc, mDataplex,this);
|
ftTransferModule *tm = new ftTransferModule(fc, mDataplex,this);
|
||||||
|
|
||||||
/* add into maps */
|
/* add into maps */
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#define FILE_DEBUG 1
|
#define FILE_DEBUG 1
|
||||||
|
|
||||||
|
#define CHUNK_MAX_AGE 30
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
*
|
*
|
||||||
* ftFileCreator methods
|
* ftFileCreator methods
|
||||||
@ -9,7 +12,7 @@
|
|||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
||||||
ftFileCreator::ftFileCreator(std::string path, uint64_t size, std::string
|
ftFileCreator::ftFileCreator(std::string path, uint64_t size, std::string
|
||||||
hash, std::string chunker): ftFileProvider(path,size,hash)
|
hash, uint64_t recvd): ftFileProvider(path,size,hash)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FIXME any inits to do?
|
* FIXME any inits to do?
|
||||||
@ -26,65 +29,29 @@ hash, std::string chunker): ftFileProvider(path,size,hash)
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initialize(chunker);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ftFileCreator::initialize(std::string chunker)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
if (chunker == "default")
|
/* initialise the Transfer Lists */
|
||||||
fileChunker = new ftFileChunker(total_size);
|
mStart = recvd;
|
||||||
else
|
mEnd = recvd;
|
||||||
fileChunker = new ftFileRandomizeChunker(total_size);
|
|
||||||
|
|
||||||
fileChunker->splitFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ftFileCreator::initializeFileAttrs()
|
bool ftFileCreator::getFileData(uint64_t offset,
|
||||||
|
uint32_t chunk_size, void *data)
|
||||||
{
|
{
|
||||||
//RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
if (offset + chunk_size > mStart)
|
||||||
/*
|
|
||||||
* check if the file exists
|
|
||||||
*/
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileCreator::initializeFileAttrs() Filename: " << file_name;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* attempt to open file in writing mode
|
|
||||||
*/
|
|
||||||
|
|
||||||
fd = fopen(file_name.c_str(), "w+b");
|
|
||||||
if (!fd)
|
|
||||||
{
|
{
|
||||||
#ifdef FILE_DEBUG
|
/* don't have the data */
|
||||||
std::cerr << "ftFileCreator::initializeFileAttrs() Failed to open (w+b): " << file_name << std::endl;
|
return false;
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return ftFileProvider::getFileData(offset, chunk_size, data);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
uint64_t ftFileCreator::getRecvd()
|
||||||
* if it opened, find it's length
|
{
|
||||||
* move to the end
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
*/
|
return mStart;
|
||||||
if (0 != fseek(fd, 0L, SEEK_END))
|
|
||||||
{
|
|
||||||
std::cerr << "ftFileCreator::initializeFileAttrs() Seek Failed" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* get the file length
|
|
||||||
*/
|
|
||||||
recv_size = ftell(fd);
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileCreator::initializeFileAttrs() recv_size: " << recv_size << std::endl;
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data)
|
bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data)
|
||||||
@ -96,28 +63,22 @@ bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data
|
|||||||
std::cerr << ", " << data << ")";
|
std::cerr << ", " << data << ")";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
/* dodgey checking outside of mutex...
|
||||||
/* check the status */
|
* much check again inside FileAttrs().
|
||||||
|
*/
|
||||||
|
/* Check File is open */
|
||||||
|
if (fd == NULL)
|
||||||
|
if (!initializeFileAttrs())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (fd==NULL)
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
{
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileCreator::addFileData() initialising";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
int init = initializeFileAttrs();
|
|
||||||
if (init ==0) {
|
|
||||||
std::cerr <<"Initialization Failed" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check its at the correct location
|
* check its at the correct location
|
||||||
*/
|
*/
|
||||||
if (offset + chunk_size > this->total_size)
|
if (offset + chunk_size > mSize)
|
||||||
{
|
{
|
||||||
chunk_size = total_size - offset;
|
chunk_size = mSize - offset;
|
||||||
std::cerr <<"Chunk Size greater than total file size, adjusting chunk " << "size " << chunk_size << std::endl;
|
std::cerr <<"Chunk Size greater than total file size, adjusting chunk " << "size " << chunk_size << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -133,8 +94,6 @@ bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data
|
|||||||
|
|
||||||
long int pos;
|
long int pos;
|
||||||
pos = ftell(fd);
|
pos = ftell(fd);
|
||||||
std::cerr << pos << " BEFORE RECV SIZE "<< recv_size << std::endl;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add the data
|
* add the data
|
||||||
*/
|
*/
|
||||||
@ -144,21 +103,18 @@ bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->recv_size += chunk_size;
|
|
||||||
|
|
||||||
pos = ftell(fd);
|
pos = ftell(fd);
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
#ifdef FILE_DEBUG
|
||||||
std::cerr << "ftFileCreator::addFileData() added Data...";
|
std::cerr << "ftFileCreator::addFileData() added Data...";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "recvd: " << recv_size;
|
|
||||||
std::cerr << " pos: " << pos;
|
std::cerr << " pos: " << pos;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Notify ftFileChunker about chunks received
|
* Notify ftFileChunker about chunks received
|
||||||
*/
|
*/
|
||||||
fileChunker->notifyReceived(offset,chunk_size);
|
notifyReceived(offset,chunk_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME HANDLE COMPLETION HERE - Any better way?
|
* FIXME HANDLE COMPLETION HERE - Any better way?
|
||||||
@ -167,6 +123,60 @@ bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ftFileCreator::initializeFileAttrs()
|
||||||
|
{
|
||||||
|
std::cerr << "ftFileCreator::initializeFileAttrs() Filename: ";
|
||||||
|
std::cerr << file_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check if the file exists
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ftFileProvider::initializeFileAttrs())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
if (fd)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::cout <<
|
||||||
|
"ftFileCreator::initializeFileAttrs() Filename: " << file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attempt to open file
|
||||||
|
*/
|
||||||
|
|
||||||
|
fd = fopen(file_name.c_str(), "w+b");
|
||||||
|
if (!fd)
|
||||||
|
{
|
||||||
|
std::cout <<
|
||||||
|
"ftFileCreator::initializeFileAttrs() Failed to open (w+b): "<< file_name << std::endl;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if it opened, find it's length
|
||||||
|
* move to the end
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (0 != fseek(fd, 0L, SEEK_END))
|
||||||
|
{
|
||||||
|
std::cerr << "ftFileCreator::initializeFileAttrs() Seek Failed" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t recvdsize = ftell(fd);
|
||||||
|
|
||||||
|
std::cerr << "ftFileCreator::initializeFileAttrs() File Expected Size: " << mSize << " RecvdSize: " << recvdsize << std::endl;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
ftFileCreator::~ftFileCreator()
|
ftFileCreator::~ftFileCreator()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -175,546 +185,104 @@ ftFileCreator::~ftFileCreator()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ftFileCreator::getMissingChunk(uint64_t &offset, uint32_t &chunk)
|
int ftFileCreator::notifyReceived(uint64_t offset, uint32_t chunk_size)
|
||||||
{
|
{
|
||||||
#ifdef FILE_DEBUG
|
/* ALREADY LOCKED */
|
||||||
std::cerr << "ftFileCreator::getMissingChunk(???," << chunk << ")";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
return fileChunker->getMissingChunk(offset, chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
/* find the chunk */
|
||||||
*
|
std::map<uint64_t, ftChunk>::iterator it;
|
||||||
* ftFileChunker methods
|
it = mChunks.find(offset);
|
||||||
*
|
if (it == mChunks.end())
|
||||||
***********************************************************/
|
|
||||||
|
|
||||||
ftFileChunker::ftFileChunker(uint64_t size): file_size(size), std_chunk_size(10000), monitorPeriod(30)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* srand for randomized version - move it to the sub-class?
|
|
||||||
*/
|
|
||||||
srand ( time(NULL) );
|
|
||||||
aggregate_status = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ftFileChunker::~ftFileChunker()
|
|
||||||
{
|
|
||||||
std::vector<ftChunk>::iterator it;
|
|
||||||
for(unsigned int i=0; i<allocationTable.size();i++) {
|
|
||||||
delete allocationTable.at(i); /* Does this need a check? */
|
|
||||||
}
|
|
||||||
if(!allocationTable.empty()){
|
|
||||||
allocationTable.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ftFileChunker::splitFile(){
|
|
||||||
RsStackMutex stack(chunkerMutex); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* all in bytes
|
|
||||||
*/
|
|
||||||
num_chunks = file_size/std_chunk_size;
|
|
||||||
/*
|
|
||||||
* FIXME - Remainder should go into last chunk
|
|
||||||
*/
|
|
||||||
uint64_t rem = file_size % std_chunk_size;
|
|
||||||
unsigned int index=0;
|
|
||||||
uint64_t max_chunk_size = file_size - (index * std_chunk_size);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker::splitFile()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tfile_size: " << file_size;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tstd_chunk_size: " << std_chunk_size;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tnum_chunks: " << num_chunks;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\trem: " << rem;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tmax_chunk_size: " << max_chunk_size;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
time_t now = time(NULL);
|
|
||||||
for(index=0;index<num_chunks;index++)
|
|
||||||
{
|
{
|
||||||
uint64_t offset = index * std_chunk_size;
|
return 0; /* ignoring */
|
||||||
max_chunk_size = file_size - (index * std_chunk_size);
|
|
||||||
ftChunk *f = new ftChunk(offset,max_chunk_size,now, ftChunk::AVAIL);
|
|
||||||
allocationTable.push_back(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rem != 0)
|
ftChunk chunk = it->second;
|
||||||
|
mChunks.erase(it);
|
||||||
|
|
||||||
|
if (chunk.chunk != chunk_size)
|
||||||
{
|
{
|
||||||
ftChunk *f = new ftChunk(file_size-rem,rem,now, ftChunk::AVAIL);
|
/* partial : shrink chunk */
|
||||||
allocationTable.push_back(f);
|
chunk.chunk -= chunk_size;
|
||||||
num_chunks++;
|
chunk.offset += chunk_size;
|
||||||
|
mChunks[chunk.offset] = chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* if we've cleaned up chunks, must update counters */
|
||||||
* DEBUGGER
|
it = mChunks.find(chunk.offset);
|
||||||
* for(int j=0;j<allocationTable.size();j++)
|
if (it == mChunks.end())
|
||||||
* {
|
{
|
||||||
* std::cout << "SIZE " << allocationTable.at(j)->max_chunk_size << " " << allocationTable.at(j)->chunk_status << std::endl;
|
mStart = mEnd;
|
||||||
* }
|
}
|
||||||
*/
|
else if (it == mChunks.begin())
|
||||||
|
{
|
||||||
|
mStart += it->second.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
bool ftFileCreator::getMissingChunk(uint64_t &offset, uint32_t &chunk)
|
||||||
* This method sets the offset, chunk may be reset if needed
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool ftFileChunker::getMissingChunk(uint64_t &offset, uint32_t &chunk)
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(chunkerMutex); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
std::cerr << "ffc::getMissingChunk(...,"<< chunk << ")"<< std::endl;
|
||||||
|
|
||||||
unsigned int i =0;
|
/* check start point */
|
||||||
bool found = false;
|
|
||||||
int chunks_after = 0;
|
|
||||||
int chunks_rem = 0;
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
if (mStart == mSize)
|
||||||
std::cerr << "ftFileChunker::getMissingChunk(???," << chunk << ")";
|
{
|
||||||
|
std::cerr << "ffc::getMissingChunk() File Done";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for freed chunks */
|
||||||
|
time_t ts = time(NULL);
|
||||||
|
time_t old = ts-CHUNK_MAX_AGE;
|
||||||
|
|
||||||
|
std::map<uint64_t, ftChunk>::iterator it;
|
||||||
|
for(it = mChunks.begin(); it != mChunks.end(); it++)
|
||||||
|
{
|
||||||
|
/* very simple algorithm */
|
||||||
|
if (it->second.ts < old)
|
||||||
|
{
|
||||||
|
std::cerr << "ffc::getMissingChunk() ReAlloc";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
/* retry this one */
|
||||||
|
it->second.ts = ts;
|
||||||
|
chunk = it->second.chunk;
|
||||||
|
offset = it->second.offset;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "ffc::getMissingChunk() new Alloc";
|
||||||
|
std::cerr << " mStart: " << mStart << " mEnd: " << mEnd;
|
||||||
|
std::cerr << "mSize: " << mSize;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/* else allocate a new chunk */
|
||||||
* This signals file completion
|
if (mSize - mEnd < chunk)
|
||||||
* FIXME Does it need to be more explicit
|
chunk = mSize - mEnd;
|
||||||
*/
|
|
||||||
|
|
||||||
if(aggregate_status == num_chunks * ftChunk::RECEIVED)
|
offset = mEnd;
|
||||||
{
|
mEnd += chunk;
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "completed ??";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mChunks[offset] = ftChunk(offset, chunk, ts);
|
||||||
while(i<allocationTable.size())
|
return true;
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker checking allocTable(" << i << ")";
|
|
||||||
std::cerr << " of " << allocationTable.size();
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(allocationTable.at(i)->max_chunk_size >=chunk)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker pre alloc(" << i << ")";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\toffset: " << allocationTable.at(i)->offset;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tmax_chunk: " << allocationTable.at(i)->max_chunk_size;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\treq_chunk: " << chunk;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
offset = allocationTable.at(i)->offset;
|
|
||||||
chunks_after = chunk/std_chunk_size; //10KB
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME Handling remaining chunk < 10KB
|
|
||||||
*/
|
|
||||||
|
|
||||||
//if (chunk <
|
|
||||||
chunks_rem = chunk % std_chunk_size;
|
|
||||||
chunk -= chunks_rem;
|
|
||||||
/*std::cout << "Found " << chunk << " at " << i << " "<< chunks_after << std::endl;*/
|
|
||||||
allocationTable.at(i)->max_chunk_size=0;
|
|
||||||
allocationTable.at(i)->timestamp = time(NULL);
|
|
||||||
allocationTable.at(i)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker postalloc(" << i << ")";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tchunks_after: " << chunks_after;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tchunks_rem: " << chunks_after;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\tchunk: " << chunks_after;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we get here, there is no available chunk bigger
|
|
||||||
* than requested ...
|
|
||||||
* NB: Request size should be a larger than std_chunk_size.
|
|
||||||
* So Edge (sub chunk allocation) condition is handled here.
|
|
||||||
*
|
|
||||||
* Find largest remaining chunk.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker::getMissingChuck() FULL CHUNK not found";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
i=0;
|
|
||||||
uint64_t max = allocationTable.at(i)->max_chunk_size;
|
|
||||||
uint64_t size = max;
|
|
||||||
int maxi = -1;
|
|
||||||
if (max > 0)
|
|
||||||
{
|
|
||||||
maxi = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(i<allocationTable.size())
|
|
||||||
{
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "Checking(" << i << ") " <<
|
|
||||||
allocationTable.at(i)->max_chunk_size;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
size = allocationTable.at(i)->max_chunk_size;
|
|
||||||
if(size > max)
|
|
||||||
{
|
|
||||||
max = allocationTable.at(i)->max_chunk_size;
|
|
||||||
maxi = i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (maxi > -1) //maxi or max
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "Biggest Avail Chunk: " << max;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
offset = allocationTable.at(maxi)->offset;
|
|
||||||
chunk = allocationTable.at(maxi)->max_chunk_size;
|
|
||||||
chunks_after = chunk/std_chunk_size; //10KB
|
|
||||||
|
|
||||||
/* Handle end condition ...
|
|
||||||
* max_chunk_size < std_chunk_size
|
|
||||||
* Trim if not end condition.
|
|
||||||
*/
|
|
||||||
if (chunks_after > 0)
|
|
||||||
{
|
|
||||||
chunks_rem = chunk % std_chunk_size;
|
|
||||||
chunk -= chunks_rem;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* end condition */
|
|
||||||
chunks_after = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocationTable.at(maxi)->max_chunk_size=0;
|
|
||||||
allocationTable.at(maxi)->timestamp = time(NULL);
|
|
||||||
allocationTable.at(maxi)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
found = true;
|
|
||||||
i = maxi;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //if not found
|
|
||||||
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
// i represents index to chunk(s) we will use.
|
|
||||||
// chunks_after is the count of how many we will use.
|
|
||||||
|
|
||||||
std::cout << "Chunks remaining " << chunks_rem << std::endl;
|
|
||||||
/*
|
|
||||||
* update all previous chunks max available size
|
|
||||||
* Expensive? Can it be smarter FIXME
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* drbob: Think this is wrong?
|
|
||||||
* disabling...
|
|
||||||
*
|
|
||||||
for(unsigned int j=0;j<i;j++)
|
|
||||||
{
|
|
||||||
if (allocationTable.at(j)->max_chunk_size >0)
|
|
||||||
allocationTable.at(j)->max_chunk_size -= chunk;
|
|
||||||
}
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
for(unsigned int j=i;j<i+chunks_after;j++)
|
|
||||||
{
|
|
||||||
allocationTable.at(j)->max_chunk_size = 0;
|
|
||||||
allocationTable.at(j)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUGGER - Uncomment
|
|
||||||
for(unsigned int j=0;j<allocationTable.size();j++)
|
|
||||||
{
|
|
||||||
std::cout << "After allocation " << allocationTable.at(j)->max_chunk_size << " " << allocationTable.at(j)->chunk_status << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunker::getMissingChuck() not found";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This should run on a separate thread when ftFileChunker is initialized
|
|
||||||
* FIXME Implemet DrBob's suggestion of request-fired check instead of dedicated
|
|
||||||
* thread
|
|
||||||
*/
|
|
||||||
int ftFileChunker::monitor()
|
|
||||||
{
|
|
||||||
int reset = 0;
|
|
||||||
uint32_t prev_size = 0;
|
|
||||||
uint32_t size = 0;
|
|
||||||
|
|
||||||
std::cout<<"Running monitor.."<<std::endl;
|
|
||||||
|
|
||||||
RsStackMutex stack(chunkerMutex); /********** STACK LOCKED MTX ******/
|
|
||||||
for(unsigned int j=allocationTable.size()-1 ;j>= 0;)
|
|
||||||
{
|
|
||||||
if((allocationTable.at(j)->chunk_status == ftChunk::ALLOCATED) &&
|
|
||||||
(allocationTable.at(j)->timestamp - time(NULL) > 30))
|
|
||||||
{
|
|
||||||
allocationTable.at(j)->chunk_status = ftChunk::AVAIL;
|
|
||||||
if (j == allocationTable.size()-1)
|
|
||||||
{
|
|
||||||
/* at end */
|
|
||||||
prev_size = 0;
|
|
||||||
size = file_size % std_chunk_size;
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
size = std_chunk_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev_size = allocationTable.at(j+1)->max_chunk_size;
|
|
||||||
size = std_chunk_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocationTable.at(j)->max_chunk_size = size + prev_size;
|
|
||||||
prev_size = allocationTable.at(j)->max_chunk_size;
|
|
||||||
|
|
||||||
for(j--; j >= 0; j--)
|
|
||||||
{
|
|
||||||
if (allocationTable.at(j)->chunk_status != ftChunk::AVAIL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
allocationTable.at(j)->max_chunk_size += prev_size;
|
|
||||||
prev_size = allocationTable.at(j)->max_chunk_size;
|
|
||||||
reset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ftFileChunker::setMonitorPeriod(int period)
|
|
||||||
{
|
|
||||||
monitorPeriod = period;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ftFileChunker::run()
|
|
||||||
{
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
|
|
||||||
for(int i = 0; i < monitorPeriod; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
/******************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
#ifndef WINDOWS_SYS
|
|
||||||
sleep(1);
|
|
||||||
#else
|
|
||||||
|
|
||||||
Sleep(1000);
|
|
||||||
#endif
|
|
||||||
/******************* WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
}
|
|
||||||
monitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int ftFileChunker::notifyReceived(uint64_t offset, uint32_t chunk_size)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(chunkerMutex); /********** STACK LOCKED MTX ******/
|
|
||||||
int index = offset / std_chunk_size;
|
|
||||||
|
|
||||||
/* should receive a multiple of chunk_size.... */
|
|
||||||
uint32_t chunks = chunk_size / std_chunk_size;
|
|
||||||
uint32_t rem_chunk = chunk_size % std_chunk_size;
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunkerr::notifyReceived(";
|
|
||||||
std::cerr << offset;
|
|
||||||
std::cerr << ", " << chunk_size << ")";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\t# complete chunks: " << chunks;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "\trem_chunk: " << rem_chunk;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(allocationTable.at(index)->chunk_status == ftChunk::ALLOCATED){
|
|
||||||
allocationTable.at(index)->chunk_status = ftChunk::RECEIVED;
|
|
||||||
aggregate_status += ftChunk::RECEIVED;
|
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
|
||||||
std::cerr << "ftFileChunkerr::notifyReceived()";
|
|
||||||
std::cerr << " flagged as RECVD";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
return aggregate_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
*
|
|
||||||
* ftFileRandomizeChunker methods
|
|
||||||
*
|
|
||||||
***********************************************************/
|
|
||||||
|
|
||||||
ftFileRandomizeChunker::ftFileRandomizeChunker(uint64_t size):
|
|
||||||
ftFileChunker(size)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ftFileRandomizeChunker::~ftFileRandomizeChunker()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ftFileRandomizeChunker::getMissingChunk(uint64_t &offset, uint32_t &chunk) {
|
|
||||||
|
|
||||||
RsStackMutex stack(chunkerMutex); /********** STACK LOCKED MTX ******/
|
|
||||||
std::cerr << "Calling getMissingChunk with chunk="<< chunk << std::endl;
|
|
||||||
unsigned int i =0;
|
|
||||||
bool found = false;
|
|
||||||
int chunks_after = 0;
|
|
||||||
int chunks_rem = 0;
|
|
||||||
|
|
||||||
if(aggregate_status == num_chunks * ftChunk::RECEIVED)
|
|
||||||
return found;
|
|
||||||
|
|
||||||
std::vector<int> randomIndex;
|
|
||||||
while(i<allocationTable.size())
|
|
||||||
{
|
|
||||||
if(allocationTable.at(i)->max_chunk_size >=chunk){
|
|
||||||
randomIndex.push_back(i);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME test sufficiently to make sure its picking every index
|
|
||||||
*/
|
|
||||||
if (randomIndex.size()>0)
|
|
||||||
{
|
|
||||||
int rnum = rand() % randomIndex.size();
|
|
||||||
i = randomIndex.at(rnum);
|
|
||||||
std::cout << "i=" <<i << " rnum " << rnum << std::endl;
|
|
||||||
offset = allocationTable.at(i)->offset;
|
|
||||||
chunks_after = chunk/std_chunk_size; //10KB
|
|
||||||
chunks_rem = chunk % std_chunk_size;
|
|
||||||
chunk -= chunks_rem;
|
|
||||||
std::cout << "Found " << chunk << " at index =" << i << " "<< chunks_after << std::endl;
|
|
||||||
allocationTable.at(i)->max_chunk_size=0;
|
|
||||||
allocationTable.at(i)->timestamp = time(NULL);
|
|
||||||
allocationTable.at(i)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
i=0;
|
|
||||||
uint64_t min = allocationTable.at(i)->max_chunk_size - chunk;
|
|
||||||
uint64_t diff = min;
|
|
||||||
int mini = -1;
|
|
||||||
while(i<allocationTable.size())
|
|
||||||
{
|
|
||||||
diff = allocationTable.at(i)->max_chunk_size-chunk;
|
|
||||||
if(diff <= min && diff >0)
|
|
||||||
{
|
|
||||||
min = allocationTable.at(i)->max_chunk_size - chunk;
|
|
||||||
mini = i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (mini > -1)
|
|
||||||
{
|
|
||||||
offset = allocationTable.at(mini)->offset;
|
|
||||||
chunk = allocationTable.at(mini)->max_chunk_size;
|
|
||||||
chunks_after = chunk/std_chunk_size; //10KB
|
|
||||||
chunks_rem = chunk % std_chunk_size;
|
|
||||||
chunk -= chunks_rem;
|
|
||||||
allocationTable.at(mini)->max_chunk_size=0;
|
|
||||||
allocationTable.at(mini)->timestamp = time(NULL);
|
|
||||||
allocationTable.at(mini)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //if not found
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
// update all previous chunks max available size
|
|
||||||
for(unsigned int j=0;j<i;j++)
|
|
||||||
{
|
|
||||||
if (allocationTable.at(j)->max_chunk_size >0)
|
|
||||||
allocationTable.at(j)->max_chunk_size -= chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int j=i;j<i+chunks_after;j++)
|
|
||||||
{
|
|
||||||
allocationTable.at(j)->max_chunk_size = 0;
|
|
||||||
allocationTable.at(j)->chunk_status = ftChunk::ALLOCATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for(int j=0;j<allocationTable.size();j++){
|
|
||||||
std::cout << "After allocation " << j << " " << allocationTable.at(j)->max_chunk_size << " " << allocationTable.at(j)->chunk_status << std::endl;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
*
|
*
|
||||||
* ftChunk methods
|
* ftChunk methods
|
||||||
*
|
*
|
||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
||||||
ftChunk::ftChunk(uint64_t offset,uint64_t chunk_size,time_t time, ftChunk::Status s) : offset(offset), max_chunk_size(chunk_size), timestamp(time), chunk_status(s)
|
ftChunk::ftChunk(uint64_t ioffset,uint64_t size,time_t now)
|
||||||
|
: offset(ioffset), chunk(size), ts(now)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -723,3 +291,4 @@ ftChunk::~ftChunk()
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,100 +33,56 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "ftfileprovider.h"
|
#include "ftfileprovider.h"
|
||||||
#include "util/rsthreads.h"
|
#include <map>
|
||||||
#include <queue>
|
|
||||||
class ftChunk;
|
class ftChunk;
|
||||||
class ftFileChunker;
|
|
||||||
|
|
||||||
class ftFileCreator: public ftFileProvider
|
class ftFileCreator: public ftFileProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ftFileCreator(std::string savepath, uint64_t size, std::string hash,std::string chunker);
|
ftFileCreator(std::string savepath, uint64_t size, std::string hash, uint64_t recvd);
|
||||||
|
|
||||||
~ftFileCreator();
|
~ftFileCreator();
|
||||||
|
|
||||||
/*
|
/* overloaded from FileProvider */
|
||||||
* overloaded from FileProvider FIXME
|
virtual bool getFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||||
* virtual bool getFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
uint64_t getRecvd();
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: initializeFileAttrs
|
|
||||||
* Should this be a over-ridden version of ftfile provider?
|
|
||||||
* What happens in the case of simultaneous upload and download?
|
|
||||||
*/
|
|
||||||
|
|
||||||
int initializeFileAttrs();
|
|
||||||
/*
|
/*
|
||||||
* creation functions for FileCreator
|
* creation functions for FileCreator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool getMissingChunk(uint64_t &offset, uint32_t &chunk);
|
bool getMissingChunk(uint64_t &offset, uint32_t &chunk);
|
||||||
bool addFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
bool addFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual int initializeFileAttrs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
int notifyReceived(uint64_t offset, uint32_t chunk_size);
|
||||||
/*
|
/*
|
||||||
* structure to track missing chunks
|
* structure to track missing chunks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint64_t recv_size;
|
uint64_t mStart;
|
||||||
std::string hash;
|
uint64_t mEnd;
|
||||||
ftFileChunker *fileChunker;
|
|
||||||
void initialize(std::string);
|
|
||||||
RsMutex ftcMutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
std::map<uint64_t, ftChunk> mChunks;
|
||||||
This class can either be specialized to follow a different splitting
|
|
||||||
policy or have an argument to indicate different policies
|
|
||||||
*/
|
|
||||||
class ftFileChunker : public RsThread {
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
* FIXME Does filechunker require hash??
|
|
||||||
*/
|
|
||||||
ftFileChunker(uint64_t size);
|
|
||||||
virtual ~ftFileChunker();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Breaks up the file into evenly sized chunks
|
|
||||||
* Initializes all chunks to never_requested
|
|
||||||
*/
|
|
||||||
int splitFile();
|
|
||||||
virtual void run();
|
|
||||||
virtual bool getMissingChunk(uint64_t &offset, uint32_t &chunk);
|
|
||||||
bool getMissingChunkRandom(uint64_t &offset, uint32_t &chunk);
|
|
||||||
int notifyReceived(uint64_t offset, uint32_t chunk_size);
|
|
||||||
int monitor();
|
|
||||||
void setMonitorPeriod(int period);
|
|
||||||
protected:
|
|
||||||
uint64_t file_size;
|
|
||||||
uint64_t num_chunks;
|
|
||||||
uint64_t std_chunk_size;
|
|
||||||
std::vector<ftChunk*> allocationTable;
|
|
||||||
unsigned int aggregate_status;
|
|
||||||
int monitorPeriod;
|
|
||||||
RsMutex chunkerMutex; /********** STACK LOCKED MTX ******/
|
|
||||||
};
|
|
||||||
|
|
||||||
class ftFileRandomizeChunker : public ftFileChunker {
|
|
||||||
public:
|
|
||||||
ftFileRandomizeChunker(uint64_t size);
|
|
||||||
virtual bool getMissingChunk(uint64_t &offset, uint32_t &chunk);
|
|
||||||
~ftFileRandomizeChunker();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ftChunk {
|
class ftChunk {
|
||||||
public:
|
public:
|
||||||
enum Status {AVAIL, ALLOCATED, RECEIVED};
|
ftChunk(uint64_t,uint64_t,time_t);
|
||||||
ftChunk(uint64_t,uint64_t,time_t,Status);
|
ftChunk():offset(0), chunk(0), ts(0) {}
|
||||||
uint64_t offset;
|
|
||||||
uint64_t max_chunk_size;
|
|
||||||
time_t timestamp;
|
|
||||||
Status chunk_status;
|
|
||||||
~ftChunk();
|
~ftChunk();
|
||||||
|
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t chunk;
|
||||||
|
time_t ts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FT_FILE_PROVIDER_HEADER
|
#endif // FT_FILE_CREATOR_HEADER
|
||||||
|
@ -1,87 +1,89 @@
|
|||||||
#include "ftfilecreator.h"
|
#include "ftfilecreator.h"
|
||||||
|
|
||||||
main(){
|
#include "util/utest.h"
|
||||||
uint64_t offset;
|
|
||||||
uint32_t csize;
|
|
||||||
/*Test file creator*/
|
|
||||||
ftFileCreator fcreator("somefile",100000,"hash","default");
|
|
||||||
csize = 40000;
|
|
||||||
if (fcreator.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Missing Chunk's offset=" << offset << " chunk_size=" << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
csize = 10000;
|
INITTEST();
|
||||||
if (fcreator.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Missing Chunk's offset=" << offset << " chunk_size=" << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
csize = 15000;
|
static int test_timeout(ftFileCreator *creator);
|
||||||
if (fcreator.getMissingChunk(offset, csize)){
|
static int test_fill(ftFileCreator *creator);
|
||||||
std::cout << "Missing Chunk's offset=" << offset << " chunk_size=" << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/* use ftcreator to create a file on tmp drive */
|
||||||
|
ftFileCreator fcreator("/tmp/rs-ftfc-test.dta",100000,"hash",0);
|
||||||
|
|
||||||
std::cout << "Test file creator adding data to file out-of-order\n";
|
test_timeout(&fcreator);
|
||||||
char* alpha = "abcdefghij";
|
test_fill(&fcreator);
|
||||||
std::cerr << "Call to addFileData =" << fcreator.addFileData(10,10,alpha );
|
|
||||||
char* numerical = "1234567890";
|
|
||||||
std::cerr << "Call to addFileData =" << fcreator.addFileData(0,10,numerical );
|
|
||||||
|
|
||||||
|
FINALREPORT("RsTlvItem Stack Tests");
|
||||||
|
|
||||||
/* Test file creator can write out of order/randomized chunker */
|
return TESTRESULT();
|
||||||
ftFileCreator franc("somefile1",50000,"hash", "randomize");
|
|
||||||
csize = 30000;
|
|
||||||
if (franc.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Offset " << offset << " Csize " << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* allA = (char*) malloc(csize);
|
|
||||||
for(int i=0;i<csize;i++)
|
|
||||||
allA[i]='a';
|
|
||||||
|
|
||||||
std::cerr << "ADD DATA RETUNED " << franc.addFileData(offset,csize,allA );
|
|
||||||
|
|
||||||
csize = 10000;
|
|
||||||
if (franc.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Offset " << offset << " Csize " << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* allB = (char*) malloc(csize);
|
|
||||||
for(int i=0;i<csize;i++)
|
|
||||||
allB[i]='b';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::cerr << "ADD DATA RETUNED " << franc.addFileData(offset,csize,allB );
|
|
||||||
|
|
||||||
if (franc.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Offset " << offset << " Csize " << csize << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cout << "getMissing chunk returned nothing" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
csize = 10000;
|
|
||||||
if (franc.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Offset " << offset << " Csize " << csize << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* allC = (char*) malloc(csize);
|
|
||||||
for(int i=0;i<csize;i++)
|
|
||||||
allC[i]='c';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::cerr << "ADD DATA RETUNED " << franc.addFileData(offset,csize,allC );
|
|
||||||
|
|
||||||
if (franc.getMissingChunk(offset, csize)){
|
|
||||||
std::cout << "Offset " << offset << " Csize " << csize << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cout << "getMissing chunk returned nothing" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(allA);
|
|
||||||
free(allB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test_timeout(ftFileCreator *creator)
|
||||||
|
{
|
||||||
|
uint32_t chunk = 1000;
|
||||||
|
uint64_t offset = 0;
|
||||||
|
int max_timeout = 30;
|
||||||
|
int max_offset = chunk * max_timeout;
|
||||||
|
int i;
|
||||||
|
std::cerr << "60 second test of chunk queue.";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
for(i = 0; i < max_timeout; i++)
|
||||||
|
{
|
||||||
|
creator->getMissingChunk(offset, chunk);
|
||||||
|
std::cerr << "Allocated Offset: " << offset << " chunk: " << chunk << std::endl;
|
||||||
|
|
||||||
|
CHECK(offset < max_offset);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "Expect Repeats now";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
for(i = 0; i < max_timeout; i++)
|
||||||
|
{
|
||||||
|
creator->getMissingChunk(offset, chunk);
|
||||||
|
std::cerr << "Allocated Offset: " << offset << " chunk: " << chunk << std::endl;
|
||||||
|
|
||||||
|
CHECK(offset < max_offset);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
REPORT("Chunk Queue");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test_fill(ftFileCreator *creator)
|
||||||
|
{
|
||||||
|
uint32_t chunk = 1000;
|
||||||
|
uint64_t offset = 0;
|
||||||
|
|
||||||
|
uint64_t init_size = creator->getFileSize();
|
||||||
|
uint64_t init_trans = creator->getRecvd();
|
||||||
|
std::cerr << "Initial FileSize: " << init_size << std::endl;
|
||||||
|
std::cerr << "Initial Transferred:" << init_trans << std::endl;
|
||||||
|
|
||||||
|
while(creator->getMissingChunk(offset, chunk))
|
||||||
|
{
|
||||||
|
/* give it too them */
|
||||||
|
void *data = malloc(chunk);
|
||||||
|
creator->addFileData(offset, chunk, data);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t end_size = creator->getFileSize();
|
||||||
|
uint64_t end_trans = creator->getRecvd();
|
||||||
|
std::cerr << "End FileSize: " << end_size << std::endl;
|
||||||
|
std::cerr << "End Transferred:" << end_trans << std::endl;
|
||||||
|
CHECK(init_size == end_size);
|
||||||
|
CHECK(end_trans == end_size);
|
||||||
|
|
||||||
|
REPORT("Test Fill");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#include "util/rsdir.h"
|
#include "util/rsdir.h"
|
||||||
|
|
||||||
ftFileProvider::ftFileProvider(std::string path, uint64_t size, std::string
|
ftFileProvider::ftFileProvider(std::string path, uint64_t size, std::string
|
||||||
hash) : total_size(size), hash(hash), file_name(path), fd(NULL) {
|
hash) : mSize(size), hash(hash), file_name(path), fd(NULL)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ftFileProvider::~ftFileProvider(){
|
ftFileProvider::~ftFileProvider(){
|
||||||
@ -13,20 +13,29 @@ ftFileProvider::~ftFileProvider(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftFileProvider::fileOk()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
return (fd != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
std::string ftFileProvider::getHash()
|
std::string ftFileProvider::getHash()
|
||||||
{
|
{
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ftFileProvider::getFileSize()
|
uint64_t ftFileProvider::getFileSize()
|
||||||
{
|
{
|
||||||
return total_size;
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ftFileProvider::FileDetails(FileInfo &info)
|
bool ftFileProvider::FileDetails(FileInfo &info)
|
||||||
{
|
{
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
info.hash = hash;
|
info.hash = hash;
|
||||||
info.size = total_size;
|
info.size = mSize;
|
||||||
info.path = file_name;
|
info.path = file_name;
|
||||||
info.fname = RsDirUtil::getTopDir(file_name);
|
info.fname = RsDirUtil::getTopDir(file_name);
|
||||||
|
|
||||||
@ -38,16 +47,14 @@ bool ftFileProvider::FileDetails(FileInfo &info)
|
|||||||
|
|
||||||
bool ftFileProvider::getFileData(uint64_t offset, uint32_t chunk_size, void *data)
|
bool ftFileProvider::getFileData(uint64_t offset, uint32_t chunk_size, void *data)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(ftPMutex); /********** STACK LOCKED MTX ******/
|
/* dodgey checking outside of mutex...
|
||||||
if (fd==NULL)
|
* much check again inside FileAttrs().
|
||||||
{
|
*/
|
||||||
int init = initializeFileAttrs();
|
if (fd == NULL)
|
||||||
if (init ==0)
|
if (!initializeFileAttrs())
|
||||||
{
|
return false;
|
||||||
std::cerr <<"Initialization Failed" << std::endl;
|
|
||||||
return 0;
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use private data, which has a pointer to file, total size etc
|
* Use private data, which has a pointer to file, total size etc
|
||||||
@ -59,9 +66,9 @@ bool ftFileProvider::getFileData(uint64_t offset, uint32_t chunk_size, void *dat
|
|||||||
int data_size = chunk_size;
|
int data_size = chunk_size;
|
||||||
long base_loc = offset;
|
long base_loc = offset;
|
||||||
|
|
||||||
if (base_loc + data_size > total_size)
|
if (base_loc + data_size > mSize)
|
||||||
{
|
{
|
||||||
data_size = total_size - base_loc;
|
data_size = mSize - base_loc;
|
||||||
std::cerr <<"Chunk Size greater than total file size, adjusting chunk size " << data_size << std::endl;
|
std::cerr <<"Chunk Size greater than total file size, adjusting chunk size " << data_size << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +115,14 @@ bool ftFileProvider::getFileData(uint64_t offset, uint32_t chunk_size, void *dat
|
|||||||
|
|
||||||
int ftFileProvider::initializeFileAttrs()
|
int ftFileProvider::initializeFileAttrs()
|
||||||
{
|
{
|
||||||
|
std::cerr << "ftFileProvider::initializeFileAttrs() Filename: ";
|
||||||
|
std::cerr << file_name;
|
||||||
|
|
||||||
|
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
if (fd)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the file exists
|
* check if the file exists
|
||||||
*/
|
*/
|
||||||
@ -130,7 +145,6 @@ int ftFileProvider::initializeFileAttrs()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if it opened, find it's length
|
* if it opened, find it's length
|
||||||
* move to the end
|
* move to the end
|
||||||
@ -142,6 +156,9 @@ int ftFileProvider::initializeFileAttrs()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_size = ftell(fd);
|
uint64_t recvdsize = ftell(fd);
|
||||||
|
|
||||||
|
std::cerr << "ftFileProvider::initializeFileAttrs() File Expected Size: " << mSize << " RecvdSize: " << recvdsize << std::endl;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,18 @@ class ftFileProvider
|
|||||||
public:
|
public:
|
||||||
ftFileProvider(std::string path, uint64_t size, std::string hash);
|
ftFileProvider(std::string path, uint64_t size, std::string hash);
|
||||||
virtual ~ftFileProvider();
|
virtual ~ftFileProvider();
|
||||||
|
|
||||||
virtual bool getFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
virtual bool getFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||||
virtual bool FileDetails(FileInfo &info);
|
virtual bool FileDetails(FileInfo &info);
|
||||||
std::string getHash();
|
std::string getHash();
|
||||||
uint64_t getFileSize();
|
uint64_t getFileSize();
|
||||||
|
bool fileOk();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int initializeFileAttrs();
|
virtual int initializeFileAttrs(); /* does for both */
|
||||||
uint64_t total_size;
|
|
||||||
|
uint64_t mSize;
|
||||||
std::string hash;
|
std::string hash;
|
||||||
std::string file_name;
|
std::string file_name;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
@ -65,7 +68,7 @@ protected:
|
|||||||
/*
|
/*
|
||||||
* Mutex Required for stuff below
|
* Mutex Required for stuff below
|
||||||
*/
|
*/
|
||||||
RsMutex ftPMutex;
|
RsMutex ftcMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,33 +1,72 @@
|
|||||||
#include "ftfileprovider.h"
|
#include "ftfileprovider.h"
|
||||||
|
#include "ftfilecreator.h"
|
||||||
|
|
||||||
int main(){
|
#include "util/utest.h"
|
||||||
ftFileProvider fp("dummy.txt",1,"ABCDEF");
|
|
||||||
char data[2];
|
|
||||||
long offset = 0;
|
|
||||||
for (int i=0;i<10;i++) {
|
|
||||||
|
|
||||||
if (fp.getFileData(offset,2,&data)){
|
|
||||||
std::cout <<"Recv data " << data[0] << std::endl;
|
INITTEST()
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
/* create a random file */
|
||||||
|
uint64_t size = 100000;
|
||||||
|
uint32_t max_chunk = 10000;
|
||||||
|
uint32_t chunk = 1000;
|
||||||
|
uint64_t offset = 0;
|
||||||
|
|
||||||
|
std::string filename = "/tmp/ft_test.dta";
|
||||||
|
std::string filename2 = "/tmp/ft_test.dta.dup";
|
||||||
|
|
||||||
|
/* use creator to make it */
|
||||||
|
|
||||||
|
void *data = malloc(max_chunk);
|
||||||
|
|
||||||
|
ftFileCreator *creator = new ftFileCreator(filename, size, "hash", 0);
|
||||||
|
for(offset = 0; offset != size; offset += chunk)
|
||||||
|
{
|
||||||
|
if (!creator->addFileData(offset, chunk, data))
|
||||||
|
{
|
||||||
|
FAILED("Create Test Data File");
|
||||||
|
std::cerr << "Failed to add data (CREATE)";
|
||||||
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
std::cout <<"Recv no data." << std::endl;
|
|
||||||
}
|
|
||||||
offset+=2;
|
|
||||||
}
|
}
|
||||||
|
delete creator;
|
||||||
|
|
||||||
|
std::cerr << "Created file: " << filename << " of size: " << size;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
ftFileProvider fp1("dummy1.txt",3,"ABCDEF");
|
/* load it with file provider */
|
||||||
char data1[3];
|
creator = new ftFileCreator(filename2, size, "hash", 0);
|
||||||
offset = 0;
|
ftFileProvider *provider = new ftFileProvider(filename, size, "hash");
|
||||||
for (int i=0;i<10;i++) {
|
|
||||||
|
|
||||||
if (fp1.getFileData(offset,2,&data1)){
|
/* create duplicate with file creator */
|
||||||
std::cout <<"Recv data " << data1[0] << std::endl;
|
|
||||||
|
while(creator->getMissingChunk(offset, chunk))
|
||||||
|
{
|
||||||
|
if (!provider->getFileData(offset, chunk, data))
|
||||||
|
{
|
||||||
|
FAILED("Read from Test Data File");
|
||||||
|
std::cerr << "Failed to get data";
|
||||||
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
std::cout <<"Revc no data" << std::endl;
|
if (!creator->addFileData(offset, chunk, data))
|
||||||
|
{
|
||||||
|
FAILED("Write to Duplicate");
|
||||||
|
std::cerr << "Failed to add data";
|
||||||
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
offset+=2;
|
|
||||||
|
std::cerr << "Transferred: " << chunk << " @ " << offset;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
/* reset chunk size */
|
||||||
|
chunk = (uint64_t) max_chunk * (rand() / (1.0 + RAND_MAX));
|
||||||
|
|
||||||
|
std::cerr << "ChunkSize = " << chunk << std::endl;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -140,16 +140,35 @@ bool ftTransferModule::recvFileData(std::string peerId, uint64_t offset,
|
|||||||
mit = mFileSources.find(peerId);
|
mit = mFileSources.find(peerId);
|
||||||
|
|
||||||
if (mit == mFileSources.end())
|
if (mit == mFileSources.end())
|
||||||
return false;
|
{
|
||||||
|
#ifdef FT_DEBUG
|
||||||
|
std::cerr << "ftTransferModule::recvFileData()";
|
||||||
|
std::cerr << " peer not found in sources";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mit->second).state != PQIPEER_DOWNLOADING)
|
if ((mit->second).state != PQIPEER_DOWNLOADING)
|
||||||
return false;
|
{
|
||||||
|
#ifdef FT_DEBUG
|
||||||
|
std::cerr << "ftTransferModule::recvFileData()";
|
||||||
|
std::cerr << " peer not downloading???";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
//return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset != ((mit->second).offset + (mit->second).receivedSize))
|
if (offset != ((mit->second).offset + (mit->second).receivedSize))
|
||||||
{
|
{
|
||||||
//fix me
|
//fix me
|
||||||
//received data not expected
|
//received data not expected
|
||||||
return false;
|
#ifdef FT_DEBUG
|
||||||
|
std::cerr << "ftTransferModule::recvFileData()";
|
||||||
|
std::cerr << " offset != offset + recvdSize";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(mit->second).receivedSize += chunk_size;
|
(mit->second).receivedSize += chunk_size;
|
||||||
|
180
libretroshare/src/ft/fttransfermoduletest.cc
Normal file
180
libretroshare/src/ft/fttransfermoduletest.cc
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* libretroshare/src/ft: fttransfermoduletest.cc
|
||||||
|
*
|
||||||
|
* File Transfer for RetroShare.
|
||||||
|
*
|
||||||
|
* Copyright 2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test for Multiplexor.....
|
||||||
|
* As this is a key middle component, it is hard to test without other bits.
|
||||||
|
* It relies on ftFileProvider/ftFileCreator/ftTransferModule...
|
||||||
|
*
|
||||||
|
* And has dummy ftDataSend and ftSearch.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "util/rswin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ft/ftextralist.h"
|
||||||
|
#include "ft/ftdatamultiplex.h"
|
||||||
|
#include "ft/ftfilesearch.h"
|
||||||
|
|
||||||
|
#include "ftfileprovider.h"
|
||||||
|
#include "ftfilecreator.h"
|
||||||
|
#include "ftcontroller.h"
|
||||||
|
#include "fttransfermodule.h"
|
||||||
|
|
||||||
|
#include "util/utest.h"
|
||||||
|
|
||||||
|
INITTEST()
|
||||||
|
|
||||||
|
|
||||||
|
void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list<std::string> &files);
|
||||||
|
|
||||||
|
|
||||||
|
void usage(char *name)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: " << name << " [-p <period>] [-d <dperiod>] <path> [<path2> ... ] ";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
uint32_t period = 1;
|
||||||
|
uint32_t dPeriod = 600; /* default 10 minutes */
|
||||||
|
|
||||||
|
std::list<std::string> fileList;
|
||||||
|
|
||||||
|
while(-1 != (c = getopt(argc, argv, "d:p:")))
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'p':
|
||||||
|
period = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
dPeriod = atoi(optarg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
{
|
||||||
|
std::cerr << "Missing Files" << std::endl;
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; optind < argc; optind++)
|
||||||
|
{
|
||||||
|
std::cerr << "Adding: " << argv[optind] << std::endl;
|
||||||
|
fileList.push_back(std::string(argv[optind]));
|
||||||
|
}
|
||||||
|
|
||||||
|
ftExtraList *eList = new ftExtraList();
|
||||||
|
eList->start();
|
||||||
|
|
||||||
|
ftSearch *ftsd = new ftSearchDummy();
|
||||||
|
ftFileSearch *ftfs = new ftFileSearch();
|
||||||
|
|
||||||
|
ftfs-> addSearchMode(ftsd, RS_FILE_HINTS_LOCAL);
|
||||||
|
ftfs-> addSearchMode(eList, RS_FILE_HINTS_EXTRA);
|
||||||
|
|
||||||
|
ftDataSendPair *ftds1 = new ftDataSendPair(NULL);
|
||||||
|
ftDataSendPair *ftds2 = new ftDataSendPair(NULL);
|
||||||
|
|
||||||
|
/* setup Actual Test bit */
|
||||||
|
ftDataMultiplex *ftmplex1 = new ftDataMultiplex("ownId", ftds2, ftfs);
|
||||||
|
ftDataMultiplex *ftmplex2 = new ftDataMultiplex("ownId", ftds1, ftfs);
|
||||||
|
|
||||||
|
ftds1->mDataRecv = ftmplex1;
|
||||||
|
ftds2->mDataRecv = ftmplex2;
|
||||||
|
|
||||||
|
ftmplex1->start();
|
||||||
|
ftmplex2->start();
|
||||||
|
|
||||||
|
/* Setup Search with some valid results */
|
||||||
|
/* Request Data */
|
||||||
|
|
||||||
|
/* now work the thread */
|
||||||
|
std::list<std::string>::iterator it;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
for(it = fileList.begin(); it != fileList.end(); it++)
|
||||||
|
{
|
||||||
|
eList->hashExtraFile(*it, dPeriod, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileList.size() < 1)
|
||||||
|
{
|
||||||
|
std::cerr << "come on, give us some files...";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now request files from ftDataMultiplex
|
||||||
|
* by adding in a ftTransferModule!
|
||||||
|
*/
|
||||||
|
std::string filename = *(fileList.begin());
|
||||||
|
|
||||||
|
/* wait for file to hash */
|
||||||
|
FileInfo info;
|
||||||
|
while(!eList->hashExtraFileDone(filename, info))
|
||||||
|
{
|
||||||
|
std::cerr << "Waiting for file to hash";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string savename = "/tmp/" + info.fname;
|
||||||
|
ftFileCreator *creator = new ftFileCreator(savename, info.size, info.hash, 0);
|
||||||
|
ftController *controller = NULL;
|
||||||
|
|
||||||
|
ftTransferModule *transfer = new ftTransferModule(creator, ftmplex1, controller);
|
||||||
|
|
||||||
|
ftmplex1->addTransferModule(transfer, creator);
|
||||||
|
|
||||||
|
std::list<std::string> peerIds;
|
||||||
|
peerIds.push_back("ownId2");
|
||||||
|
|
||||||
|
transfer->setFileSources(peerIds);
|
||||||
|
transfer->setPeerState("ownId2", PQIPEER_IDLE, 1000);
|
||||||
|
//transfer->resumeTransfer();
|
||||||
|
|
||||||
|
/* check file progress */
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
std::cerr << "File Transfer Status";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "Transfered: " << creator->getRecvd();
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
transfer->tick();
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user