preprocessed_ofarm.cpp

          # 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"
          }