344 {
345 const uint16_t type_id = generic_index<MultiIndexType>::value_type::type_id;
347 typedef typename index_type::allocator_type index_alloc;
348
349 std::string
type_name = boost::core::demangle(
typeid(
typename index_type::value_type ).
name() );
350
351 if( !( _index_map.size() <= type_id || _index_map[ type_id ] == nullptr ) ) {
352 BOOST_THROW_EXCEPTION( std::logic_error( type_name + "::type_id is already in use" ) );
353 }
354
355 index_type* idx_ptr = nullptr;
356 if( _read_only )
358 else
360 bool first_time_adding = false;
361 if( !idx_ptr ) {
362 if( _read_only ) {
363 BOOST_THROW_EXCEPTION( std::runtime_error( "unable to find index for " + type_name + " in read only database" ) );
364 }
365 first_time_adding = true;
367 }
368
369 idx_ptr->validate();
370
371
372 if( _index_list.size() > 0 ) {
373 auto expected_revision_range = _index_list.front()->undo_stack_revision_range();
374 auto added_index_revision_range = idx_ptr->undo_stack_revision_range();
375
376 if( added_index_revision_range.first != expected_revision_range.first ||
377 added_index_revision_range.second != expected_revision_range.second ) {
378
379 if( !first_time_adding ) {
380 BOOST_THROW_EXCEPTION( std::logic_error(
381 "existing index for " + type_name + " has an undo stack (revision range [" +
382 std::to_string(added_index_revision_range.first) + ", " + std::to_string(added_index_revision_range.second) +
383 "]) that is inconsistent with other indices in the database (revision range [" +
384 std::to_string(expected_revision_range.first) + ", " + std::to_string(expected_revision_range.second) +
385 "]); corrupted database?"
386 ) );
387 }
388
389 if( _read_only ) {
390 BOOST_THROW_EXCEPTION( std::logic_error(
391 "new index for " + type_name +
392 " requires an undo stack that is consistent with other indices in the database; cannot fix in read-only mode"
393 ) );
394 }
395
396 idx_ptr->set_revision(
static_cast<uint64_t>(expected_revision_range.first) );
397 while( idx_ptr->revision() < expected_revision_range.second ) {
398 idx_ptr->start_undo_session(true).push();
399 }
400 }
401 }
402
403 if( type_id >= _index_map.size() )
404 _index_map.resize( type_id + 1 );
405
406 auto new_index = new index<index_type>( *idx_ptr );
407 _index_map[ type_id ].reset( new_index );
408 _index_list.push_back( new_index );
409 }
segment_manager * get_segment_manager() const
multi_index_to_undo_index< MultiIndexType > generic_index
unsigned __int64 uint64_t