static uint32_t Hash(const char* data, size_t n, uint32_t seed) { // Similar to murmur hash const uint32_t m = 0xc6a4a793; const uint32_t r = 24; const char* limit = data + n; uint32_t h = seed ^ (n * m); // Pick up four bytes at a time while (data + 4 <= limit) { uint32_t w = DecodeFixed32(data); data += 4; h += w; h *= m; h ^= (h >> 16); } // Pick up remaining bytes switch (limit - data) { case 3: h += data[2] << 16; FALLTHROUGH_INTENDED; case 2: h += data[1] << 8; FALLTHROUGH_INTENDED; case 1: h += data[0]; h *= m; h ^= (h >> r); break; } return h; }
unsigned int Reader::ReadPhysicalRecord(string &result, uint32_t &id, uint32_t &blockid) { while (true) { //cout << "buffer_.size: "<< buffer_.size() << endl; if (buffer_.size() < kHeaderSize) { if (!eof_) { // Last read was a full read, so this is a trailer to skip buffer_.clear(); bool s = file_->Read(kBlockSize, buffer_, backing_store_); end_of_buffer_offset_ += buffer_.size(); read_block_num_++; //Version::Instance()->SetBlockId(); if (!s) { buffer_.clear(); ReportDrop(kBlockSize); eof_ = true; return kEof; } else if (buffer_.size() < kBlockSize) { eof_ = true; } continue; } else if (buffer_.size() == 0) { // End of file return kEof; } else { //size_t drop_size = buffer_.size(); buffer_.clear(); return kEof; } } if(offset_in_block_ > 0) { buffer_ = buffer_.substr(offset_in_block_); offset_in_block_ = 0; } // Parse the header const char* header = buffer_.data(); const uint32_t a = static_cast<uint32_t>(header[4]) & 0xff; const uint32_t b = static_cast<uint32_t>(header[5]) & 0xff; const unsigned int type = header[6]; const uint32_t length = a | (b << 8); //blockid const uint32_t c = static_cast<uint32_t>(header[7]) & 0xff; const uint32_t d = static_cast<uint32_t>(header[8]) & 0xff; const uint32_t bid = c | (d << 8); //interid const uint32_t e = static_cast<uint32_t>(header[9]) & 0xff; const uint32_t f = static_cast<uint32_t>(header[10]) & 0xff; const uint32_t iid = e | (f << 8); id = iid | (bid << 16); blockid = bid; if (kHeaderSize + length > buffer_.size()) { size_t drop_size = buffer_.size(); buffer_.clear(); cout << drop_size << " bad record length" << endl; return kBadRecord; } if (type == kZeroType && length == 0) { // Skip zero length record without reporting any drops since // such records are produced by the mmap based writing code in // env_posix.cc that preallocates file regions. buffer_.clear(); return kBadRecord; } uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header)); uint32_t actual_crc = crc32c::Value(header + 11, length); if (actual_crc != expected_crc) { cout << "crc32 failed " << endl; return kBadRecord; } //buffer_.remove_prefix(kHeaderSize + length); // Skip physical record that started before initial_offset_ if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length < initial_offset_) { result.clear(); return kBadRecord; } result.assign(header + kHeaderSize, length); buffer_ = buffer_.substr(kHeaderSize + length); return type; } }
int WriteBatchInternal::Count(const WriteBatch* b) { return DecodeFixed32(b->rep_.data() + 8); }