autodriver/autodriver.c
void *timestampFunc() {
  time_t lastStamp = 0;
  int lastJumpIndex = -1;
  int output_fd;

  // open output file read only to build timestamp:offset map
  if ((output_fd = open(OUTPUT_FILE, O_RDONLY)) < 0) {
    ERROR_ERRNO("Opening output file by parent process");
    // don't quit for this type of error
  }

  while (1) {
    if (childFinished) {
      break;
    }

    sleep(1);

    // allocate/reallocate space to create/grow the map
    if (timestampCount % TIMESTAMP_MAP_CHUNK_SIZE == 0) {
      timestamp_map_t *newBuffer =
        realloc(timestampMap,
                sizeof(timestamp_map_t) * (TIMESTAMP_MAP_CHUNK_SIZE + timestampCount));
      if (!newBuffer){
        ERROR_ERRNO("Failed to allocate timestamp map. Current map size %d",
                    timestampCount);
        continue;  // continue without allocation
      }
      timestampMap = newBuffer;
      newBuffer += timestampCount;
      memset(newBuffer, 0, sizeof(timestamp_map_t) * TIMESTAMP_MAP_CHUNK_SIZE);
    }

    struct stat buf;
    if (output_fd <= 0 || fstat(output_fd, &buf) < 0) {
      ERROR_ERRNO("Statting output file to read offset");
      continue;  // simply skip this time
    }

    size_t currentOffset = buf.st_size;
    time_t currentTime = time(NULL);

    // record following timestamps:
    // 1. enough time has passed since last timestamp or
    // 2. output has grown and enough time has passed since last offset change

    if (timestampCount == 0 ||
        timestampMap[timestampCount - 1].offset != currentOffset) {
      if (lastJumpIndex >= 0 &&
          currentTime - timestampMap[lastJumpIndex].time < args.timestamp_interval) {
        continue;
      }
      lastJumpIndex = timestampCount;
    } else if (currentTime - lastStamp < args.timestamp_interval) {
      continue;
    }

    lastStamp = currentTime;
    timestampMap[timestampCount].time = currentTime;
    timestampMap[timestampCount].offset = currentOffset;
    timestampCount++;
  }

  if (output_fd <= 0 || close(output_fd) < 0) {
    ERROR_ERRNO("Closing output file before cleanup");
  }
  return NULL;
}
// pthread function, keep a map of timestamp and user's output file offset.
// The thread is not started unless timestamp interval option is specified.
pthread function, keep a map of timestamp and user's output file offset.
The thread is not started unless timestamp interval option is specified.
pthread function keep a map of timestamp and user ' s output file offset . The thread is not started unless timestamp interval option is specified .
void *timestampFunc() {
  time_t lastStamp = 0;
  int lastJumpIndex = -1;
  int output_fd;
  if ((output_fd = open(OUTPUT_FILE, O_RDONLY)) < 0) {
    ERROR_ERRNO("Opening output file by parent process");
  }
  while (1) {
    if (childFinished) {
      break;
    }
    sleep(1);
    if (timestampCount % TIMESTAMP_MAP_CHUNK_SIZE == 0) {
      timestamp_map_t *newBuffer =
        realloc(timestampMap,
                sizeof(timestamp_map_t) * (TIMESTAMP_MAP_CHUNK_SIZE + timestampCount));
      if (!newBuffer){
        ERROR_ERRNO("Failed to allocate timestamp map. Current map size %d",
                    timestampCount);
        continue;  
      }
      timestampMap = newBuffer;
      newBuffer += timestampCount;
      memset(newBuffer, 0, sizeof(timestamp_map_t) * TIMESTAMP_MAP_CHUNK_SIZE);
    }
    struct stat buf;
    if (output_fd <= 0 || fstat(output_fd, &buf) < 0) {
      ERROR_ERRNO("Statting output file to read offset");
      continue;  
    }
    size_t currentOffset = buf.st_size;
    time_t currentTime = time(NULL);
    if (timestampCount == 0 ||
        timestampMap[timestampCount - 1].offset != currentOffset) {
      if (lastJumpIndex >= 0 &&
          currentTime - timestampMap[lastJumpIndex].time < args.timestamp_interval) {
        continue;
      }
      lastJumpIndex = timestampCount;
    } else if (currentTime - lastStamp < args.timestamp_interval) {
      continue;
    }
    lastStamp = currentTime;
    timestampMap[timestampCount].time = currentTime;
    timestampMap[timestampCount].offset = currentOffset;
    timestampCount++;
  }
  if (output_fd <= 0 || close(output_fd) < 0) {
    ERROR_ERRNO("Closing output file before cleanup");
  }
  return NULL;
}
void * timestampFunc ( ) { time_t lastStamp = 0 ; int lastJumpIndex = -1 ; int output_fd ; if ( ( output_fd = open ( OUTPUT_FILE , O_RDONLY ) ) < 0 ) { ERROR_ERRNO ( " " ) ; } while ( 1 ) { if ( childFinished ) { break ; } sleep ( 1 ) ; if ( timestampCount % TIMESTAMP_MAP_CHUNK_SIZE == 0 ) { timestamp_map_t * newBuffer = realloc ( timestampMap , sizeof ( timestamp_map_t ) * ( TIMESTAMP_MAP_CHUNK_SIZE + timestampCount ) ) ; if ( ! newBuffer ) { ERROR_ERRNO ( " " , timestampCount ) ; continue ; } timestampMap = newBuffer ; newBuffer += timestampCount ; memset ( newBuffer , 0 , sizeof ( timestamp_map_t ) * TIMESTAMP_MAP_CHUNK_SIZE ) ; } struct stat buf ; if ( output_fd <= 0 || fstat ( output_fd , & buf ) < 0 ) { ERROR_ERRNO ( " " ) ; continue ; } size_t currentOffset = buf . st_size ; time_t currentTime = time ( NULL ) ; if ( timestampCount == 0 || timestampMap [ timestampCount - 1 ] . offset != currentOffset ) { if ( lastJumpIndex >= 0 && currentTime - timestampMap [ lastJumpIndex ] . time < args . timestamp_interval ) { continue ; } lastJumpIndex = timestampCount ; } else if ( currentTime - lastStamp < args . timestamp_interval ) { continue ; } lastStamp = currentTime ; timestampMap [ timestampCount ] . time = currentTime ; timestampMap [ timestampCount ] . offset = currentOffset ; timestampCount ++ ; } if ( output_fd <= 0 || close ( output_fd ) < 0 ) { ERROR_ERRNO ( " " ) ; } return NULL ; }
pthread function, keep a map of timestamp and user's output file offset.
pthread function keep a map of timestamp and user ' s output file offset .
// open output file read only to build timestamp:offset map // don't quit for this type of error // allocate/reallocate space to create/grow the map // continue without allocation // simply skip this time // record following timestamps: // 1. enough time has passed since last timestamp or // 2. output has grown and enough time has passed since last offset change