@@ -366,26 +366,25 @@ struct index_root_page
366366 pag irt_header;
367367 USHORT irt_relation; // relation id (for consistency)
368368 USHORT irt_count; // number of indices
369- ULONG irt_unused ; // so far used as a padding to ensure the same
369+ ULONG irt_dummy ; // so far used as a padding to ensure the same
370370 // alignment between 32-bit and 64-bit builds
371371 struct irt_repeat
372372 {
373373 friend class index_root_page ; // to allow offset check for private members
374+
374375 private:
375- union
376- {
377- FB_UINT64 irt_transaction; // transaction in progress
378- struct
379- {
380- ULONG irt_page_num; // page number
381- ULONG irt_page_space_id; // page space
382- } irt_root; // index root page
383- };
376+ FB_UINT64 irt_transaction; // transaction in progress
377+ ULONG irt_page_num; // page number
378+ ULONG irt_page_space_id; // page space
384379 public:
385380 USHORT irt_desc; // offset to key descriptions
386381 USHORT irt_flags; // index flags
382+ UCHAR irt_state; // index state
387383 UCHAR irt_keys; // number of keys in index
384+ private:
385+ USHORT irt_dummy; // alignment to 8-byte boundary
388386
387+ public:
389388 TraNumber inProgress () const ;
390389 void setInProgress (TraNumber traNumber);
391390
@@ -396,15 +395,17 @@ struct index_root_page
396395 void setEmpty ();
397396 } irt_rpt[1 ];
398397
399- static_assert (sizeof (struct irt_repeat ) == 16 , " struct irt_repeat size mismatch" );
398+ static_assert (sizeof (struct irt_repeat ) == 24 , " struct irt_repeat size mismatch" );
400399 static_assert (offsetof(struct irt_repeat , irt_transaction) == 0 , " irt_transaction offset mismatch" );
401- static_assert (offsetof(struct irt_repeat , irt_root) == 0 , " irt_root offset mismatch" );
402- static_assert (offsetof(struct irt_repeat , irt_desc) == 8 , " irt_desc offset mismatch" );
403- static_assert (offsetof(struct irt_repeat , irt_flags) == 10 , " irt_flags offset mismatch" );
404- static_assert (offsetof(struct irt_repeat , irt_keys) == 12 , " irt_keys offset mismatch" );
400+ static_assert (offsetof(struct irt_repeat , irt_page_num) == 8 , " irt_root offset mismatch" );
401+ static_assert (offsetof(struct irt_repeat , irt_page_space_id) == 12 , " irt_root offset mismatch" );
402+ static_assert (offsetof(struct irt_repeat , irt_desc) == 16 , " irt_desc offset mismatch" );
403+ static_assert (offsetof(struct irt_repeat , irt_flags) == 18 , " irt_flags offset mismatch" );
404+ static_assert (offsetof(struct irt_repeat , irt_state) == 20 , " irt_state offset mismatch" );
405+ static_assert (offsetof(struct irt_repeat , irt_keys) == 21 , " irt_keys offset mismatch" );
405406};
406407
407- static_assert (sizeof (struct index_root_page ) == 40 , " struct index_root_page size mismatch" );
408+ static_assert (sizeof (struct index_root_page ) == 48 , " struct index_root_page size mismatch" );
408409static_assert (offsetof(struct index_root_page , irt_header) == 0 , " irt_header offset mismatch" );
409410static_assert (offsetof(struct index_root_page , irt_relation) == 16 , " irt_relation offset mismatch" );
410411static_assert (offsetof(struct index_root_page , irt_count) == 18 , " irt_count offset mismatch" );
@@ -427,45 +428,65 @@ static_assert(offsetof(struct irtd, irtd_selectivity) == 4, "irtd_selectivity of
427428// irt_flags, must match the idx_flags (see btr.h)
428429inline constexpr USHORT irt_unique = 1 ;
429430inline constexpr USHORT irt_descending = 2 ;
430- inline constexpr USHORT irt_in_progress = 4 ;
431- inline constexpr USHORT irt_foreign = 8 ;
432- inline constexpr USHORT irt_primary = 16 ;
433- inline constexpr USHORT irt_expression = 32 ;
434- inline constexpr USHORT irt_condition = 64 ;
431+ inline constexpr USHORT irt_foreign = 4 ;
432+ inline constexpr USHORT irt_primary = 8 ;
433+ inline constexpr USHORT irt_expression = 16 ;
434+ inline constexpr USHORT irt_condition = 32 ;
435+
436+ // possible index states
437+ inline constexpr UCHAR irt_unused = 0 ; // empty slot
438+ inline constexpr UCHAR irt_in_progress = 1 ; // under construction - sort & merge
439+ inline constexpr UCHAR irt_rollback = 2 ; // index to be removed when irt_transaction dead (rolled back)
440+ inline constexpr UCHAR irt_normal = 3 ; // normal working state of index
441+ inline constexpr UCHAR irt_kill = 4 ; // index to be removed when irt_transaction ended (both commit/rollback)
442+ inline constexpr UCHAR irt_commit = 5 ; // start index removal (switch to irt_drop) when irt_transaction committed
443+ inline constexpr UCHAR irt_drop = 6 ; // index to be removed when OAT > irt_transaction
435444
436445inline bool index_root_page::irt_repeat::isUsed () const
437446{
438- return (irt_flags & irt_in_progress) || (irt_root. irt_page_num != 0 );
447+ return (irt_state != irt_unused );
439448}
440449
441450inline void index_root_page::irt_repeat::setEmpty ()
442451{
443452 irt_transaction = 0 ;
444- fb_assert (irt_root.irt_page_num == 0 && irt_root.irt_page_space_id == 0 );
453+ irt_page_num = 0 ;
454+ irt_page_space_id = 0 ;
445455 irt_flags = 0 ;
456+ irt_state = irt_unused;
446457}
447458
448459inline TraNumber index_root_page::irt_repeat::inProgress () const
449460{
450- return (irt_flags & irt_in_progress) ? irt_transaction : 0 ;
461+ return irt_transaction;
451462}
452463
453464inline void index_root_page::irt_repeat::setInProgress (TraNumber traNumber)
454465{
466+ fb_assert (irt_state == irt_unused);
467+ fb_assert (!irt_page_num && !irt_page_space_id);
468+
455469 irt_transaction = traNumber;
456- irt_flags |= irt_in_progress;
470+ irt_page_num = 0 ;
471+ irt_page_space_id = 0 ;
472+ irt_state = irt_in_progress;
457473}
458474
459475inline ULONG index_root_page::irt_repeat::getRoot () const
460476{
461- return (irt_flags & irt_in_progress ) ? 0 : irt_root. irt_page_num ;
477+ return (irt_state == irt_unused ) ? 0 : irt_page_num;
462478}
463479
464480inline void index_root_page::irt_repeat::setRoot (ULONG rootPage)
465481{
466- irt_root.irt_page_num = rootPage;
467- irt_root.irt_page_space_id = 0 ;
468- irt_flags &= ~irt_in_progress;
482+ fb_assert (irt_state == irt_in_progress);
483+ fb_assert (!irt_page_num && !irt_page_space_id);
484+ fb_assert (rootPage);
485+
486+ irt_transaction = 0 ;
487+ irt_page_num = rootPage;
488+ irt_page_space_id = 0 ;
489+ irt_state = irt_normal;
469490}
470491
471492
0 commit comments