26
26
#include < pc.hpp>
27
27
#include < DynArr256.hpp>
28
28
#include < SimulatedBlock.hpp>
29
+ #include < LHLevel.hpp>
29
30
30
31
#ifdef DBACC_C
31
32
// Debug Macros
@@ -199,7 +200,7 @@ class ElementHeader {
199
200
*
200
201
* l = Locked -- If true contains operation else scan bits + hash value
201
202
* s = Scan bits
202
- * h = Hash value
203
+ * h = Reduced hash value. The lower bits used for address is shifted away
203
204
* o = Operation ptr I
204
205
*
205
206
* 1111111111222222222233
@@ -208,17 +209,16 @@ class ElementHeader {
208
209
* ooooooooooooooooooooooooooooooo
209
210
*/
210
211
public:
211
- STATIC_CONST ( HASH_VALUE_PART_MASK = 0xFFFF );
212
-
213
212
static bool getLocked (Uint32 data);
214
213
static bool getUnlocked (Uint32 data);
215
214
static Uint32 getScanBits (Uint32 data);
216
- static Uint32 getHashValuePart (Uint32 data);
217
215
static Uint32 getOpPtrI (Uint32 data);
216
+ static LHBits16 getReducedHashValue (Uint32 data);
218
217
219
218
static Uint32 setLocked (Uint32 opPtrI);
220
- static Uint32 setUnlocked (Uint32 hashValuePart, Uint32 scanBits );
219
+ static Uint32 setUnlocked (Uint32 scanBits, LHBits16 const & reducedHashValue );
221
220
static Uint32 setScanBit (Uint32 header, Uint32 scanBit);
221
+ static Uint32 setReducedHashValue (Uint32 header, LHBits16 const & reducedHashValue);
222
222
static Uint32 clearScanBit (Uint32 header, Uint32 scanBit);
223
223
};
224
224
@@ -241,11 +241,11 @@ ElementHeader::getScanBits(Uint32 data){
241
241
return (data >> 1 ) & ((1 << MAX_PARALLEL_SCANS_PER_FRAG) - 1 );
242
242
}
243
243
244
- inline
245
- Uint32
246
- ElementHeader::getHashValuePart (Uint32 data){
244
+ inline
245
+ LHBits16
246
+ ElementHeader::getReducedHashValue (Uint32 data){
247
247
assert (getUnlocked (data));
248
- return data >> 16 ;
248
+ return LHBits16::unpack ( data >> 16 ) ;
249
249
}
250
250
251
251
inline
@@ -258,12 +258,15 @@ ElementHeader::getOpPtrI(Uint32 data){
258
258
inline
259
259
Uint32
260
260
ElementHeader::setLocked (Uint32 opPtrI){
261
+ assert (opPtrI < 0x8000000 );
261
262
return (opPtrI << 1 ) + 0 ;
262
263
}
263
264
inline
264
265
Uint32
265
- ElementHeader::setUnlocked (Uint32 hashValue, Uint32 scanBits){
266
- return (hashValue << 16 ) + (scanBits << 1 ) + 1 ;
266
+ ElementHeader::setUnlocked (Uint32 scanBits, LHBits16 const & reducedHashValue)
267
+ {
268
+ assert (scanBits < (1 << MAX_PARALLEL_SCANS_PER_FRAG));
269
+ return (Uint32 (reducedHashValue.pack ()) << 16 ) | (scanBits << 1 ) | 1 ;
267
270
}
268
271
269
272
inline
@@ -280,6 +283,13 @@ ElementHeader::clearScanBit(Uint32 header, Uint32 scanBit){
280
283
return header & (~(scanBit << 1 ));
281
284
}
282
285
286
+ inline
287
+ Uint32
288
+ ElementHeader::setReducedHashValue (Uint32 header, LHBits16 const & reducedHashValue)
289
+ {
290
+ assert (getUnlocked (header));
291
+ return (Uint32 (reducedHashValue.pack ()) << 16 ) | (header & 0xffff );
292
+ }
283
293
284
294
class Dbacc : public SimulatedBlock {
285
295
friend class DbaccProxy ;
@@ -401,14 +411,15 @@ struct Fragmentrec {
401
411
// slackCheck When slack goes over this value it is time to expand.
402
412
// slackCheck = (maxp + p + 1)*(maxloadfactor - minloadfactor) or
403
413
// bucketSize * hysteresis
414
+ // Since at most RNIL 8KiB-pages can be used for a fragment, the extreme values
415
+ // for slack will be within -2^43 and +2^43 words.
404
416
// -----------------------------------------------------------------------------
417
+ LHLevelRH level;
405
418
Uint32 localkeylen;
406
- Uint32 maxp;
407
419
Uint32 maxloadfactor;
408
420
Uint32 minloadfactor;
409
- Uint32 p;
410
- Uint32 slack;
411
- Uint32 slackCheck;
421
+ Int64 slack;
422
+ Int64 slackCheck;
412
423
413
424
// -----------------------------------------------------------------------------
414
425
// nextfreefrag is the next free fragment if linked into a free list
@@ -441,19 +452,17 @@ struct Fragmentrec {
441
452
Uint16 keyLength;
442
453
443
454
// -----------------------------------------------------------------------------
444
- // This flag is used to avoid sending a big number of expand or shrink signals
445
- // when simultaneously committing many inserts or deletes.
455
+ // Only allow one expand or shrink signal in queue at the time.
446
456
// -----------------------------------------------------------------------------
447
- Uint8 expandFlag ;
457
+ bool expandOrShrinkQueued ;
448
458
449
459
// -----------------------------------------------------------------------------
450
460
// hashcheckbit is the bit to check whether to send element to split bucket or not
451
461
// k (== 6) is the number of buckets per page
452
- // lhfragbits is the number of bits used to calculate the fragment id
453
462
// -----------------------------------------------------------------------------
454
- Uint8 hashcheckbit ;
455
- Uint8 k ;
456
- Uint8 lhfragbits ;
463
+ STATIC_CONST ( k = 6 ) ;
464
+ STATIC_CONST ( MIN_HASH_COMPARE_BITS = 7 ) ;
465
+ STATIC_CONST ( MAX_HASH_VALUE_BITS = 31 ) ;
457
466
458
467
// -----------------------------------------------------------------------------
459
468
// nodetype can only be STORED in this release. Is currently only set, never read
@@ -469,6 +478,11 @@ struct Fragmentrec {
469
478
// flag to mark that execEXPANDCHECK2 has failed due to DirRange full
470
479
// -----------------------------------------------------------------------------
471
480
Uint8 dirRangeFull;
481
+
482
+ public:
483
+ Uint32 getPageNumber (Uint32 bucket_number) const ;
484
+ Uint32 getPageIndex (Uint32 bucket_number) const ;
485
+ bool enough_valid_bits (LHBits16 const & reduced_hash_value) const ;
472
486
};
473
487
474
488
typedef Ptr <Fragmentrec> FragmentrecPtr;
@@ -484,8 +498,7 @@ struct Operationrec {
484
498
Uint32 elementPointer;
485
499
Uint32 fid;
486
500
Uint32 fragptr;
487
- Uint32 hashvaluePart;
488
- Uint32 hashValue;
501
+ LHBits32 hashValue;
489
502
Uint32 nextLockOwnerOp;
490
503
Uint32 nextOp;
491
504
Uint32 nextParallelQue;
@@ -511,7 +524,8 @@ struct Operationrec {
511
524
Uint16 tupkeylen;
512
525
Uint32 xfrmtupkeylen;
513
526
Uint32 userblockref;
514
- Uint32 scanBits;
527
+ Uint16 scanBits;
528
+ LHBits16 reducedHashValue;
515
529
516
530
enum OpBits {
517
531
OP_MASK = 0x0000F // 4 bits for operation type
@@ -692,8 +706,8 @@ struct Tabrec {
692
706
void releaseDirIndexResources (Signal* signal, FragmentrecPtr regFragPtr);
693
707
void releaseFragRecord (Signal* signal, FragmentrecPtr regFragPtr);
694
708
void initScanFragmentPart (Signal* signal);
695
- Uint32 checkScanExpand (Signal* signal);
696
- Uint32 checkScanShrink (Signal* signal);
709
+ Uint32 checkScanExpand (Signal* signal, Uint32 splitBucket );
710
+ Uint32 checkScanShrink (Signal* signal, Uint32 sourceBucket, Uint32 destBucket );
697
711
void initialiseFragRec (Signal* signal);
698
712
void initialiseFsConnectionRec (Signal* signal);
699
713
void initialiseFsOpRec (Signal* signal);
@@ -761,6 +775,10 @@ struct Tabrec {
761
775
void seizeRightlist (Signal* signal);
762
776
Uint32 readTablePk (Uint32 lkey1, Uint32 lkey2, Uint32 eh, OperationrecPtr);
763
777
Uint32 getElement (Signal* signal, OperationrecPtr& lockOwner);
778
+ LHBits32 getElementHash (OperationrecPtr& oprec);
779
+ LHBits32 getElementHash (Uint32 const * element, Int32 forward);
780
+ LHBits32 getElementHash (Uint32 const * element, Int32 forward, OperationrecPtr& oprec);
781
+ void shrink_adjust_reduced_hash_value (Uint32 bucket_number);
764
782
Uint32 getPagePtr (DynArr256::Head&, Uint32);
765
783
bool setPagePtr (DynArr256::Head& directory, Uint32 index, Uint32 ptri);
766
784
Uint32 unsetPagePtr (DynArr256::Head& directory, Uint32 index);
@@ -837,8 +855,6 @@ struct Tabrec {
837
855
838
856
void zpagesize_error (const char * where);
839
857
840
- void reenable_expand_after_redo_log_exection_complete (Signal*);
841
-
842
858
// charsets
843
859
void xfrmKeyData (Signal* signal);
844
860
@@ -1000,7 +1016,6 @@ struct Tabrec {
1000
1016
Uint32 tgeContainerptr;
1001
1017
Uint32 tgeElementptr;
1002
1018
Uint32 tgeForward;
1003
- Uint32 texpReceivedBucket;
1004
1019
Uint32 texpDirInd;
1005
1020
Uint32 texpDirRangeIndex;
1006
1021
Uint32 texpDirPageIndex;
@@ -1034,7 +1049,6 @@ struct Tabrec {
1034
1049
Uint32 tmp;
1035
1050
Uint32 tmpP;
1036
1051
Uint32 tmpP2;
1037
- Uint32 tmp1;
1038
1052
Uint32 tmp2;
1039
1053
Uint32 tgflPageindex;
1040
1054
Uint32 tmpindex;
@@ -1094,4 +1108,23 @@ struct Tabrec {
1094
1108
Uint32 c_memusage_report_frequency;
1095
1109
};
1096
1110
1111
+ inline Uint32 Dbacc::Fragmentrec::getPageNumber (Uint32 bucket_number) const
1112
+ {
1113
+ assert (bucket_number < RNIL);
1114
+ return bucket_number >> k;
1115
+ }
1116
+
1117
+ inline Uint32 Dbacc::Fragmentrec::getPageIndex (Uint32 bucket_number) const
1118
+ {
1119
+ assert (bucket_number < RNIL);
1120
+ return bucket_number & ((1 << k) - 1 );
1121
+ }
1122
+
1123
+ inline bool Dbacc::Fragmentrec::enough_valid_bits (LHBits16 const & reduced_hash_value) const
1124
+ {
1125
+ // Forte C 5.0 needs use of intermediate constant
1126
+ int const bits = MIN_HASH_COMPARE_BITS;
1127
+ return level.getNeededValidBits (bits) <= reduced_hash_value.valid_bits ();
1128
+ }
1129
+
1097
1130
#endif
0 commit comments