inline int freeBlockEntry(BlockEntry* blockEntry) { freeSlice(&blockEntry->key_); freeSlice(&blockEntry->value_); return 1; }
/* 成功则返回在segment中的偏移量,失败则返回1,应为offset不可能等于1 */ uint32_t scanSegment(const Block* block,const Segment* segment,DBhandle* dbhandle) { Slice lastKey; BlockEntry blockEntry; size_t tmp; size_t result; uint32_t offset = 0; unsigned char* b = block->data_ + segment->start_; printf("scanSegment:start_ = %u\n",segment->start_); initSlice(&lastKey,20); lastKey.size_ = 0; initBlockEntry(&blockEntry); while(offset < segment->size_){ tmp = decodeBlockEntry(&blockEntry,b+offset,&lastKey); //showBlockEntry(&blockEntry); printf("keysize = %zd,valuesize = %zd\n",blockEntry.key_.size_,blockEntry.value_.size_); //break; //showBlockEntry(&blockEntry); //showIndexBlockEntry(&blockEntry); result = compareKey(blockEntry.key_,dbhandle->key_); if(0 == result){ cpySlice(&dbhandle->value_,&blockEntry.value_); freeSlice(&lastKey); freeBlockEntry(&blockEntry); return offset; }else if(1 == result){ printf("Waring:Not Found!\n"); freeSlice(&lastKey); freeBlockEntry(&blockEntry); return 1; } offset += tmp; } freeSlice(&lastKey); freeBlockEntry(&blockEntry); return 1; }
void showBlockData(const Block* block) { size_t i; size_t offset = 0; Slice lastKey; BlockEntry blockEntry; initBlockEntry(&blockEntry); initSlice(&lastKey,20); do{ readBlockEntry(block,&blockEntry,&offset,&lastKey); showBlockEntry(&blockEntry); }while(offset < block->restart_offset); freeBlockEntry(&blockEntry); freeSlice(&lastKey); }
int segmentFix(Segment* segment,const Block* block,const Slice* key) { uint32_t low,mid,high; int result = -1; Slice midkey; initSlice(&midkey,20); low = 0; high = block->restartNum-1; while(low < high){ mid = low + high; mid = mid >> 1; printf("slow=%u,high=%u,mid=%u\n",low,high,mid); getBlockEntryKey(block->data_+block->restart_[mid],&midkey); result = compareKey(midkey,*key); if(result == 1){ high = mid; }else if(result == 2){ low = mid+1; mid = low; }else{ high = mid; low = mid; } } if(mid == 0){ printf("Waring: the first key of the block is bigger than key.\n"); } if(mid != 0){ mid--; } if(mid == (block->restartNum-1)){ segment->start_ = block->restart_[mid]; segment->size_ = block->restart_offset - block->restart_[mid]; }else{ segment->start_ = block->restart_[mid]; segment->size_ = block->restart_[mid+1] - block->restart_[mid]; } printf("Fixed finished!\nmid = %u,start_ = %u,size_ = %u\n",mid,segment->start_,segment->size_); midkey.size_ = 0; getBlockEntryKey(block->data_+segment->start_,&midkey); showKey(&midkey); printf("FIXFIX\n"); freeSlice(&midkey); return 1; }
/* * 读取sstable文件的Footer */ int readFooter(sequentialFile* psFile,Footer* pfooter) { unsigned char footerSpace[48]; long filesize; Slice r; initSlice(&r,20); int i; filesize = getFilesize(psFile); readSFile(48,filesize-48,psFile,footerSpace); setSlice(&r,footerSpace,48); decodeFooter(pfooter,&r); for(i = 0;i < 48;i++){ printXchar(r.data_[i]); } freeSlice(&r); printf("file size = %ld,footersize = %zd\n",filesize,r.size_); return 0; }
void showBlokRestart(const Block* block) { size_t i; size_t offset = 0; Slice lastKey; BlockEntry blockEntry; initBlockEntry(&blockEntry); initSlice(&lastKey,20); for(i = 0;i < block->restartNum;i++){ offset = 0; lastKey.size_ = 0; offset = block->restart_[i]; readBlockEntry(block,&blockEntry,&offset,&lastKey); showIndexBlockEntry(&blockEntry); } freeBlockEntry(&blockEntry); freeSlice(&lastKey); }
/* * 批量读取block数据 */ int readAllBlock(sequentialFile* psFile,Block* blockArray,const Block* dataIndexBlock) { printf("Read All Block.\n"); //printf("%s(%d)-<%s>: ",__FILE__, __LINE__, __FUNCTION__); uint32_t i = 0; BlockHandle blockHandle; BlockEntry blockEntry; unsigned char* data; Slice lastKey; initSlice(&lastKey,20); initBlockEntry(&blockEntry); for(i = 0;i < dataIndexBlock->restartNum;i++){ data =(unsigned char*) (dataIndexBlock->data_+dataIndexBlock->restart_[i]); decodeBlockEntry(&blockEntry,data,&lastKey); decodeBlockHandle(&blockHandle,&blockEntry.value_); readBlock(psFile,&blockArray[i],blockHandle); //showBlock(&blockArray[i]); } freeBlockEntry(&blockEntry); freeSlice(&lastKey); return 0; }
static THREAD_RETURN netSenderMain(void *args0) { sender_state_t sendst = (sender_state_t) args0; struct net_config *config = sendst->config; struct timeval tv; struct timespec ts; int atEnd = 0; int nrWaited=0; unsigned long waitAverage=10000; /* Exponential average of last wait times */ struct slice *xmitSlice=NULL; /* slice being transmitted a first time */ struct slice *rexmitSlice=NULL; /* slice being re-transmitted */ int sliceNo = 0; /* transmit the data */ if(config->default_slice_size == 0) { #ifdef BB_FEATURE_UDPCAST_FEC if(config->flags & FLAG_FEC) { config->sliceSize = config->fec_stripesize * config->fec_stripes; } else #endif if(config->flags & FLAG_ASYNC) config->sliceSize = 1024; else if (sendst->config->flags & FLAG_SN) { sendst->config->sliceSize = 112; } else sendst->config->sliceSize = 130; sendst->config->discovery = DSC_DOUBLING; } else { config->sliceSize = config->default_slice_size; #ifdef BB_FEATURE_UDPCAST_FEC if((config->flags & FLAG_FEC) && (config->sliceSize > 128 * config->fec_stripes)) config->sliceSize = 128 * config->fec_stripes; #endif } #ifdef BB_FEATURE_UDPCAST_FEC if( (sendst->config->flags & FLAG_FEC) && config->max_slice_size > config->fec_stripes * 128) config->max_slice_size = config->fec_stripes * 128; #endif if(config->sliceSize > config->max_slice_size) config->sliceSize = config->max_slice_size; assert(config->sliceSize <= MAX_SLICE_SIZE); do { /* first, cleanup rexmit Slice if needed */ if(rexmitSlice != NULL) { if(rexmitSlice->nrReady == udpc_nrParticipants(sendst->rc.participantsDb)){ #if DEBUG flprintf("slice is ready\n"); #endif ackSlice(rexmitSlice, sendst->config, sendst->fifo, sendst->stats); } if(isSliceAcked(rexmitSlice)) { freeSlice(sendst, rexmitSlice); rexmitSlice = NULL; } } /* then shift xmit slice to rexmit slot, if possible */ if(rexmitSlice == NULL && xmitSlice != NULL && isSliceXmitted(xmitSlice)) { rexmitSlice = xmitSlice; xmitSlice = NULL; sendReqack(rexmitSlice, sendst->config, sendst->fifo, sendst->stats, sendst->socket); } /* handle any messages */ if(pc_getWaiting(sendst->rc.incoming)) { #if DEBUG flprintf("Before message %d\n", pc_getWaiting(sendst->rc.incoming)); #endif handleNextMessage(sendst, xmitSlice, rexmitSlice); /* restart at beginning of loop: we may have acked the rxmit * slice, makeing it possible to shift the pipe */ continue; } /* do any needed retransmissions */ if(rexmitSlice != NULL && rexmitSlice->needRxmit) { doRetransmissions(sendst, rexmitSlice); /* restart at beginning: new messages may have arrived during * retransmission */ continue; } /* if all participants answered, send req ack */ if(rexmitSlice != NULL && rexmitSlice->nrAnswered == udpc_nrParticipants(sendst->rc.participantsDb)) { rexmitSlice->rxmitId++; sendReqack(rexmitSlice, sendst->config, sendst->fifo, sendst->stats, sendst->socket); } if(xmitSlice == NULL && !atEnd) { #if DEBUG flprintf("SN=%d\n", sendst->config->flags & FLAG_SN); #endif if((sendst->config->flags & FLAG_SN) || rexmitSlice == NULL) { #ifdef BB_FEATURE_UDPCAST_FEC if(sendst->config->flags & FLAG_FEC) { int i; pc_consume(sendst->fec_data_pc, 1); i = pc_getConsumerPosition(sendst->fec_data_pc); xmitSlice = &sendst->slices[i]; pc_consumed(sendst->fec_data_pc, 1); } else #endif { xmitSlice = makeSlice(sendst, sliceNo++); } if(xmitSlice->bytes == 0) atEnd = 1; } } if(xmitSlice != NULL && xmitSlice->state == SLICE_NEW) { sendSlice(sendst, xmitSlice, 0); #if DEBUG flprintf("%d Interrupted at %d/%d\n", xmitSlice->sliceNo, xmitSlice->nextBlock, getSliceBlocks(xmitSlice, sendst->config)); #endif continue; } if(atEnd && rexmitSlice == NULL && xmitSlice == NULL) break; if(sendst->config->flags & FLAG_ASYNC) break; #if DEBUG flprintf("Waiting for timeout...\n"); #endif gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec; ts.tv_nsec = (tv.tv_usec + 1.1*waitAverage) * 1000; #ifdef WINDOWS /* Windows has a granularity of 1 millisecond in its timer. Take this * into account here */ #define GRANULARITY 1000000 ts.tv_nsec += 3*GRANULARITY/2; ts.tv_nsec -= ts.tv_nsec % GRANULARITY; #endif #define BILLION 1000000000 while(ts.tv_nsec >= BILLION) { ts.tv_nsec -= BILLION; ts.tv_sec++; } if(rexmitSlice->rxmitId > 10) /* after tenth retransmission, wait minimum one second */ ts.tv_sec++; if(pc_consumeAnyWithTimeout(sendst->rc.incoming, &ts) != 0) { #if DEBUG flprintf("Have data\n"); #endif { struct timeval tv2; unsigned long timeout; gettimeofday(&tv2, 0); timeout = (tv2.tv_sec - tv.tv_sec) * 1000000+ tv2.tv_usec - tv.tv_usec; if(nrWaited) timeout += waitAverage; waitAverage += 9; /* compensate against rounding errors */ waitAverage = (0.9 * waitAverage + 0.1 * timeout); } nrWaited = 0; continue; } if(rexmitSlice == NULL) { udpc_flprintf("Weird. Timeout and no rxmit slice"); break; } if(nrWaited > 5){ #ifndef WINDOWS /* on Cygwin, we would get too many of those messages... */ udpc_flprintf("Timeout notAnswered="); udpc_printNotSet(sendst->rc.participantsDb, rexmitSlice->answeredSet); udpc_flprintf(" notReady="); udpc_printNotSet(sendst->rc.participantsDb, rexmitSlice->sl_reqack.readySet); udpc_flprintf(" nrAns=%d nrRead=%d nrPart=%d avg=%ld\n", rexmitSlice->nrAnswered, rexmitSlice->nrReady, udpc_nrParticipants(sendst->rc.participantsDb), waitAverage); nrWaited=0; #endif } nrWaited++; if(rexmitSlice->rxmitId > config->retriesUntilDrop) { int i; for(i=0; i < MAX_CLIENTS; i++) { if(udpc_isParticipantValid(sendst->rc.participantsDb, i) && !BIT_ISSET(i, rexmitSlice->sl_reqack.readySet)) { udpc_flprintf("Dropping client #%d because of timeout\n", i); #ifdef USE_SYSLOG syslog(LOG_INFO, "dropped client #%d because of timeout", i); #endif udpc_removeParticipant(sendst->rc.participantsDb, i); if(nrParticipants(sendst->rc.participantsDb) == 0) exit(0); } } continue; } rexmitSlice->rxmitId++; sendReqack(rexmitSlice, sendst->config, sendst->fifo, sendst->stats, sendst->socket); } while(udpc_nrParticipants(sendst->rc.participantsDb)|| (config->flags & FLAG_ASYNC)); cancelReturnChannel(&sendst->rc); return 0; }
void freeEntrykey(Entrykey* entrykey){ freeSlice(&entrykey->nosharedkey); }