diff options
| author | Antonin Kral <a.kral@bobek.cz> | 2012-08-29 20:54:51 +0200 |
|---|---|---|
| committer | Antonin Kral <a.kral@bobek.cz> | 2012-08-29 20:54:51 +0200 |
| commit | 83957b73f9177f6e38bd5375bd93ca1f6a47188c (patch) | |
| tree | f20b7d6ac9a9c64ff5bb6b5910a24abbb356b1d5 /db/record.cpp | |
| parent | 5071d203970edd4c995493d810abe20987e76fe9 (diff) | |
Imported Upstream version 2.2.0upstream/2.2.0
Diffstat (limited to 'db/record.cpp')
| -rw-r--r-- | db/record.cpp | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/db/record.cpp b/db/record.cpp deleted file mode 100644 index a8a3e43d024..00000000000 --- a/db/record.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// record.cpp - -#include "pch.h" -#include "pdfile.h" -#include "../util/processinfo.h" -#include "../util/net/listen.h" - -namespace mongo { - - namespace ps { - - enum State { - In , Out, Unk - }; - - enum Constants { - SliceSize = 65536 , - MaxChain = 20 , // intentionally very low - NumSlices = 10 , - RotateTimeSecs = 90 - }; - - int hash( size_t region ) { - return - abs( ( ( 7 + (int)(region & 0xFFFF) ) - * ( 11 + (int)( ( region >> 16 ) & 0xFFFF ) ) -#if defined(_WIN64) || defined(__amd64__) - * ( 13 + (int)( ( region >> 32 ) & 0xFFFF ) ) - * ( 17 + (int)( ( region >> 48 ) & 0xFFFF ) ) -#endif - ) % SliceSize ); - } - - - /** - * simple hash map for region -> status - * this constitures a single region of time - * it does chaining, but very short chains - */ - class Slice { - - struct Entry { - size_t region; - unsigned long long value; - }; - - public: - - Slice() { - reset(); - } - - void reset() { - memset( _data , 0 , SliceSize * sizeof(Entry) ); - } - - State get( int regionHash , size_t region , short offset ) { - DEV assert( hash( region ) == regionHash ); - - Entry * e = _get( regionHash , region , false ); - if ( ! e ) - return Unk; - - return ( e->value & ( ((unsigned long long)1) << offset ) ) ? In : Out; - } - - /** - * @return true if added, false if full - */ - bool in( int regionHash , size_t region , short offset ) { - DEV assert( hash( region ) == regionHash ); - - Entry * e = _get( regionHash , region , true ); - if ( ! e ) - return false; - - e->value |= ((unsigned long long)1) << offset; - return true; - } - - private: - - Entry* _get( int start , size_t region , bool add ) { - for ( int i=0; i<MaxChain; i++ ) { - - int bucket = ( start + i ) % SliceSize; - - if ( _data[bucket].region == 0 ) { - if ( ! add ) - return 0; - - _data[bucket].region = region; - return &_data[bucket]; - } - - if ( _data[bucket].region == region ) { - return &_data[bucket]; - } - } - return 0; - } - - Entry _data[SliceSize]; - }; - - - /** - * this contains many slices of times - * the idea you put mem status in the current time slice - * and then after a certain period of time, it rolls off so we check again - */ - class Rolling { - - public: - Rolling() - : _lock( "ps::Rolling" ){ - _curSlice = 0; - _lastRotate = Listener::getElapsedTimeMillis(); - } - - - /** - * after this call, we assume the page is in ram - * @param doHalf if this is a known good access, want to put in first half - * @return whether we know the page is in ram - */ - bool access( size_t region , short offset , bool doHalf ) { - int regionHash = hash(region); - - SimpleMutex::scoped_lock lk( _lock ); - - static int rarely_count = 0; - if ( rarely_count++ % 2048 == 0 ) { - long long now = Listener::getElapsedTimeMillis(); - RARELY if ( now == 0 ) { - tlog() << "warning Listener::getElapsedTimeMillis returning 0ms" << endl; - } - - if ( now - _lastRotate > ( 1000 * RotateTimeSecs ) ) { - _rotate(); - } - } - - for ( int i=0; i<NumSlices / ( doHalf ? 2 : 1 ); i++ ) { - int pos = (_curSlice+i)%NumSlices; - State s = _slices[pos].get( regionHash , region , offset ); - - if ( s == In ) - return true; - - if ( s == Out ) { - _slices[pos].in( regionHash , region , offset ); - return false; - } - } - - // we weren't in any slice - // so add to cur - if ( ! _slices[_curSlice].in( regionHash , region , offset ) ) { - _rotate(); - _slices[_curSlice].in( regionHash , region , offset ); - } - return false; - } - - private: - - void _rotate() { - _curSlice = ( _curSlice + 1 ) % NumSlices; - _slices[_curSlice].reset(); - _lastRotate = Listener::getElapsedTimeMillis(); - } - - int _curSlice; - long long _lastRotate; - Slice _slices[NumSlices]; - - SimpleMutex _lock; - } rolling; - - } - - bool Record::MemoryTrackingEnabled = true; - - - volatile int __record_touch_dummy = 1; // this is used to make sure the compiler doesn't get too smart on us - void Record::touch( bool entireRecrd ) { - - if ( lengthWithHeaders > HeaderSize ) { // this also makes sure lengthWithHeaders is in memory - char * addr = data; - char * end = data + netLength(); - for ( ; addr <= end ; addr += 2048 ) { - __record_touch_dummy += addr[0]; - - break; // TODO: remove this, pending SERVER-3711 - - if ( ! entireRecrd ) - break; - } - } - - } - - bool Record::likelyInPhysicalMemory() { - if ( ! MemoryTrackingEnabled ) - return true; - - static bool blockSupported = ProcessInfo::blockCheckSupported(); - - const size_t page = (size_t)data >> 12; - const size_t region = page >> 6; - const size_t offset = page & 0x3f; - - if ( ps::rolling.access( region , offset , false ) ) - return true; - - if ( ! blockSupported ) - return false; - return ProcessInfo::blockInMemory( data ); - } - - Record* Record::accessed() { - const size_t page = (size_t)data >> 12; - const size_t region = page >> 6; - const size_t offset = page & 0x3f; - - ps::rolling.access( region , offset , true ); - return this; - } - -} |
