# 1 "code_ff_ofarm.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "code_ff_ofarm.cpp"
# 23 "code_ff_ofarm.cpp"
extern "C" {
}
# 42 "code_ff_ofarm.cpp"
config_t * conf;
struct hashtable *cache;
17 static unsigned int hash_from_key_fn( void *k ) {
return ( ( unsigned int * )k )[0];
}
22 static int keys_equal_fn ( void *key1, void *key2 ) {
return ( memcmp( key1, key2, SHA1_LEN ) == 0 );
}
struct thread_args {
int tid;
int fd;
struct {
void *buffer;
size_t size;
} input_file;
};
# 180 "code_ff_ofarm.cpp"
39 static int write_file( int fd, u_char type, u_long len, u_char * content ) {
if ( xwrite( fd, &type, sizeof( type ) ) < 0 ){
perror( "xwrite:" );
EXIT_TRACE( "xwrite type fails\n" );
return -1;
}
if ( xwrite( fd, &len, sizeof( len ) ) < 0 ){
EXIT_TRACE( "xwrite content fails\n" );
}
if ( xwrite( fd, content, len ) < 0 ){
EXIT_TRACE( "xwrite content fails\n" );
}
return 0;
}
59 static int create_output_file( char *outfile ) {
int fd;
fd = open( outfile, O_CREAT|O_TRUNC|O_WRONLY|O_TRUNC, S_IRGRP | S_IWUSR | S_IRUSR | S_IROTH );
if ( fd < 0 ) {
EXIT_TRACE( "Cannot open output file." );
}
if ( write_header( fd, conf->compress_type ) ) {
EXIT_TRACE( "Cannot write output file header.\n" );
}
return fd;
}
# 230 "code_ff_ofarm.cpp"
76 static void write_chunk_to_file( int fd, chunk_t *chunk ) {
assert( chunk!=NULL );
if( chunk->header.isDuplicate ) chunk = chunk->compressed_data_ref;
pthread_mutex_lock( &chunk->header.lock );
while( chunk->header.state == CHUNK_STATE_UNCOMPRESSED ) {
pthread_cond_wait( &chunk->header.update, &chunk->header.lock );
}
if( chunk->header.state == CHUNK_STATE_COMPRESSED ) {
write_file( fd, TYPE_COMPRESS, chunk->compressed_data.n, ( u_char* ) chunk->compressed_data.ptr );
mbuffer_free( &chunk->compressed_data );
chunk->header.state = CHUNK_STATE_FLUSHED;
} else {
write_file( fd, TYPE_FINGERPRINT, SHA1_LEN, ( unsigned char * )( chunk->sha1 ) );
}
pthread_mutex_unlock( &chunk->header.lock );
}
int rf_win;
int rf_win_dataprocess;
109 static void sub_Compress( chunk_t *chunk ) {
size_t n;
int r;
assert( chunk!=NULL );
pthread_mutex_lock( &chunk->header.lock );
assert( chunk->header.state == CHUNK_STATE_UNCOMPRESSED );
switch ( conf->compress_type ) {
case COMPRESS_NONE:
n = chunk->uncompressed_data.n;
r = mbuffer_create( &chunk->compressed_data, n );
if( r != 0 ) {
EXIT_TRACE( "Creation of compression buffer failed.\n" );
}
memcpy( chunk->compressed_data.ptr, chunk->uncompressed_data.ptr, chunk->uncompressed_data.n );
break;
# 324 "code_ff_ofarm.cpp"
default:
EXIT_TRACE( "Compression type not implemented.\n" );
break;
}
mbuffer_free( &chunk->uncompressed_data );
chunk->header.state = CHUNK_STATE_COMPRESSED;
pthread_cond_broadcast( &chunk->header.update );
pthread_mutex_unlock( &chunk->header.lock );
return;
}
# 344 "code_ff_ofarm.cpp"
141 class Compress: public ff::ff_node{
private:
143 bool sendOut;
144 std::vector<ringbuffer_t*> dataOut;
145 chunk_t * chunk;
int r;
147 ringbuffer_t *recv_buf, *send_buf;
public:
152 Compress( bool send ):sendOut( send ), chunk( NULL ), recv_buf( NULL ){
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
r=0;
r += ringbuffer_init( send_buf, ITEM_PER_INSERT );
assert( r==0 );
}
165 std::vector<ringbuffer_t*> getDataOut( ) const{return dataOut;}
166 stats_t* getStats( ) const{return thread_stats;}
168 void *svc( void * task ) {
dataOut.clear( );
recv_buf = ( ringbuffer_t* ) task;
bool isLast = ringbuffer_isLast( recv_buf );
while( !ringbuffer_isEmpty( recv_buf ) ){
chunk = ( chunk_t * )ringbuffer_remove( recv_buf );
assert( chunk!=NULL );
if( chunk->header.isDuplicate ){
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if ( ringbuffer_isFull( send_buf ) ) {
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, ITEM_PER_INSERT );
}
continue;
}
sub_Compress( chunk );
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if ( ringbuffer_isFull( send_buf ) ) {
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, ITEM_PER_INSERT );
}
}
ringbuffer_destroy( recv_buf );
free( recv_buf );
if( isLast ){
ringbuffer_setLast( send_buf );
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
}
return GO_ON;
}
};
# 441 "code_ff_ofarm.cpp"
229 static int sub_Deduplicate( chunk_t *chunk ) {
int isDuplicate;
chunk_t *entry;
assert( chunk!=NULL );
assert( chunk->uncompressed_data.ptr!=NULL );
SHA1_Digest( chunk->uncompressed_data.ptr, chunk->uncompressed_data.n, ( unsigned char * )( chunk->sha1 ) );
pthread_mutex_t *ht_lock = hashtable_getlock( cache, ( void * )( chunk->sha1 ) );
pthread_mutex_lock( ht_lock );
entry = ( chunk_t * )hashtable_search( cache, ( void * )( chunk->sha1 ) );
isDuplicate = ( entry != NULL );
chunk->header.isDuplicate = isDuplicate;
if ( !isDuplicate ) {
pthread_mutex_init( &chunk->header.lock, NULL );
pthread_cond_init( &chunk->header.update, NULL );
if ( hashtable_insert( cache, ( void * )( chunk->sha1 ), ( void * )chunk ) == 0 ) {
EXIT_TRACE( "hashtable_insert failed" );
}
} else {
chunk->compressed_data_ref = entry;
mbuffer_free( &chunk->uncompressed_data );
}
pthread_mutex_unlock( ht_lock );
return isDuplicate;
}
# 483 "code_ff_ofarm.cpp"
262 class Deduplicate: public ff::ff_node{
private:
264 bool sendOut;
265 std::vector<ringbuffer_t*> dataOut;
266 chunk_t *chunk;
int r;
268 ringbuffer_t *recv_buf, *send_buf;
public:
273 Deduplicate( bool send ):
sendOut( send ), chunk( NULL ), recv_buf( NULL ){
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
r=0;
r += ringbuffer_init( send_buf, ITEM_PER_INSERT );
assert( r==0 );
}
290 stats_t* getStats( ) const{return thread_stats;}
292 std::vector<ringbuffer_t*> getDataOut( ) const{
return dataOut;
}
296 void * svc( void * task ) {
dataOut.clear( );
recv_buf = ( ringbuffer_t* ) task;
bool isLast = ringbuffer_isLast( recv_buf );
while( !ringbuffer_isEmpty( recv_buf ) ){
chunk = ( chunk_t * )ringbuffer_remove( recv_buf );
assert( chunk!=NULL );
int isDuplicate = sub_Deduplicate( chunk );
# 537 "code_ff_ofarm.cpp"
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if ( ringbuffer_isFull( send_buf ) ) {
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, ITEM_PER_INSERT );
}
}
ringbuffer_destroy( recv_buf );
free( recv_buf );
if( isLast ){
ringbuffer_setLast( send_buf );
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
}
return GO_ON;
}
};
# 578 "code_ff_ofarm.cpp"
338 class FragmentRefine: public ff::ff_node{
private:
340 bool sendOut;
341 std::vector<ringbuffer_t*> dataOut;
342 ringbuffer_t* recv_buf, *send_buf;
int r;
345 chunk_t *temp;
346 chunk_t *chunk;
347 u32int * rabintab;
348 u32int * rabinwintab;
public:
353 FragmentRefine( bool send ): sendOut( send ), recv_buf( NULL ), temp( NULL ), chunk( NULL ){
rabintab = ( u32int* ) malloc( 256*sizeof rabintab[0] );
rabinwintab = ( u32int* ) malloc( 256*sizeof rabintab[0] );
if( rabintab == NULL || rabinwintab == NULL ) {
EXIT_TRACE( "Memory allocation failed.\n" );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
r=0;
r += ringbuffer_init( send_buf, CHUNK_ANCHOR_PER_INSERT );
assert( r==0 );
# 612 "code_ff_ofarm.cpp"
}
367 ~FragmentRefine( ){
free( rabintab );
free( rabinwintab );
}
372 stats_t* getStats( ) const{return thread_stats;}
374 std::vector<ringbuffer_t*> getDataOut( ) const{
return dataOut;
}
378 void *svc( void * task ) {
dataOut.clear( );
recv_buf = ( ringbuffer_t* ) task;
bool isLast = ringbuffer_isLast( recv_buf );
while( !ringbuffer_isEmpty( recv_buf ) ){
chunk = ( chunk_t * )ringbuffer_remove( recv_buf );
assert( chunk!=NULL );
rabininit( rf_win, rabintab, rabinwintab );
int split;
sequence_number_t chcount = 0;
do {
int offset = rabinseg( ( uchar* ) chunk->uncompressed_data.ptr, chunk->uncompressed_data.n, rf_win, rabintab, rabinwintab );
if( offset < chunk->uncompressed_data.n ) {
temp = ( chunk_t * )malloc( sizeof( chunk_t ) );
if( temp==NULL ) EXIT_TRACE( "Memory allocation failed.\n" );
temp->header.state = chunk->header.state;
temp->sequence.l1num = chunk->sequence.l1num;
r = mbuffer_split( &chunk->uncompressed_data, &temp->uncompressed_data, offset );
if( r!=0 ) EXIT_TRACE( "Unable to split memory buffer.\n" );
chunk->sequence.l2num = chcount;
chunk->isLastL2Chunk = FALSE;
chcount++;
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if ( ringbuffer_isFull( send_buf ) ) {
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, CHUNK_ANCHOR_PER_INSERT );
}
chunk = temp;
split = 1;
} else {
chunk->sequence.l2num = chcount;
chunk->isLastL2Chunk = TRUE;
chcount++;
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if ( ringbuffer_isFull( send_buf ) ) {
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, CHUNK_ANCHOR_PER_INSERT );
}
chunk = NULL;
split = 0;
}
} while( split );
}
ringbuffer_destroy( recv_buf );
free( recv_buf );
if( isLast ) {
ringbuffer_setLast( send_buf );
if( sendOut ){
while( !ff_send_out( ( void* ) send_buf ) );
}else{
dataOut.push_back( send_buf );
}
}
return GO_ON;
}
};
# 741 "code_ff_ofarm.cpp"
477 class Fragment: public ff::ff_node{
struct thread_args *args;
479 size_t nw;
480 ff::ff_loadbalancer* lb;
public:
482 Fragment( struct thread_args* targs, size_t numWorkers, ff::ff_loadbalancer* l ):
args( targs ), nw( numWorkers ), lb( l ){;}
485 void* svc( void * ){
size_t preloading_buffer_seek = 0;
int fd = args->fd;
int i;
ringbuffer_t* send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
sequence_number_t anchorcount = 0;
int r;
chunk_t *temp = NULL;
chunk_t *chunk = NULL;
u32int * rabintab = ( u32int* ) malloc( 256*sizeof rabintab[0] );
u32int * rabinwintab = ( u32int* ) malloc( 256*sizeof rabintab[0] );
if( rabintab == NULL || rabinwintab == NULL ) {
EXIT_TRACE( "Memory allocation failed.\n" );
}
r = ringbuffer_init( send_buf, ANCHOR_DATA_PER_INSERT );
assert( r==0 );
rf_win_dataprocess = 0;
rabininit( rf_win_dataprocess, rabintab, rabinwintab );
if( MAXBUF < 8 * ANCHOR_JUMP ) {
printf( "WARNING: I/O buffer size is very small. Performance degraded.\n" );
fflush( NULL );
}
while ( 1 ) {
size_t bytes_left;
if( temp != NULL ) {
bytes_left = temp->uncompressed_data.n;
} else {
bytes_left = 0;
}
if( MAXBUF+bytes_left > SSIZE_MAX ) {
EXIT_TRACE( "Input buffer size exceeds system maximum.\n" );
}
chunk = ( chunk_t * )malloc( sizeof( chunk_t ) );
if( chunk==NULL ) EXIT_TRACE( "Memory allocation failed.\n" );
r = mbuffer_create( &chunk->uncompressed_data, MAXBUF+bytes_left );
if( r!=0 ) {
EXIT_TRACE( "Unable to initialize memory buffer.\n" );
}
if( bytes_left > 0 ) {
chunk->header.state = CHUNK_STATE_UNCOMPRESSED;
chunk->sequence.l1num = temp->sequence.l1num;
memcpy( chunk->uncompressed_data.ptr, temp->uncompressed_data.ptr, temp->uncompressed_data.n );
mbuffer_free( &temp->uncompressed_data );
free( temp );
temp = NULL;
} else {
chunk->header.state = CHUNK_STATE_UNCOMPRESSED;
chunk->sequence.l1num = anchorcount;
anchorcount++;
}
size_t bytes_read=0;
if( conf->preloading ) {
size_t max_read = MIN( MAXBUF, args->input_file.size-preloading_buffer_seek );
memcpy( chunk->uncompressed_data.ptr+bytes_left, args->input_file.buffer+preloading_buffer_seek, max_read );
bytes_read = max_read;
preloading_buffer_seek += max_read;
} else {
while( bytes_read < MAXBUF ) {
r = read( fd, chunk->uncompressed_data.ptr+bytes_left+bytes_read, MAXBUF-bytes_read );
if( r<0 ) switch( errno ) {
case EAGAIN:
EXIT_TRACE( "I/O error: No data available\n" );break;
case EBADF:
EXIT_TRACE( "I/O error: Invalid file descriptor\n" );break;
case EFAULT:
EXIT_TRACE( "I/O error: Buffer out of range\n" );break;
case EINTR:
EXIT_TRACE( "I/O error: Interruption\n" );break;
case EINVAL:
EXIT_TRACE( "I/O error: Unable to read from file descriptor\n" );break;
case EIO:
EXIT_TRACE( "I/O error: Generic I/O error\n" );break;
case EISDIR:
EXIT_TRACE( "I/O error: Cannot read from a directory\n" );break;
default:
EXIT_TRACE( "I/O error: Unrecognized error\n" );break;
}
if( r==0 ) break;
bytes_read += r;
}
}
if( bytes_left + bytes_read == 0 ) {
mbuffer_free( &chunk->uncompressed_data );
free( chunk );
chunk = NULL;
break;
}
if( bytes_left+bytes_read < chunk->uncompressed_data.n ) {
r = mbuffer_realloc( &chunk->uncompressed_data, bytes_left+bytes_read );
assert( r == 0 );
}
if( bytes_read == 0 ) {
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
break;
}
int split;
do {
split = 0;
if( ANCHOR_JUMP < chunk->uncompressed_data.n ) {
int offset = rabinseg( chunk->uncompressed_data.ptr + ANCHOR_JUMP, chunk->uncompressed_data.n - ANCHOR_JUMP, rf_win_dataprocess, rabintab, rabinwintab );
if( offset == 0 ) {
assert( 0 );
split = 0;
} else if( offset + ANCHOR_JUMP < chunk->uncompressed_data.n ) {
temp = ( chunk_t * )malloc( sizeof( chunk_t ) );
if( temp==NULL ) EXIT_TRACE( "Memory allocation failed.\n" );
r = mbuffer_split( &chunk->uncompressed_data, &temp->uncompressed_data, offset + ANCHOR_JUMP );
if( r!=0 ) EXIT_TRACE( "Unable to split memory buffer.\n" );
temp->header.state = CHUNK_STATE_UNCOMPRESSED;
temp->sequence.l1num = anchorcount;
anchorcount++;
r = ringbuffer_insert( send_buf, chunk );
assert( r==0 );
if( ringbuffer_isFull( send_buf ) ) {
ff_send_out( ( void* ) send_buf );
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
r = ringbuffer_init( send_buf, ANCHOR_DATA_PER_INSERT );
}
chunk = temp;
temp = NULL;
split = 1;
} else {
temp = chunk;
chunk = NULL;
split = 0;
}
} else {
temp = chunk;
chunk = NULL;
split = 0;
}
} while( split );
}
ringbuffer_setLast( send_buf );
if( lb ){
while( !lb->ff_send_out_to( ( void* ) send_buf, 0 ) ){;}
}else{
while( !ff_send_out( ( void* ) send_buf ) ){;}
}
for( size_t i = 1; i < nw; i++ ){
send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
r = ringbuffer_init( send_buf, ANCHOR_DATA_PER_INSERT );
ringbuffer_setLast( send_buf );
if( lb ){
while( !lb->ff_send_out_to( ( void* ) send_buf, i ) ){;}
}else{
while( !ff_send_out( ( void* ) send_buf ) ){;}
}
}
free( rabintab );
free( rabinwintab );
return EOS;
}
};
# 964 "code_ff_ofarm.cpp"
686 class Reorder: public ff::ff_node{
private:
struct thread_args *args;
int fd;
690 ringbuffer_t *recv_buf;
691 chunk_t *chunk;
int i;
public:
694 Reorder( struct thread_args* targs ):
args( targs ), fd( create_output_file( conf->outfile ) ), fd( 0 ),
recv_buf( NULL ), chunk( NULL ), r( 0 ), i( 0 ){
;
}
700 ~Reorder( ){
close( fd );
ringbuffer_destroy( recv_buf );
free( recv_buf );
}
706 void *svc( void * task ) {
recv_buf = ( ringbuffer_t* ) task;
while( !ringbuffer_isEmpty( recv_buf ) ) {
chunk = ( chunk_t* )ringbuffer_remove( recv_buf );
if ( chunk == NULL ){break;}
write_chunk_to_file( fd, chunk );
}
return GO_ON;
}
};
717 class CollapsedPipeline: public ff::ff_node{
private:
719 FragmentRefine* fr;
720 Deduplicate* d;
721 Compress* c;
public:
723 CollapsedPipeline( ){
fr = new FragmentRefine( false );
d = new Deduplicate( false );
c = new Compress( false );
}
729 ~CollapsedPipeline( ){
delete fr;
delete d;
delete c;
}
735 FragmentRefine* getFragmentRefine( ) const{return fr;}
736 Deduplicate* getDeduplicate( ) const{return d;}
737 Compress* getCompress( ) const{return c;}
739 void* svc( void* task ){
fr->svc( task );
std::vector<ringbuffer_t*> toD = fr->getDataOut( );
std::vector<ringbuffer_t*> toCompressor;
std::vector<ringbuffer_t*> toReorder;
for( size_t i = 0; i < toD.size( ); i++ ){
std::vector<ringbuffer_t*> fromD;
d->svc( toD[i] );
fromD = d->getDataOut( );
for( size_t j = 0; j < fromD.size( ); j++ ){
toCompressor.push_back( fromD[j] );
}
}
for( size_t i = 0; i < toCompressor.size( ); i++ ){
std::vector<ringbuffer_t*> fromC;
c->svc( toCompressor[i] );
fromC = c->getDataOut( );
for( size_t j = 0; j < fromC.size( ); j++ ){
toReorder.push_back( fromC[j] );
}
}
assert( GRAIN == 1 );
size_t numChunks = toReorder.size( ) * CHUNK_ANCHOR_PER_INSERT;
ringbuffer_t* send_buf = ( ringbuffer_t* ) malloc( sizeof( ringbuffer_t ) );
ringbuffer_init( send_buf, numChunks );
chunk_t* chunk = NULL;
for( size_t i = 0; i < toReorder.size( ); i++ ){
while( !ringbuffer_isEmpty( toReorder[i] ) ) {
chunk = ( chunk_t* )ringbuffer_remove( toReorder[i] );
if ( chunk == NULL ){break;}
ringbuffer_insert( send_buf, chunk );
}
free( toReorder[i] );
}
return send_buf;
}
};
779 static void runSingleFarm( config_t * conf, struct thread_args* data_process_args,
struct thread_args* send_block_args, stats_t **threads_anchor_rv,
stats_t **threads_chunk_rv, stats_t **threads_compress_rv ){
ff::ff_ofarm ofarm;
ofarm.cleanup_all( );
std::vector<ff::ff_node*> workers;
for( size_t i = 0; i < conf->nthreads; i++ ){workers.push_back( new CollapsedPipeline( ) );}
ofarm.setEmitterF( new Fragment( data_process_args, conf->nthreads, NULL ) );
ofarm.add_workers( workers );
ofarm.setCollectorF( new Reorder( send_block_args ) );
ofarm.run_and_wait_end( );
}
}
# 1086 "code_ff_ofarm.cpp"
void EncodeFF( config_t * _conf ) {
struct stat filestat;
int32 fd;
conf = _conf;
cache = hashtable_create( 65536, hash_from_key_fn, keys_equal_fn, FALSE );
if( cache == NULL ) {
printf( "ERROR: Out of memory\n" );
exit( 1 );
}
struct thread_args data_process_args;
int i;
assert( !mbuffer_system_init( ) );
if ( stat( conf->infile, &filestat ) < 0 )
EXIT_TRACE( "stat( ) %s failed: %s\n", conf->infile, strerror( errno ) );
if ( !S_ISREG( filestat.st_mode ) )
EXIT_TRACE( "not a normal file: %s\n", conf->infile );
if( ( fd = open( conf->infile, O_RDONLY | O_LARGEFILE ) ) < 0 )
EXIT_TRACE( "%s file open error %s\n", conf->infile, strerror( errno ) );
void *preloading_buffer = NULL;
if( conf->preloading ) {
size_t bytes_read=0;
int r;
preloading_buffer = malloc( filestat.st_size );
if( preloading_buffer == NULL )
EXIT_TRACE( "Error allocating memory for input buffer.\n" );
while( bytes_read < filestat.st_size ) {
r = read( fd, preloading_buffer+bytes_read, filestat.st_size-bytes_read );
if( r<0 ) switch( errno ) {
case EAGAIN:
EXIT_TRACE( "I/O error: No data available\n" );break;
case EBADF:
EXIT_TRACE( "I/O error: Invalid file descriptor\n" );break;
case EFAULT:
EXIT_TRACE( "I/O error: Buffer out of range\n" );break;
case EINTR:
EXIT_TRACE( "I/O error: Interruption\n" );break;
case EINVAL:
EXIT_TRACE( "I/O error: Unable to read from file descriptor\n" );break;
case EIO:
EXIT_TRACE( "I/O error: Generic I/O error\n" );break;
case EISDIR:
EXIT_TRACE( "I/O error: Cannot read from a directory\n" );break;
default:
EXIT_TRACE( "I/O error: Unrecognized error\n" );break;
}
if( r==0 ) break;
bytes_read += r;
}
data_process_args.input_file.size = filestat.st_size;
data_process_args.input_file.buffer = preloading_buffer;
}
data_process_args.tid = 0;
data_process_args.fd = fd;
struct thread_args send_block_args;
send_block_args.tid = 0;
int nthreadsstats = conf->nthreads;
stats_t *threads_anchor_rv[nthreadsstats];
stats_t *threads_chunk_rv[nthreadsstats];
stats_t *threads_compress_rv[nthreadsstats];
runSingleFarm( conf, &data_process_args, &send_block_args,
threads_anchor_rv, threads_chunk_rv, threads_compress_rv );
# 1197 "code_ff_ofarm.cpp"
if( conf->preloading ) {
free( preloading_buffer );
}
if ( conf->infile != NULL )
close( fd );
assert( !mbuffer_system_destroy( ) );
hashtable_destroy( cache, TRUE );
# 1218 "code_ff_ofarm.cpp"
}