@@ -366,42 +366,51 @@ struct index_root_page
366366{
367367 pag irt_header;
368368 USHORT irt_relation; // relation id (for consistency)
369- USHORT irt_count; // Number of indices
369+ USHORT irt_count; // number of indices
370+ ULONG irt_dummy; // so far used as a padding to ensure the same
371+ // alignment between 32-bit and 64-bit builds
370372 struct irt_repeat
371373 {
374+ friend class index_root_page ; // to allow offset check for private members
375+
372376 private:
373- friend struct index_root_page ; // to allow offset check for private members
374- ULONG irt_root; // page number of index root if irt_in_progress is NOT set, or
375- // highest 32 bit of transaction if irt_in_progress is set
376- ULONG irt_transaction; // transaction in progress (lowest 32 bits)
377+ FB_UINT64 irt_transaction; // transaction in progress
378+ ULONG irt_page_num; // page number
379+ ULONG irt_page_space_id; // page space
377380 public:
378- USHORT irt_desc; // offset to key descriptions
379- UCHAR irt_keys; // number of keys in index
380- UCHAR irt_flags;
381+ USHORT irt_desc; // offset to key descriptions
382+ USHORT irt_flags; // index flags
383+ UCHAR irt_state; // index state
384+ UCHAR irt_keys; // number of keys in index
385+ private:
386+ USHORT irt_dummy; // alignment to 8-byte boundary
381387
382- ULONG getRoot () const ;
383- void setRoot (ULONG root_page);
388+ public:
389+ TraNumber inProgress () const ;
390+ void setInProgress (TraNumber traNumber);
384391
385- TraNumber getTransaction () const ;
386- void setTransaction (TraNumber traNumber );
392+ ULONG getRoot () const ;
393+ void setRoot (ULONG rootPage );
387394
388395 bool isUsed () const ;
389-
396+ void setEmpty ();
390397 } irt_rpt[1 ];
391398
392- static_assert (sizeof (struct irt_repeat ) == 12 , " struct irt_repeat size mismatch" );
393- static_assert (offsetof(struct irt_repeat , irt_root) == 0 , " irt_root offset mismatch" );
394- static_assert (offsetof(struct irt_repeat , irt_transaction) == 4 , " irt_transaction offset mismatch" );
395- static_assert (offsetof(struct irt_repeat , irt_desc) == 8 , " irt_desc offset mismatch" );
396- static_assert (offsetof(struct irt_repeat , irt_keys) == 10 , " irt_keys offset mismatch" );
397- static_assert (offsetof(struct irt_repeat , irt_flags) == 11 , " irt_flags offset mismatch" );
399+ static_assert (sizeof (struct irt_repeat ) == 24 , " struct irt_repeat size mismatch" );
400+ static_assert (offsetof(struct irt_repeat , irt_transaction) == 0 , " irt_transaction offset mismatch" );
401+ static_assert (offsetof(struct irt_repeat , irt_page_num) == 8 , " irt_root offset mismatch" );
402+ static_assert (offsetof(struct irt_repeat , irt_page_space_id) == 12 , " irt_root offset mismatch" );
403+ static_assert (offsetof(struct irt_repeat , irt_desc) == 16 , " irt_desc offset mismatch" );
404+ static_assert (offsetof(struct irt_repeat , irt_flags) == 18 , " irt_flags offset mismatch" );
405+ static_assert (offsetof(struct irt_repeat , irt_state) == 20 , " irt_state offset mismatch" );
406+ static_assert (offsetof(struct irt_repeat , irt_keys) == 21 , " irt_keys offset mismatch" );
398407};
399408
400- static_assert (sizeof (struct index_root_page ) == 32 , " struct index_root_page size mismatch" );
409+ static_assert (sizeof (struct index_root_page ) == 48 , " struct index_root_page size mismatch" );
401410static_assert (offsetof(struct index_root_page , irt_header) == 0 , " irt_header offset mismatch" );
402411static_assert (offsetof(struct index_root_page , irt_relation) == 16 , " irt_relation offset mismatch" );
403412static_assert (offsetof(struct index_root_page , irt_count) == 18 , " irt_count offset mismatch" );
404- static_assert (offsetof(struct index_root_page , irt_rpt) == 20 , " irt_rpt offset mismatch" );
413+ static_assert (offsetof(struct index_root_page , irt_rpt) == 24 , " irt_rpt offset mismatch" );
405414
406415// key descriptor
407416
@@ -420,38 +429,65 @@ static_assert(offsetof(struct irtd, irtd_selectivity) == 4, "irtd_selectivity of
420429// irt_flags, must match the idx_flags (see btr.h)
421430inline constexpr USHORT irt_unique = 1 ;
422431inline constexpr USHORT irt_descending = 2 ;
423- inline constexpr USHORT irt_in_progress = 4 ;
424- inline constexpr USHORT irt_foreign = 8 ;
425- inline constexpr USHORT irt_primary = 16 ;
426- inline constexpr USHORT irt_expression = 32 ;
427- inline constexpr USHORT irt_condition = 64 ;
432+ inline constexpr USHORT irt_foreign = 4 ;
433+ inline constexpr USHORT irt_primary = 8 ;
434+ inline constexpr USHORT irt_expression = 16 ;
435+ inline constexpr USHORT irt_condition = 32 ;
436+
437+ // possible index states
438+ inline constexpr UCHAR irt_unused = 0 ; // empty slot
439+ inline constexpr UCHAR irt_in_progress = 1 ; // under construction - sort & merge
440+ inline constexpr UCHAR irt_rollback = 2 ; // index to be removed when irt_transaction dead (rolled back)
441+ inline constexpr UCHAR irt_normal = 3 ; // normal working state of index
442+ inline constexpr UCHAR irt_kill = 4 ; // index to be removed when irt_transaction ended (both commit/rollback)
443+ inline constexpr UCHAR irt_commit = 5 ; // start index removal (switch to irt_drop) when irt_transaction committed
444+ inline constexpr UCHAR irt_drop = 6 ; // index to be removed when OAT > irt_transaction
428445
429- inline ULONG index_root_page::irt_repeat::getRoot () const
446+ inline bool index_root_page::irt_repeat::isUsed () const
430447{
431- return (irt_flags & irt_in_progress) ? 0 : irt_root ;
448+ return (irt_state != irt_unused) ;
432449}
433450
434- inline void index_root_page::irt_repeat::setRoot (ULONG root_page )
451+ inline void index_root_page::irt_repeat::setEmpty ( )
435452{
436- irt_root = root_page;
437- irt_flags &= ~irt_in_progress;
453+ irt_transaction = 0 ;
454+ irt_page_num = 0 ;
455+ irt_page_space_id = 0 ;
456+ irt_flags = 0 ;
457+ irt_state = irt_unused;
438458}
439459
440- inline TraNumber index_root_page::irt_repeat::getTransaction () const
460+ inline TraNumber index_root_page::irt_repeat::inProgress () const
441461{
442- return (irt_flags & irt_in_progress) ? ((TraNumber) irt_root << BITS_PER_LONG) | irt_transaction : 0 ;
462+ return irt_transaction;
443463}
444464
445- inline void index_root_page::irt_repeat::setTransaction (TraNumber traNumber)
465+ inline void index_root_page::irt_repeat::setInProgress (TraNumber traNumber)
446466{
447- irt_root = ULONG (traNumber >> BITS_PER_LONG);
448- irt_transaction = ULONG (traNumber);
449- irt_flags |= irt_in_progress;
467+ fb_assert (irt_state == irt_unused);
468+ fb_assert (!irt_page_num && !irt_page_space_id);
469+
470+ irt_transaction = traNumber;
471+ irt_page_num = 0 ;
472+ irt_page_space_id = 0 ;
473+ irt_state = irt_in_progress;
450474}
451475
452- inline bool index_root_page::irt_repeat::isUsed () const
476+ inline ULONG index_root_page::irt_repeat::getRoot () const
477+ {
478+ return (irt_state == irt_unused) ? 0 : irt_page_num;
479+ }
480+
481+ inline void index_root_page::irt_repeat::setRoot (ULONG rootPage)
453482{
454- return (irt_flags & irt_in_progress) || (irt_root != 0 );
483+ fb_assert (irt_state == irt_in_progress);
484+ fb_assert (!irt_page_num && !irt_page_space_id);
485+ fb_assert (rootPage);
486+
487+ irt_transaction = 0 ;
488+ irt_page_num = rootPage;
489+ irt_page_space_id = 0 ;
490+ irt_state = irt_normal;
455491}
456492
457493
0 commit comments