// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. #include #include #include #include #include "db/prefetch_iter.h" #include "db/db_impl.h" #include "db/dbformat.h" #include "db/filename.h" #include "leveldb/env.h" #include "leveldb/iterator.h" #include "port/port.h" #include "util/logging.h" #include "util/mutexlock.h" #include "util/random.h" #include "port/port.h" namespace leveldb { namespace { // Memtables and sstables that make the DB representation contain // (userkey,seq,type) => uservalue entries. DBPreFetchIter // combines multiple entries for the same userkey found in the DB // representation into a single entry while accounting for sequence // numbers, deletion markers, overwrites, etc. class DBPreFetchIter : public Iterator { public: // Which direction is the iterator currently moving? // (1) When moving forward, the internal iterator is positioned at // the exact entry that yields this->key(), this->value() // (2) When moving backwards, the internal iterator is positioned // just before all entries whose user key == this->key(). enum IterPos {Left,Mid,Right}; DBPreFetchIter(DBImpl* db, Iterator* iter, Iterator* prefetch_iter,int prefetch_num) : db_(db),iter_(iter),prefetch_iter_(prefetch_iter),prefetch_num_(prefetch_num) {} DBPreFetchIter(const DBPreFetchIter&) = delete; DBPreFetchIter& operator=(const DBPreFetchIter&) = delete; ~DBPreFetchIter() override { // if(prefetch_thread.joinable()){ // stop_flag.store(true); // prefetch_thread.join(); // } delete prefetch_iter_; //std::cout<<"fetch:"<Valid(); } Slice key() const override { return iter_->key(); } Slice value() const override { // if(cur_pos>=0&&cur_pos<=1000000&&prefetched_array[cur_pos].load()){ // fetched_++; // return prefetch_array[cur_pos]; // } // else{ // unfetched_++; buf_for_value=std::move(GetAndParseTrueValue(iter_->value())); return Slice(buf_for_value.data(),buf_for_value.size()); //} } Status status() const override { return iter_->status(); } void Next() override; void Prev() override; void Seek(const Slice& target) override; void SeekToFirst() override; void SeekToLast() override; private: std::string GetAndParseTrueValue(Slice tmp_value)const{ Slice key; if(tmp_value.size()==0){ return ""; } if(tmp_value.data()[0]==(char)(0x00)){ tmp_value.remove_prefix(1); return std::string(tmp_value.data(),tmp_value.size()); } tmp_value.remove_prefix(1); uint64_t file_id,valuelog_offset; bool res=GetVarint64(&tmp_value,&file_id); if(!res)assert(0); res=GetVarint64(&tmp_value,&valuelog_offset); if(!res)assert(0); std::string str; Status s=db_->ReadValueLog(file_id,valuelog_offset, &key, &str); return str; } // void PreFetchThreadForward(){ // std::thread prefetch_threads[prefetch_num_]; // std::queue> q; // port::Mutex* lock=new port::Mutex(); // port::CondVar* cv=new port::CondVar(lock); // bool local_stop_flag=false; // int remaining_task_cnt=0; // bool main_finish=false; // for(int i=0;iLock(); // while(q.empty()&&!local_stop_flag&&!(remaining_task_cnt==0&&main_finish)){ // cv->Wait(); // } // if(local_stop_flag||(remaining_task_cnt==0&&main_finish)){ // cv->SignalAll(); // lock->Unlock(); // break; // } // std::string s=q.front().first; // pos=q.front().second; // q.pop(); // remaining_task_cnt--; // lock->Unlock(); // prefetch_array[pos]=std::move(GetAndParseTrueValue(s)); // prefetched_array[pos].store(true); // } // } // ); // } // Slice val; // int pos=0; // for(int i=0;i<100&&prefetch_iter_->Valid();i++){ // prefetch_iter_->Next(); // pos++; // } // for(;prefetch_iter_->Valid()&&!stop_flag.load()&&pos<1000000;prefetch_iter_->Next()){ // val=prefetch_iter_->value(); // lock->Lock(); // q.push({std::string(val.data(),val.size()),pos}); // cv->Signal(); // remaining_task_cnt++; // lock->Unlock(); // pos++; // } // lock->Lock(); // main_finish=true; // while(remaining_task_cnt){ // cv->Wait(); // } // lock->Unlock(); // cv->SignalAll(); // for (auto& thread : prefetch_threads) { // if (thread.joinable()) { // thread.join(); // } // } // } // void PreFetchThreadBackward(){ // std::thread prefetch_threads[prefetch_num_]; // std::queue> q; // port::Mutex* lock=new port::Mutex(); // port::CondVar* cv=new port::CondVar(lock); // bool local_stop_flag=false; // int remaining_task_cnt=0; // bool main_finish=false; // for(int i=0;iLock(); // while(q.empty()&&!local_stop_flag&&!(remaining_task_cnt==0&&main_finish)){ // cv->Wait(); // } // if(local_stop_flag||(remaining_task_cnt==0&&main_finish)){ // cv->SignalAll(); // lock->Unlock(); // break; // } // std::string s=q.front().first; // pos=q.front().second; // q.pop(); // remaining_task_cnt--; // lock->Unlock(); // prefetch_array[pos]=std::move(GetAndParseTrueValue(s)); // prefetched_array[pos].store(true); // } // } // ); // } // Slice val; // int pos=1000000; // for(;prefetch_iter_->Valid()&&!stop_flag.load()&&pos>=0;prefetch_iter_->Prev()){ // val=prefetch_iter_->value(); // lock->Lock(); // q.push({std::string(val.data(),val.size()),pos}); // cv->Signal(); // remaining_task_cnt++; // lock->Unlock(); // pos--; // } // lock->Lock(); // main_finish=true; // while(remaining_task_cnt){ // cv->Wait(); // } // lock->Unlock(); // cv->SignalAll(); // for (auto& thread : prefetch_threads) { // if (thread.joinable()) { // thread.join(); // } // } // } DBImpl* db_; Iterator* const iter_; Iterator* const prefetch_iter_; int prefetch_num_; // std::atomic stop_flag; // std::string prefetch_array[1000005]; // std::atomic prefetched_array[1000005]; std::thread prefetch_thread; mutable std::string buf_for_value; int cur_pos=0; mutable int fetched_=0; mutable int unfetched_=0; }; void DBPreFetchIter::Next() { iter_->Next(); //cur_pos++; } void DBPreFetchIter::Prev() { iter_->Prev(); //cur_pos--; } void DBPreFetchIter::Seek(const Slice& target) { iter_->Seek(target); // if(prefetch_thread.joinable()){ // stop_flag.store(true); // prefetch_thread.join(); // stop_flag=false; // } // for(int i=0;i<=1000000;i++)prefetched_array[i]=false; // cur_pos=0; // prefetch_iter_->Seek(target); // prefetch_thread=std::thread([this]() { // PreFetchThreadForward(); // }); } void DBPreFetchIter::SeekToFirst() { iter_->SeekToFirst(); // if(prefetch_thread.joinable()){ // stop_flag.store(true); // prefetch_thread.join(); // stop_flag=false; // } // for(int i=0;i<=1000000;i++)prefetched_array[i]=false; // cur_pos=0; // prefetch_iter_->SeekToFirst(); // prefetch_thread=std::thread([this]() { // PreFetchThreadForward(); // }); } void DBPreFetchIter::SeekToLast() { iter_->SeekToLast(); // if(prefetch_thread.joinable()){ // stop_flag.store(true); // prefetch_thread.join(); // stop_flag=false; // } // for(int i=0;i<=1000000;i++)prefetched_array[i]=false; // cur_pos=1000000; // prefetch_thread=std::thread([this]() { // prefetch_iter_->SeekToLast(); // PreFetchThreadBackward(); // }); } } // anonymous namespace Iterator* NewPreFetchIterator(DBImpl* db,Iterator* db_iter,Iterator* prefetch_iter,int prefetch_num) { return new DBPreFetchIter(db,db_iter,prefetch_iter,prefetch_num); } } // namespace leveldb