// each file buffer stores an array of coded blocks // +-------+------------+-------+------------+----- // | coeff | coded data | coeff | coded data | ... // +-------+------------+-------+------------+----- CodedBlockPtr CodeTorrent::ReadGenBuf(int gen, int k) { // NOTE: error checking must be done prior to invoking this method! // (i.e. are there strictly less than k blocks in this file buffer?) // NOTE: k begins at 0 CodedBlockPtr tempBlock; tempBlock = AllocCodedBlock(num_blocks_gen[gen], block_size); tempBlock->gen = gen; const char *ext = ".temp"; char *ext2 = new char[3]; // what if more than 100 gens? #ifdef WIN32 itoa(gen, ext2, 10); // base : 10 #else sprintf(ext2, "%d", gen); #endif int fname_len = strlen(filename); int ext_len = strlen(ext); int ext2_len = strlen(ext2); // this is dumb but works char *filename_read = new char[fname_len + ext_len + ext2_len + 1]; memcpy(filename_read, filename, fname_len); memcpy(filename_read + fname_len, ext, ext_len); memcpy(filename_read + fname_len + ext_len, ext2, ext2_len); filename_read[fname_len + ext_len + ext2_len] = '\0'; fp = fopen(filename_read, "rb"); if(fp) HAGGLE_DBG2("Opening file %s for writing with file descriptor %d\n", filename_read, fileno(fp)); if (!fp) { HAGGLE_ERR("CODETORRENT ERROR: cache access error!\n"); } if (fseek(fp, (num_blocks_gen[gen] + block_size) * k, SEEK_SET)) { HAGGLE_ERR("CODETORRENT ERROR: cache access error!\n"); } int cf = fread(tempBlock->coeffs, 1, num_blocks_gen[gen], fp); int sm = fread(tempBlock->sums, 1, block_size, fp); if (cf != num_blocks_gen[gen] || sm != block_size) { HAGGLE_ERR("CODETORRENT ERROR: cache reading error!\n"); } fclose(fp); delete[] filename_read; delete[] ext2; return tempBlock; }
CodedBlock* CodeTorrent::CopyCodedBlock(CodedBlockPtr ptr) { CodedBlock *new_blk = AllocCodedBlock(ptr->num_blocks_gen, ptr->block_size); new_blk->gen = ptr->gen; new_blk->num_blocks_gen = ptr->num_blocks_gen; new_blk->block_size = ptr->block_size; memcpy(new_blk->coeffs, ptr->coeffs, new_blk->num_blocks_gen); memcpy(new_blk->sums, ptr->sums, new_blk->block_size); return new_blk; }
// re-encode a block from generation "gen" // return NULL pointer if failed (e.g. no data in buffer) CodedBlockPtr CodeTorrent::ReEncode(int gen) { int j; // TODO: Make this work with file buffers // CBMEN, HL - Allocate memory here CodedBlockPtr cb = AllocCodedBlock(num_blocks_gen[gen], block_size); if (!cb) return NULL; cb->gen = gen; cb->num_blocks_gen = num_blocks_gen[gen]; cb->block_size = block_size; //std::vector<CodedBlockPtr> *tempBuf = new std::vector<CodedBlockPtr>[GetRankVec()[gen]]; std::vector<CodedBlockPtr> tempBuf; gettimeofday(&ct_vector_beg, &ct_tz); for (std::vector<CodedBlockPtr>::iterator it = buf.begin(); it != buf.end(); ++it) { if ((*it)->gen == gen) tempBuf.push_back(CopyCodedBlock((*it))); } int blocks_in_file = rank_vec[gen] - rank_vec_in_buf[gen]; for (j = 0; j < blocks_in_file; j++) { tempBuf.push_back(ReadGenBuf(gen, j)); } gettimeofday(&ct_vector_end, &ct_tz); //printf("[CT_Encode] Vector time: %ld.%03ld\n", CT_GetTimeDifference(ct_vector_beg, ct_vector_end) / 1000, // CT_GetTimeDifference(ct_vector_beg, ct_vector_end) % 1000); //gettimeofday(&ct_encode_beg, &ct_tz); if (!nc->ReEncodeBlock(tempBuf, cb)) { return NULL; } //gettimeofday(&ct_encode_end, &ct_tz); //printf("[CT_Encode] Encode time: %ld.%03ld\n", CT_GetTimeDifference(ct_encode_beg, ct_encode_end)/1000, CT_GetTimeDifference(ct_encode_beg, ct_encode_end)%1000); for (j = 0; j < tempBuf.size(); j++) FreeCodedBlock(tempBuf[j]); tempBuf.clear(); // CBMEN, HL - no need for redundant copy return cb; //return CopyCodedBlock(cb); }
// encode a block from generation "gen" CodedBlockPtr SingleBlockEncoder::EncodeSingleBlock(int gen, int blockIdInGen, BlockPtr fragBlockData, int fragDataSize, int num_blocks_gen) { int block_size = fragDataSize; // int buffer_size = 2 * block_size; if(fragDataSize != block_size){ //TODO: Report error return NULL; } // create a new copy CodedBlockPtr cb_to = AllocCodedBlock(num_blocks_gen, block_size); cb_to->gen = gen; cb_to->num_blocks_gen = num_blocks_gen; cb_to->block_size = block_size; //Make a fake data to encode std::vector<BlockPtr> fakeData; BlockPtr pblk; for(int i=0;i<num_blocks_gen;i++){ pblk = AllocBlock((block_size)); memset(pblk, 0, (block_size)); if(i==blockIdInGen){ memcpy(pblk, fragBlockData, (block_size)); } fakeData.push_back(pblk); } nc->EncodeSingleBlock(fakeData, cb_to, blockIdInGen); //release fake data for(int i=0;i<(int) fakeData.size();i++){ FreeBlock(fakeData[i]); } fakeData.clear(); return cb_to; }
// encode a block from generation "gen" CodedBlockPtr CodeTorrent::Encode(int gen) { // if the data's not already in memory, load it if (gen_in_memory != gen) { LoadFile(gen); if(data.size() == 0) return NULL; // MOS } // create a new copy CodedBlockPtr cb_to = AllocCodedBlock(num_blocks_gen[gen], block_size); cb_to->gen = gen; cb_to->num_blocks_gen = num_blocks_gen[gen]; cb_to->block_size = block_size; gettimeofday(&ct_encode_beg, &ct_tz); nc->EncodeBlock(data, cb_to); gettimeofday(&ct_encode_end, &ct_tz); // printf("[CT_Encode] Encode time: %ld.%03ld\n", CT_GetTimeDifference(ct_encode_beg, ct_encode_end) / 1000, // CT_GetTimeDifference(ct_encode_beg, ct_encode_end) % 1000); return cb_to; }