/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// #include "Enumerator.h" using namespace JetBrains::Omea::Base; using namespace JetBrains::Omea::Containers; namespace DBIndex { static void TranslateNativeKey2ManagedKey( int type, const BTreeKeyBase* nativeKey, KeyPair* managedKey ) { switch( type ) { case int_Key: { const BTreeKey* intKey = static_cast< const BTreeKey* >( nativeKey ); managedKey->_key->SetIntKey( intKey->GetKey() ); break; } case long_Key: { const BTreeKey* longKey = static_cast< const BTreeKey* >( nativeKey ); managedKey->_key->Key = dynamic_cast< System::IComparable* >( __box( longKey->GetKey() ) ); break; } case int_int_Key: { const BTreeKey< CompoundKey >* cKey = static_cast< const BTreeKey< CompoundKey >* >( nativeKey ); Compound* compound = dynamic_cast( managedKey->_key->Key ); compound->_key1 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._first ) ); compound->_key2 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._second ) ); break; } case int_int_int_Key: { const BTreeKey< CompoundKeyWithValue >* cKey = static_cast< const BTreeKey< CompoundKeyWithValue >* >( nativeKey ); CompoundAndValue* theKey = dynamic_cast< CompoundAndValue* >( managedKey->_key->Key ); theKey->_key1 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._first ) ); theKey->_key2 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._second ) ); theKey->_value = dynamic_cast( IntInternalizer::Intern( cKey->GetKey().GetValue() ) ); break; } case int_int_datetime_Key: { const BTreeKey< CompoundKeyWithValue >* cKey = static_cast< const BTreeKey< CompoundKeyWithValue >* >( nativeKey ); CompoundAndValue* theKey = dynamic_cast< CompoundAndValue* >( managedKey->_key->Key ); theKey->_key1 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._first ) ); theKey->_key2 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._second ) ); theKey->_value = __box( DateTime( cKey->GetKey().GetValue() ) ); break; } case int_datetime_int_Key: { const BTreeKey< CompoundKeyWithValue >* cKey = static_cast< const BTreeKey< CompoundKeyWithValue >* >( nativeKey ); CompoundAndValue* theKey = dynamic_cast< CompoundAndValue* >( managedKey->_key->Key ); theKey->_key1 = dynamic_cast( IntInternalizer::Intern( cKey->GetKey()._first ) ); theKey->_key2 = __box( DateTime( cKey->GetKey()._second ) ); theKey->_value = dynamic_cast( IntInternalizer::Intern( cKey->GetKey().GetValue() ) ); break; } default: { throw new System::Exception( String::Format( "Key type {0} is not supported!", __box( type ) ) ); } } managedKey->_offset = nativeKey->GetOffset(); } /////////////////////////////////////////////////////////////////////////// // GetAllKeysEnumerator implementation /////////////////////////////////////////////////////////////////////////// GetAllKeysEnumerator::GetAllKeysEnumerator( OmniaMeaBTree* bTree ) { _bTree = bTree; _btreeHeaderIterator = bTree->_btreeHeaderIterator; _current = new KeyPair(); _current->_key = _bTree->_factoryKey; _currentPageKeys = (const BTreeKeyBase**) DBIndexHeapObject::operator new( MAX_KEYS_IN_PAGE * sizeof( const BTreeKeyBase* ) ); Reset(); } Object* GetAllKeysEnumerator::get_Current() { TranslateNativeKey2ManagedKey( _bTree->_keyType, _currentPageKeys[ _currentPageIndex ] , _current ); return _current; } bool GetAllKeysEnumerator::MoveNext() { while( ++_currentPageIndex >= _currentPageCount ) { if( _btreeHeaderIterator->Exhausted() ) { return false; } BTreePageBase* page = _bTree->GetPageByOffset( _btreeHeaderIterator->GetCurrentOffset() ); _currentPageCount = (short) page->GetAllKeys( _currentPageKeys ); if( _currentPageCount > MAX_KEYS_IN_PAGE ) { throw new BadIndexesException( "BTree contains cycles. Possible memory corruption." ); } _currentPageIndex = -1; _btreeHeaderIterator->MoveNextPage(); } return true; } void GetAllKeysEnumerator::Reset() { _bTree->_btreeHeader->GetMinimumPage( *_btreeHeaderIterator ); _currentPageIndex = -1; _currentPageCount = 0; } void GetAllKeysEnumerator::Dispose() { if( _currentPageKeys ) { DBIndexHeapObject::operator delete( _currentPageKeys ); _currentPageKeys = 0; } else { throw new System::ObjectDisposedException( "GetAllKeysEnumerator.Dispose(): object is already disposed." ); } } /////////////////////////////////////////////////////////////////////////// // SearchForRangeEnumerator implementation /////////////////////////////////////////////////////////////////////////// SearchForRangeEnumerator::SearchForRangeEnumerator() { _current = new KeyPair(); _currentPageKeys = (const BTreeKeyBase**) DBIndexHeapObject::operator new( MAX_KEYS_IN_PAGE * sizeof( const BTreeKeyBase*) ); } void SearchForRangeEnumerator::Init( OmniaMeaBTree* bTree, IFixedLengthKey* beginKey, IFixedLengthKey* endKey ) { _bTree = bTree; _beginKey = beginKey; _endKey = endKey; _btreeHeaderIterator = bTree->_btreeHeaderIterator; _current->_key = _bTree->_factoryKey; Reset(); } Object* SearchForRangeEnumerator::get_Current() { TranslateNativeKey2ManagedKey( _bTree->_keyType, _currentPageKeys[ _currentPageIndex ] , _current ); return _current; } bool SearchForRangeEnumerator::MoveNext() { while( ++_currentPageIndex >= _currentPageCount ) { if( _btreeHeaderIterator->Exhausted() ) { return false; } const BTreeKeyBase& lastKey = *( _bTree->_lastKey ); BTreeKeyBase& headerKey = *( _bTree->_headerKey ); _btreeHeaderIterator->GetCurrentKey( headerKey ); if( _bTree->_keyComparer->Less( lastKey, headerKey ) ) { return false; } BTreePageBase* page = _bTree->GetPageByOffset( _btreeHeaderIterator->GetCurrentOffset() ); _currentPageCount = (short) page->SearchForRange( *( _bTree->_firstKey ), lastKey, _currentPageKeys ); if( _currentPageCount > MAX_KEYS_IN_PAGE ) { throw new BadIndexesException( "BTree contains cycles. Possible memory corruption." ); } _currentPageIndex = -1; _btreeHeaderIterator->MoveNextPage(); } return true; } void SearchForRangeEnumerator::Reset() { _bTree->SetFirstAndLastKeys( _beginKey, _endKey ); _bTree->_btreeHeader->GetPage( *( _bTree->_firstKey ), *_btreeHeaderIterator ); _currentPageIndex = -1; _currentPageCount = 0; } void SearchForRangeEnumerator::Dispose() { SearchForRangeEnumerable::_enumeratorPool->Dispose( this ); } /////////////////////////////////////////////////////////////////////////// // SearchForRangeEnumerable implementation /////////////////////////////////////////////////////////////////////////// void SearchForRangeEnumerable::Init( IFixedLengthKey* beginKey, IFixedLengthKey* endKey ) { if( _enumeratorPool == 0 ) { _enumeratorPool = new ObjectPool( 64, new ObjectPool::CreateObjectDelegate( 0, &SearchForRangeEnumerable::CreateNewEnumerator ), 0, 0 ); } _beginKey = beginKey; _endKey = endKey; } System::Object* SearchForRangeEnumerable::CreateNewEnumerator() { return new SearchForRangeEnumerator(); } IEnumerator* SearchForRangeEnumerable::GetEnumerator() { SearchForRangeEnumerator* result = dynamic_cast ( _enumeratorPool->Alloc() ); result->Init( _bTree, _beginKey, _endKey ); return result; } }