@ -36,11 +36,15 @@ class VectorRep : public MemTableRep {
virtual ~ VectorRep ( ) override { }
class Iterator : public MemTableRep : : Iterator {
class VectorRep * vrep_ ;
std : : shared_ptr < std : : vector < const char * > > bucket_ ;
typename std : : vector < const char * > : : const_iterator cit_ ;
typename std : : vector < const char * > : : const_iterator mutable cit_ ;
const KeyComparator & compare_ ;
bool mutable sorted_ ;
void DoSort ( ) const ;
public :
explicit Iterator ( std : : shared_ptr < std : : vector < const char * > > bucket ,
explicit Iterator ( class VectorRep * vrep ,
std : : shared_ptr < std : : vector < const char * > > bucket ,
const KeyComparator & compare ) ;
// Initialize an iterator over the specified collection.
@ -82,11 +86,12 @@ class VectorRep : public MemTableRep {
virtual std : : shared_ptr < MemTableRep : : Iterator > GetIterator ( ) override ;
private :
friend class Iterator ;
typedef std : : vector < const char * > Bucket ;
std : : shared_ptr < Bucket > bucket_ ;
mutable port : : RWMutex rwlock_ ;
bool immutable_ = false ;
bool sorted_ = false ;
bool immutable_ ;
bool sorted_ ;
const KeyComparator & compare_ ;
} ;
@ -119,16 +124,42 @@ size_t VectorRep::ApproximateMemoryUsage() {
VectorRep : : VectorRep ( const KeyComparator & compare , Arena * arena , size_t count )
: bucket_ ( new Bucket ( count ) ) ,
immutable_ ( false ) ,
sorted_ ( false ) ,
compare_ ( compare ) { }
VectorRep : : Iterator : : Iterator ( std : : shared_ptr < std : : vector < const char * > > bucket ,
VectorRep : : Iterator : : Iterator ( class VectorRep * vrep ,
std : : shared_ptr < std : : vector < const char * > > bucket ,
const KeyComparator & compare )
: bucket_ ( bucket ) ,
cit_ ( bucket_ - > begin ( ) ) ,
compare_ ( compare ) { }
: vrep_ ( vrep ) ,
bucket_ ( bucket ) ,
cit_ ( nullptr ) ,
compare_ ( compare ) ,
sorted_ ( false ) { }
void VectorRep : : Iterator : : DoSort ( ) const {
// vrep is non-null means that we are working on an immutable memtable
if ( ! sorted_ & & vrep_ ! = nullptr ) {
WriteLock l ( & vrep_ - > rwlock_ ) ;
if ( ! vrep_ - > sorted_ ) {
std : : sort ( bucket_ - > begin ( ) , bucket_ - > end ( ) , Compare ( compare_ ) ) ;
cit_ = bucket_ - > begin ( ) ;
vrep_ - > sorted_ = true ;
}
sorted_ = true ;
}
if ( ! sorted_ ) {
std : : sort ( bucket_ - > begin ( ) , bucket_ - > end ( ) , Compare ( compare_ ) ) ;
cit_ = bucket_ - > begin ( ) ;
sorted_ = true ;
}
assert ( sorted_ ) ;
assert ( vrep_ = = nullptr | | vrep_ - > sorted_ ) ;
}
// Returns true iff the iterator is positioned at a valid node.
bool VectorRep : : Iterator : : Valid ( ) const {
DoSort ( ) ;
return cit_ ! = bucket_ - > end ( ) ;
}
@ -165,6 +196,7 @@ void VectorRep::Iterator::Prev() {
// Advance to the first entry with a key >= target
void VectorRep : : Iterator : : Seek ( const char * target ) {
DoSort ( ) ;
// Do binary search to find first value not less than the target
cit_ = std : : equal_range ( bucket_ - > begin ( ) ,
bucket_ - > end ( ) ,
@ -177,12 +209,14 @@ void VectorRep::Iterator::Seek(const char* target) {
// Position at the first entry in collection.
// Final state of iterator is Valid() iff collection is not empty.
void VectorRep : : Iterator : : SeekToFirst ( ) {
DoSort ( ) ;
cit_ = bucket_ - > begin ( ) ;
}
// Position at the last entry in collection.
// Final state of iterator is Valid() iff collection is not empty.
void VectorRep : : Iterator : : SeekToLast ( ) {
DoSort ( ) ;
cit_ = bucket_ - > end ( ) ;
if ( bucket_ - > size ( ) ! = 0 ) {
- - cit_ ;
@ -190,21 +224,16 @@ void VectorRep::Iterator::SeekToLast() {
}
std : : shared_ptr < MemTableRep : : Iterator > VectorRep : : GetIterator ( ) {
std : : shared_ptr < Bucket > tmp ;
ReadLock l ( & rwlock_ ) ;
// Do not sort here. The sorting would be done the first time
// a Seek is performed on the iterator.
if ( immutable_ ) {
rwlock_ . Unlock ( ) ;
rwlock_ . WriteLock ( ) ;
tmp = bucket_ ;
if ( ! sorted_ ) {
std : : sort ( tmp - > begin ( ) , tmp - > end ( ) , Compare ( compare_ ) ) ;
sorted_ = true ;
}
return std : : make_shared < Iterator > ( this , bucket_ , compare_ ) ;
} else {
std : : shared_ptr < Bucket > tmp ;
tmp . reset ( new Bucket ( * bucket_ ) ) ; // make a copy
std : : sort ( tmp - > begin ( ) , tmp - > end ( ) , Compare ( compare_ ) ) ;
return std : : make_shared < Iterator > ( nullptr , tmp , compare_ ) ;
}
return std : : make_shared < Iterator > ( tmp , compare_ ) ;
}
} // anon namespace