summaryrefslogtreecommitdiff
path: root/db/record.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
committerAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
commit83957b73f9177f6e38bd5375bd93ca1f6a47188c (patch)
treef20b7d6ac9a9c64ff5bb6b5910a24abbb356b1d5 /db/record.cpp
parent5071d203970edd4c995493d810abe20987e76fe9 (diff)
Imported Upstream version 2.2.0upstream/2.2.0
Diffstat (limited to 'db/record.cpp')
-rw-r--r--db/record.cpp231
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;
- }
-
-}