/** * @brief Get the total number of data items used. * @return The number of data items used in all chunks. */ inline size_t getDataSize() { size_t size = curChunk->getUsedSize(); if(getNumChunks() != 0) { size += (getNumChunks() - 1) * chunkSize; } return size; }
void TFileTransport::seekToChunk(int32_t chunk) { if (fd_ <= 0) { throw TTransportException("File not open"); } int32_t numChunks = getNumChunks(); // file is empty, seeking to chunk is pointless if (numChunks == 0) { return; } // negative indicates reverse seek (from the end) if (chunk < 0) { chunk += numChunks; } // too large a value for reverse seek, just seek to beginning if (chunk < 0) { T_DEBUG("%s", "Incorrect value for reverse seek. Seeking to beginning..."); chunk = 0; } // cannot seek past EOF bool seekToEnd = false; off_t minEndOffset = 0; if (chunk >= numChunks) { T_DEBUG("%s", "Trying to seek past EOF. Seeking to EOF instead..."); seekToEnd = true; chunk = numChunks - 1; // this is the min offset to process events till minEndOffset = lseek(fd_, 0, SEEK_END); } off_t newOffset = off_t(chunk) * chunkSize_; offset_ = lseek(fd_, newOffset, SEEK_SET); readState_.resetAllValues(); currentEvent_ = NULL; if (offset_ == -1) { GlobalOutput("TFileTransport: lseek error in seekToChunk"); throw TTransportException("TFileTransport: lseek error in seekToChunk"); } // seek to EOF if user wanted to go to last chunk if (seekToEnd) { uint32_t oldReadTimeout = getReadTimeout(); setReadTimeout(NO_TAIL_READ_TIMEOUT); // keep on reading unti the last event at point of seekChunk call boost::scoped_ptr<eventInfo> event; while ((offset_ + readState_.bufferPtr_) < minEndOffset) { event.reset(readEvent()); if (event.get() == NULL) { break; } } setReadTimeout(oldReadTimeout); } }
void TFileTransport::performRecovery() { // perform some kickass recovery uint32_t curChunk = getCurChunk(); if (lastBadChunk_ == curChunk) { numCorruptedEventsInChunk_++; } else { lastBadChunk_ = curChunk; numCorruptedEventsInChunk_ = 1; } if (numCorruptedEventsInChunk_ < maxCorruptedEvents_) { // maybe there was an error in reading the file from disk // seek to the beginning of chunk and try again seekToChunk(curChunk); } else { // just skip ahead to the next chunk if we not already at the last chunk if (curChunk != (getNumChunks() - 1)) { seekToChunk(curChunk + 1); } else if (readTimeout_ == TAIL_READ_TIMEOUT) { // if tailing the file, wait until there is enough data to start // the next chunk while(curChunk == (getNumChunks() - 1)) { usleep(DEFAULT_CORRUPTED_SLEEP_TIME_US); } seekToChunk(curChunk + 1); } else { // pretty hosed at this stage, rewind the file back to the last successful // point and punt on the error readState_.resetState(readState_.lastDispatchPtr_); currentEvent_ = NULL; char errorMsg[1024]; sprintf(errorMsg, "TFileTransport: log file corrupted at offset: %lu", (offset_ + readState_.lastDispatchPtr_)); GlobalOutput(errorMsg); throw TTransportException(errorMsg); } } }
int main (int argc, char ** argv){ if(argc != 5) usage(1); getoptions(argc, argv); if(DEBUG){ printf("port: %d\n", port); printf("fileOpt: %s\n", fileOpt); } int fd, bytesRead, fileSize, counter, i; char* inFile = "./tracker.txt"; FILE * trackFp =fopen(inFile, "r"); if(trackFp == NULL) errorExit("bad Tracker"); int numlines = numLines(inFile); if(DEBUG) printf("Numlines:%d\n", numlines); tracker * tracks = malloc ( numlines * sizeof(tracker)); buildTracker(tracks, trackFp); //sort the tracks to make easier for later. Look @ compare to see sort order qsort (tracks, numlines, sizeof(tracks[0]), compare); if(DEBUG){ for(i =0; i < numlines ; ++i) printTrack(tracks[i]); } //now we have all information in memory int numChunks = getNumChunks(tracks, fileOpt, numlines); printf("numChunks:%d\n", numChunks); sd = UDP_Open(-1); assert(sd > -1); for(i=1; i <= numChunks; ++i){ packArgs argsP = getIDParams(tracks, fileOpt, i, numlines); if(DEBUG > 1) printf("host:%s, port:%d\n", argsP.hostname, argsP.port); getPackets(argsP.hostname, argsP.port); } return 0; }
gridfs_offset GridFile::write( ostream & out ) { _exists(); const int num = getNumChunks(); for ( int i=0; i<num; i++ ) { GridFSChunk c = getChunk( i ); int len; const char * data = c.data( len ); out.write( data , len ); } return getContentLength(); }
void TFileTransport::seekToEnd() { seekToChunk(getNumChunks()); }