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