duckdb 0.3.2-dev396.0 → 0.3.2-dev481.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +3695 -400
- package/src/duckdb.hpp +2 -2
package/src/duckdb.cpp
CHANGED
|
@@ -29651,8 +29651,7 @@ void Deserializer::ReadStringVector(vector<string> &list) {
|
|
|
29651
29651
|
namespace duckdb {
|
|
29652
29652
|
|
|
29653
29653
|
struct SortLayout;
|
|
29654
|
-
struct
|
|
29655
|
-
struct SortedData;
|
|
29654
|
+
struct SBScanState;
|
|
29656
29655
|
|
|
29657
29656
|
using ValidityBytes = RowLayout::ValidityBytes;
|
|
29658
29657
|
|
|
@@ -29662,14 +29661,14 @@ public:
|
|
|
29662
29661
|
static bool TieIsBreakable(const idx_t &col_idx, const data_ptr_t row_ptr, const RowLayout &row_layout);
|
|
29663
29662
|
//! Compares the tuples that a being read from in the 'left' and 'right blocks during merge sort
|
|
29664
29663
|
//! (only in case we cannot simply 'memcmp' - if there are blob columns)
|
|
29665
|
-
static int CompareTuple(const
|
|
29664
|
+
static int CompareTuple(const SBScanState &left, const SBScanState &right, const data_ptr_t &l_ptr,
|
|
29666
29665
|
const data_ptr_t &r_ptr, const SortLayout &sort_layout, const bool &external_sort);
|
|
29667
29666
|
//! Compare two blob values
|
|
29668
29667
|
static int CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, const LogicalType &type);
|
|
29669
29668
|
|
|
29670
29669
|
private:
|
|
29671
29670
|
//! Compares two blob values that were initially tied by their prefix
|
|
29672
|
-
static int BreakBlobTie(const idx_t &tie_col, const
|
|
29671
|
+
static int BreakBlobTie(const idx_t &tie_col, const SBScanState &left, const SBScanState &right,
|
|
29673
29672
|
const SortLayout &sort_layout, const bool &external);
|
|
29674
29673
|
//! Compare two fixed-size values
|
|
29675
29674
|
template <class T>
|
|
@@ -30423,59 +30422,36 @@ struct RowDataBlock;
|
|
|
30423
30422
|
struct SortLayout;
|
|
30424
30423
|
struct GlobalSortState;
|
|
30425
30424
|
|
|
30425
|
+
enum class SortedDataType { BLOB, PAYLOAD };
|
|
30426
|
+
|
|
30426
30427
|
//! Object that holds sorted rows, and an accompanying heap if there are blobs
|
|
30427
30428
|
struct SortedData {
|
|
30428
30429
|
public:
|
|
30429
|
-
SortedData(const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state);
|
|
30430
|
+
SortedData(SortedDataType type, const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state);
|
|
30430
30431
|
//! Number of rows that this object holds
|
|
30431
30432
|
idx_t Count();
|
|
30432
|
-
//! Pin the current block so it can be read
|
|
30433
|
-
void Pin();
|
|
30434
|
-
//! Pointer to the row that is currently being read from
|
|
30435
|
-
data_ptr_t DataPtr() const;
|
|
30436
|
-
//! Pointer to the heap row that corresponds to the current row
|
|
30437
|
-
data_ptr_t HeapPtr() const;
|
|
30438
|
-
//! Advance one row
|
|
30439
|
-
void Advance(const bool &adv);
|
|
30440
30433
|
//! Initialize new block to write to
|
|
30441
30434
|
void CreateBlock();
|
|
30442
|
-
//! Reset read indices to the given indices
|
|
30443
|
-
void ResetIndices(idx_t block_idx_to, idx_t entry_idx_to);
|
|
30444
30435
|
//! Create a slice that holds the rows between the start and end indices
|
|
30445
|
-
unique_ptr<SortedData> CreateSlice(idx_t start_block_index, idx_t
|
|
30446
|
-
idx_t end_entry_index);
|
|
30436
|
+
unique_ptr<SortedData> CreateSlice(idx_t start_block_index, idx_t end_block_index, idx_t end_entry_index);
|
|
30447
30437
|
//! Unswizzles all
|
|
30448
30438
|
void Unswizzle();
|
|
30449
30439
|
|
|
30450
30440
|
public:
|
|
30441
|
+
const SortedDataType type;
|
|
30451
30442
|
//! Layout of this data
|
|
30452
30443
|
const RowLayout layout;
|
|
30453
30444
|
//! Data and heap blocks
|
|
30454
30445
|
vector<RowDataBlock> data_blocks;
|
|
30455
30446
|
vector<RowDataBlock> heap_blocks;
|
|
30456
|
-
//! Buffer handles to the data being currently read
|
|
30457
|
-
unique_ptr<BufferHandle> data_handle;
|
|
30458
|
-
unique_ptr<BufferHandle> heap_handle;
|
|
30459
|
-
//! Read indices
|
|
30460
|
-
idx_t block_idx;
|
|
30461
|
-
idx_t entry_idx;
|
|
30462
30447
|
//! Whether the pointers in this sorted data are swizzled
|
|
30463
30448
|
bool swizzled;
|
|
30464
30449
|
|
|
30465
|
-
private:
|
|
30466
|
-
//! Pin fixed-size row data
|
|
30467
|
-
void PinData();
|
|
30468
|
-
//! Pin the accompanying heap data (if any)
|
|
30469
|
-
void PinHeap();
|
|
30470
|
-
|
|
30471
30450
|
private:
|
|
30472
30451
|
//! The buffer manager
|
|
30473
30452
|
BufferManager &buffer_manager;
|
|
30474
30453
|
//! The global state
|
|
30475
30454
|
GlobalSortState &state;
|
|
30476
|
-
//! Pointers into the buffers being currently read
|
|
30477
|
-
data_ptr_t data_ptr;
|
|
30478
|
-
data_ptr_t heap_ptr;
|
|
30479
30455
|
};
|
|
30480
30456
|
|
|
30481
30457
|
//! Block that holds sorted rows: radix, blob and payload data
|
|
@@ -30484,21 +30460,17 @@ public:
|
|
|
30484
30460
|
SortedBlock(BufferManager &buffer_manager, GlobalSortState &gstate);
|
|
30485
30461
|
//! Number of rows that this object holds
|
|
30486
30462
|
idx_t Count() const;
|
|
30487
|
-
//! The remaining number of rows to be read from this object
|
|
30488
|
-
idx_t Remaining() const;
|
|
30489
30463
|
//! Initialize this block to write data to
|
|
30490
30464
|
void InitializeWrite();
|
|
30491
30465
|
//! Init new block to write to
|
|
30492
30466
|
void CreateBlock();
|
|
30493
|
-
//! Pins radix block with given index
|
|
30494
|
-
void PinRadix(idx_t pin_block_idx);
|
|
30495
30467
|
//! Fill this sorted block by appending the blocks held by a vector of sorted blocks
|
|
30496
30468
|
void AppendSortedBlocks(vector<unique_ptr<SortedBlock>> &sorted_blocks);
|
|
30497
30469
|
//! Locate the block and entry index of a row in this block,
|
|
30498
30470
|
//! given an index between 0 and the total number of rows in this block
|
|
30499
30471
|
void GlobalToLocalIndex(const idx_t &global_idx, idx_t &local_block_index, idx_t &local_entry_index);
|
|
30500
30472
|
//! Create a slice that holds the rows between the start and end indices
|
|
30501
|
-
unique_ptr<SortedBlock> CreateSlice(const idx_t start, const idx_t end);
|
|
30473
|
+
unique_ptr<SortedBlock> CreateSlice(const idx_t start, const idx_t end, idx_t &entry_idx);
|
|
30502
30474
|
|
|
30503
30475
|
//! Size (in bytes) of the heap of this block
|
|
30504
30476
|
idx_t HeapSize() const;
|
|
@@ -30508,25 +30480,59 @@ public:
|
|
|
30508
30480
|
public:
|
|
30509
30481
|
//! Radix/memcmp sortable data
|
|
30510
30482
|
vector<RowDataBlock> radix_sorting_data;
|
|
30511
|
-
unique_ptr<BufferHandle> radix_handle;
|
|
30512
|
-
idx_t block_idx;
|
|
30513
|
-
idx_t entry_idx;
|
|
30514
30483
|
//! Variable sized sorting data
|
|
30515
30484
|
unique_ptr<SortedData> blob_sorting_data;
|
|
30516
30485
|
//! Payload data
|
|
30517
30486
|
unique_ptr<SortedData> payload_data;
|
|
30518
30487
|
|
|
30519
30488
|
private:
|
|
30520
|
-
//! Buffer manager, and sorting layout constants
|
|
30489
|
+
//! Buffer manager, global state, and sorting layout constants
|
|
30521
30490
|
BufferManager &buffer_manager;
|
|
30522
30491
|
GlobalSortState &state;
|
|
30523
30492
|
const SortLayout &sort_layout;
|
|
30524
30493
|
const RowLayout &payload_layout;
|
|
30525
30494
|
};
|
|
30526
30495
|
|
|
30527
|
-
|
|
30496
|
+
//! State used to scan a SortedBlock e.g. during merge sort
|
|
30497
|
+
struct SBScanState {
|
|
30528
30498
|
public:
|
|
30529
|
-
|
|
30499
|
+
SBScanState(BufferManager &buffer_manager, GlobalSortState &state);
|
|
30500
|
+
|
|
30501
|
+
void PinRadix(idx_t block_idx_to);
|
|
30502
|
+
void PinData(SortedData &sd);
|
|
30503
|
+
|
|
30504
|
+
data_ptr_t RadixPtr() const;
|
|
30505
|
+
data_ptr_t DataPtr(SortedData &sd) const;
|
|
30506
|
+
data_ptr_t HeapPtr(SortedData &sd) const;
|
|
30507
|
+
data_ptr_t BaseHeapPtr(SortedData &sd) const;
|
|
30508
|
+
|
|
30509
|
+
idx_t Remaining() const;
|
|
30510
|
+
|
|
30511
|
+
void SetIndices(idx_t block_idx_to, idx_t entry_idx_to);
|
|
30512
|
+
|
|
30513
|
+
public:
|
|
30514
|
+
BufferManager &buffer_manager;
|
|
30515
|
+
const SortLayout &sort_layout;
|
|
30516
|
+
GlobalSortState &state;
|
|
30517
|
+
|
|
30518
|
+
SortedBlock *sb;
|
|
30519
|
+
|
|
30520
|
+
idx_t block_idx;
|
|
30521
|
+
idx_t entry_idx;
|
|
30522
|
+
|
|
30523
|
+
unique_ptr<BufferHandle> radix_handle = nullptr;
|
|
30524
|
+
|
|
30525
|
+
unique_ptr<BufferHandle> blob_sorting_data_handle = nullptr;
|
|
30526
|
+
unique_ptr<BufferHandle> blob_sorting_heap_handle = nullptr;
|
|
30527
|
+
|
|
30528
|
+
unique_ptr<BufferHandle> payload_data_handle = nullptr;
|
|
30529
|
+
unique_ptr<BufferHandle> payload_heap_handle = nullptr;
|
|
30530
|
+
};
|
|
30531
|
+
|
|
30532
|
+
//! Used to scan the data into DataChunks after sorting
|
|
30533
|
+
struct PayloadScanner {
|
|
30534
|
+
public:
|
|
30535
|
+
PayloadScanner(SortedData &sorted_data, GlobalSortState &global_sort_state);
|
|
30530
30536
|
|
|
30531
30537
|
//! Scans the next data chunk from the sorted data
|
|
30532
30538
|
void Scan(DataChunk &chunk);
|
|
@@ -30534,6 +30540,8 @@ public:
|
|
|
30534
30540
|
private:
|
|
30535
30541
|
//! The sorted data being scanned
|
|
30536
30542
|
SortedData &sorted_data;
|
|
30543
|
+
//! Read state
|
|
30544
|
+
SBScanState read_state;
|
|
30537
30545
|
//! The total count of sorted_data
|
|
30538
30546
|
const idx_t total_count;
|
|
30539
30547
|
//! The global sort state
|
|
@@ -30685,13 +30693,29 @@ public:
|
|
|
30685
30693
|
//! Finds and merges partitions until the current cascaded merge round is finished
|
|
30686
30694
|
void PerformInMergeRound();
|
|
30687
30695
|
|
|
30696
|
+
private:
|
|
30697
|
+
//! The global sorting state
|
|
30698
|
+
GlobalSortState &state;
|
|
30699
|
+
//! The sorting and payload layouts
|
|
30700
|
+
BufferManager &buffer_manager;
|
|
30701
|
+
const SortLayout &sort_layout;
|
|
30702
|
+
|
|
30703
|
+
//! The left and right reader
|
|
30704
|
+
unique_ptr<SBScanState> left;
|
|
30705
|
+
unique_ptr<SBScanState> right;
|
|
30706
|
+
|
|
30707
|
+
//! Input and output blocks
|
|
30708
|
+
unique_ptr<SortedBlock> left_input;
|
|
30709
|
+
unique_ptr<SortedBlock> right_input;
|
|
30710
|
+
SortedBlock *result;
|
|
30711
|
+
|
|
30688
30712
|
private:
|
|
30689
30713
|
//! Computes the left and right block that will be merged next (Merge Path partition)
|
|
30690
30714
|
void GetNextPartition();
|
|
30691
30715
|
//! Finds the boundary of the next partition using binary search
|
|
30692
|
-
void GetIntersection(
|
|
30716
|
+
void GetIntersection(const idx_t diagonal, idx_t &l_idx, idx_t &r_idx);
|
|
30693
30717
|
//! Compare values within SortedBlocks using a global index
|
|
30694
|
-
int CompareUsingGlobalIndex(
|
|
30718
|
+
int CompareUsingGlobalIndex(SBScanState &l, SBScanState &r, const idx_t l_idx, const idx_t r_idx);
|
|
30695
30719
|
|
|
30696
30720
|
//! Finds the next partition and merges it
|
|
30697
30721
|
void MergePartition();
|
|
@@ -30703,7 +30727,7 @@ private:
|
|
|
30703
30727
|
void MergeRadix(const idx_t &count, const bool left_smaller[]);
|
|
30704
30728
|
//! Merges SortedData according to the 'left_smaller' array
|
|
30705
30729
|
void MergeData(SortedData &result_data, SortedData &l_data, SortedData &r_data, const idx_t &count,
|
|
30706
|
-
const bool left_smaller[], idx_t next_entry_sizes[]);
|
|
30730
|
+
const bool left_smaller[], idx_t next_entry_sizes[], bool reset_indices);
|
|
30707
30731
|
//! Merges constant size rows according to the 'left_smaller' array
|
|
30708
30732
|
void MergeRows(data_ptr_t &l_ptr, idx_t &l_entry_idx, const idx_t &l_count, data_ptr_t &r_ptr, idx_t &r_entry_idx,
|
|
30709
30733
|
const idx_t &r_count, RowDataBlock *target_block, data_ptr_t &target_ptr, const idx_t &entry_size,
|
|
@@ -30717,18 +30741,6 @@ private:
|
|
|
30717
30741
|
idx_t &source_entry_idx, data_ptr_t &source_heap_ptr, RowDataBlock *target_data_block,
|
|
30718
30742
|
data_ptr_t &target_data_ptr, RowDataBlock *target_heap_block, BufferHandle &target_heap_handle,
|
|
30719
30743
|
data_ptr_t &target_heap_ptr, idx_t &copied, const idx_t &count);
|
|
30720
|
-
|
|
30721
|
-
private:
|
|
30722
|
-
//! The global sorting state
|
|
30723
|
-
GlobalSortState &state;
|
|
30724
|
-
//! The sorting and payload layouts
|
|
30725
|
-
BufferManager &buffer_manager;
|
|
30726
|
-
const SortLayout &sort_layout;
|
|
30727
|
-
|
|
30728
|
-
//! The left, right and result blocks of the current partition
|
|
30729
|
-
unique_ptr<SortedBlock> left_block;
|
|
30730
|
-
unique_ptr<SortedBlock> right_block;
|
|
30731
|
-
SortedBlock *result;
|
|
30732
30744
|
};
|
|
30733
30745
|
|
|
30734
30746
|
} // namespace duckdb
|
|
@@ -30757,7 +30769,7 @@ bool Comparators::TieIsBreakable(const idx_t &col_idx, const data_ptr_t row_ptr,
|
|
|
30757
30769
|
return true;
|
|
30758
30770
|
}
|
|
30759
30771
|
|
|
30760
|
-
int Comparators::CompareTuple(const
|
|
30772
|
+
int Comparators::CompareTuple(const SBScanState &left, const SBScanState &right, const data_ptr_t &l_ptr,
|
|
30761
30773
|
const data_ptr_t &r_ptr, const SortLayout &sort_layout, const bool &external_sort) {
|
|
30762
30774
|
// Compare the sorting columns one by one
|
|
30763
30775
|
int comp_res = 0;
|
|
@@ -30766,8 +30778,7 @@ int Comparators::CompareTuple(const SortedBlock &left, const SortedBlock &right,
|
|
|
30766
30778
|
for (idx_t col_idx = 0; col_idx < sort_layout.column_count; col_idx++) {
|
|
30767
30779
|
comp_res = FastMemcmp(l_ptr_offset, r_ptr_offset, sort_layout.column_sizes[col_idx]);
|
|
30768
30780
|
if (comp_res == 0 && !sort_layout.constant_size[col_idx]) {
|
|
30769
|
-
comp_res =
|
|
30770
|
-
BreakBlobTie(col_idx, *left.blob_sorting_data, *right.blob_sorting_data, sort_layout, external_sort);
|
|
30781
|
+
comp_res = BreakBlobTie(col_idx, left, right, sort_layout, external_sort);
|
|
30771
30782
|
}
|
|
30772
30783
|
if (comp_res != 0) {
|
|
30773
30784
|
break;
|
|
@@ -30793,11 +30804,11 @@ int Comparators::CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, cons
|
|
|
30793
30804
|
}
|
|
30794
30805
|
}
|
|
30795
30806
|
|
|
30796
|
-
int Comparators::BreakBlobTie(const idx_t &tie_col, const
|
|
30807
|
+
int Comparators::BreakBlobTie(const idx_t &tie_col, const SBScanState &left, const SBScanState &right,
|
|
30797
30808
|
const SortLayout &sort_layout, const bool &external) {
|
|
30798
30809
|
const idx_t &col_idx = sort_layout.sorting_to_blob_col.at(tie_col);
|
|
30799
|
-
data_ptr_t l_data_ptr = left.DataPtr();
|
|
30800
|
-
data_ptr_t r_data_ptr = right.DataPtr();
|
|
30810
|
+
data_ptr_t l_data_ptr = left.DataPtr(*left.sb->blob_sorting_data);
|
|
30811
|
+
data_ptr_t r_data_ptr = right.DataPtr(*right.sb->blob_sorting_data);
|
|
30801
30812
|
if (!TieIsBreakable(col_idx, l_data_ptr, sort_layout.blob_layout)) {
|
|
30802
30813
|
// Quick check to see if ties can be broken
|
|
30803
30814
|
return 0;
|
|
@@ -30808,12 +30819,12 @@ int Comparators::BreakBlobTie(const idx_t &tie_col, const SortedData &left, cons
|
|
|
30808
30819
|
r_data_ptr += tie_col_offset;
|
|
30809
30820
|
// Do the comparison
|
|
30810
30821
|
const int order = sort_layout.order_types[tie_col] == OrderType::DESCENDING ? -1 : 1;
|
|
30811
|
-
const auto &type =
|
|
30822
|
+
const auto &type = sort_layout.blob_layout.GetTypes()[col_idx];
|
|
30812
30823
|
int result;
|
|
30813
30824
|
if (external) {
|
|
30814
30825
|
// Store heap pointers
|
|
30815
|
-
data_ptr_t l_heap_ptr = left.HeapPtr();
|
|
30816
|
-
data_ptr_t r_heap_ptr = right.HeapPtr();
|
|
30826
|
+
data_ptr_t l_heap_ptr = left.HeapPtr(*left.sb->blob_sorting_data);
|
|
30827
|
+
data_ptr_t r_heap_ptr = right.HeapPtr(*right.sb->blob_sorting_data);
|
|
30817
30828
|
// Unswizzle offset to pointer
|
|
30818
30829
|
UnswizzleSingleValue(l_data_ptr, l_heap_ptr, type);
|
|
30819
30830
|
UnswizzleSingleValue(r_data_ptr, r_heap_ptr, type);
|
|
@@ -31114,21 +31125,23 @@ void MergeSorter::PerformInMergeRound() {
|
|
|
31114
31125
|
}
|
|
31115
31126
|
|
|
31116
31127
|
void MergeSorter::MergePartition() {
|
|
31117
|
-
auto &
|
|
31118
|
-
auto &
|
|
31128
|
+
auto &left_block = *left->sb;
|
|
31129
|
+
auto &right_block = *right->sb;
|
|
31119
31130
|
#ifdef DEBUG
|
|
31120
|
-
D_ASSERT(
|
|
31121
|
-
D_ASSERT(
|
|
31131
|
+
D_ASSERT(left_block.radix_sorting_data.size() == left_block.payload_data->data_blocks.size());
|
|
31132
|
+
D_ASSERT(right_block.radix_sorting_data.size() == right_block.payload_data->data_blocks.size());
|
|
31122
31133
|
if (!state.payload_layout.AllConstant() && state.external) {
|
|
31123
|
-
D_ASSERT(
|
|
31124
|
-
D_ASSERT(
|
|
31134
|
+
D_ASSERT(left_block.payload_data->data_blocks.size() == left_block.payload_data->heap_blocks.size());
|
|
31135
|
+
D_ASSERT(right_block.payload_data->data_blocks.size() == right_block.payload_data->heap_blocks.size());
|
|
31125
31136
|
}
|
|
31126
31137
|
if (!sort_layout.all_constant) {
|
|
31127
|
-
D_ASSERT(
|
|
31128
|
-
D_ASSERT(
|
|
31138
|
+
D_ASSERT(left_block.radix_sorting_data.size() == left_block.blob_sorting_data->data_blocks.size());
|
|
31139
|
+
D_ASSERT(right_block.radix_sorting_data.size() == right_block.blob_sorting_data->data_blocks.size());
|
|
31129
31140
|
if (state.external) {
|
|
31130
|
-
D_ASSERT(
|
|
31131
|
-
|
|
31141
|
+
D_ASSERT(left_block.blob_sorting_data->data_blocks.size() ==
|
|
31142
|
+
left_block.blob_sorting_data->heap_blocks.size());
|
|
31143
|
+
D_ASSERT(right_block.blob_sorting_data->data_blocks.size() ==
|
|
31144
|
+
right_block.blob_sorting_data->heap_blocks.size());
|
|
31132
31145
|
}
|
|
31133
31146
|
}
|
|
31134
31147
|
#endif
|
|
@@ -31140,12 +31153,12 @@ void MergeSorter::MergePartition() {
|
|
|
31140
31153
|
idx_t next_entry_sizes[STANDARD_VECTOR_SIZE];
|
|
31141
31154
|
// Merge loop
|
|
31142
31155
|
#ifdef DEBUG
|
|
31143
|
-
auto l_count = left
|
|
31144
|
-
auto r_count = right
|
|
31156
|
+
auto l_count = left->Remaining();
|
|
31157
|
+
auto r_count = right->Remaining();
|
|
31145
31158
|
#endif
|
|
31146
31159
|
while (true) {
|
|
31147
|
-
auto l_remaining = left
|
|
31148
|
-
auto r_remaining = right
|
|
31160
|
+
auto l_remaining = left->Remaining();
|
|
31161
|
+
auto r_remaining = right->Remaining();
|
|
31149
31162
|
if (l_remaining + r_remaining == 0) {
|
|
31150
31163
|
// Done
|
|
31151
31164
|
break;
|
|
@@ -31158,17 +31171,12 @@ void MergeSorter::MergePartition() {
|
|
|
31158
31171
|
// Actually merge the data (radix, blob, and payload)
|
|
31159
31172
|
MergeRadix(next, left_smaller);
|
|
31160
31173
|
if (!sort_layout.all_constant) {
|
|
31161
|
-
MergeData(*result->blob_sorting_data, *
|
|
31162
|
-
next_entry_sizes);
|
|
31163
|
-
D_ASSERT(left.block_idx == left.blob_sorting_data->block_idx &&
|
|
31164
|
-
left.entry_idx == left.blob_sorting_data->entry_idx);
|
|
31165
|
-
D_ASSERT(right.block_idx == right.blob_sorting_data->block_idx &&
|
|
31166
|
-
right.entry_idx == right.blob_sorting_data->entry_idx);
|
|
31174
|
+
MergeData(*result->blob_sorting_data, *left_block.blob_sorting_data, *right_block.blob_sorting_data, next,
|
|
31175
|
+
left_smaller, next_entry_sizes, true);
|
|
31167
31176
|
D_ASSERT(result->radix_sorting_data.size() == result->blob_sorting_data->data_blocks.size());
|
|
31168
31177
|
}
|
|
31169
|
-
MergeData(*result->payload_data, *
|
|
31170
|
-
|
|
31171
|
-
D_ASSERT(right.block_idx == right.payload_data->block_idx && right.entry_idx == right.payload_data->entry_idx);
|
|
31178
|
+
MergeData(*result->payload_data, *left_block.payload_data, *right_block.payload_data, next, left_smaller,
|
|
31179
|
+
next_entry_sizes, false);
|
|
31172
31180
|
D_ASSERT(result->radix_sorting_data.size() == result->payload_data->data_blocks.size());
|
|
31173
31181
|
}
|
|
31174
31182
|
#ifdef DEBUG
|
|
@@ -31181,34 +31189,39 @@ void MergeSorter::GetNextPartition() {
|
|
|
31181
31189
|
state.sorted_blocks_temp[state.pair_idx].push_back(make_unique<SortedBlock>(buffer_manager, state));
|
|
31182
31190
|
result = state.sorted_blocks_temp[state.pair_idx].back().get();
|
|
31183
31191
|
// Determine which blocks must be merged
|
|
31184
|
-
auto &
|
|
31185
|
-
auto &
|
|
31186
|
-
const idx_t l_count =
|
|
31187
|
-
const idx_t r_count =
|
|
31192
|
+
auto &left_block = *state.sorted_blocks[state.pair_idx * 2];
|
|
31193
|
+
auto &right_block = *state.sorted_blocks[state.pair_idx * 2 + 1];
|
|
31194
|
+
const idx_t l_count = left_block.Count();
|
|
31195
|
+
const idx_t r_count = right_block.Count();
|
|
31196
|
+
// Initialize left and right reader
|
|
31197
|
+
left = make_unique<SBScanState>(buffer_manager, state);
|
|
31198
|
+
right = make_unique<SBScanState>(buffer_manager, state);
|
|
31188
31199
|
// Compute the work that this thread must do using Merge Path
|
|
31189
31200
|
idx_t l_end;
|
|
31190
31201
|
idx_t r_end;
|
|
31191
31202
|
if (state.l_start + state.r_start + state.block_capacity < l_count + r_count) {
|
|
31203
|
+
left->sb = state.sorted_blocks[state.pair_idx * 2].get();
|
|
31204
|
+
right->sb = state.sorted_blocks[state.pair_idx * 2 + 1].get();
|
|
31192
31205
|
const idx_t intersection = state.l_start + state.r_start + state.block_capacity;
|
|
31193
|
-
GetIntersection(
|
|
31206
|
+
GetIntersection(intersection, l_end, r_end);
|
|
31194
31207
|
D_ASSERT(l_end <= l_count);
|
|
31195
31208
|
D_ASSERT(r_end <= r_count);
|
|
31196
31209
|
D_ASSERT(intersection == l_end + r_end);
|
|
31197
|
-
// Unpin after finding the intersection
|
|
31198
|
-
if (!sort_layout.blob_layout.AllConstant()) {
|
|
31199
|
-
left.blob_sorting_data->ResetIndices(0, 0);
|
|
31200
|
-
right.blob_sorting_data->ResetIndices(0, 0);
|
|
31201
|
-
}
|
|
31202
31210
|
} else {
|
|
31203
31211
|
l_end = l_count;
|
|
31204
31212
|
r_end = r_count;
|
|
31205
31213
|
}
|
|
31206
31214
|
// Create slices of the data that this thread must merge
|
|
31207
|
-
|
|
31208
|
-
|
|
31209
|
-
|
|
31215
|
+
left->SetIndices(0, 0);
|
|
31216
|
+
right->SetIndices(0, 0);
|
|
31217
|
+
left_input = left_block.CreateSlice(state.l_start, l_end, left->entry_idx);
|
|
31218
|
+
right_input = right_block.CreateSlice(state.r_start, r_end, right->entry_idx);
|
|
31219
|
+
left->sb = left_input.get();
|
|
31220
|
+
right->sb = right_input.get();
|
|
31210
31221
|
state.l_start = l_end;
|
|
31211
31222
|
state.r_start = r_end;
|
|
31223
|
+
D_ASSERT(left->Remaining() + right->Remaining() == state.block_capacity || (l_end == l_count && r_end == r_count));
|
|
31224
|
+
// Update global state
|
|
31212
31225
|
if (state.l_start == l_count && state.r_start == r_count) {
|
|
31213
31226
|
// Delete references to previous pair
|
|
31214
31227
|
state.sorted_blocks[state.pair_idx * 2] = nullptr;
|
|
@@ -31220,9 +31233,9 @@ void MergeSorter::GetNextPartition() {
|
|
|
31220
31233
|
}
|
|
31221
31234
|
}
|
|
31222
31235
|
|
|
31223
|
-
int MergeSorter::CompareUsingGlobalIndex(
|
|
31224
|
-
D_ASSERT(l_idx < l.Count());
|
|
31225
|
-
D_ASSERT(r_idx < r.Count());
|
|
31236
|
+
int MergeSorter::CompareUsingGlobalIndex(SBScanState &l, SBScanState &r, const idx_t l_idx, const idx_t r_idx) {
|
|
31237
|
+
D_ASSERT(l_idx < l.sb->Count());
|
|
31238
|
+
D_ASSERT(r_idx < r.sb->Count());
|
|
31226
31239
|
|
|
31227
31240
|
// Easy comparison using the previous result (intersections must increase monotonically)
|
|
31228
31241
|
if (l_idx < state.l_start) {
|
|
@@ -31232,37 +31245,28 @@ int MergeSorter::CompareUsingGlobalIndex(SortedBlock &l, SortedBlock &r, const i
|
|
|
31232
31245
|
return 1;
|
|
31233
31246
|
}
|
|
31234
31247
|
|
|
31235
|
-
|
|
31236
|
-
|
|
31237
|
-
l.GlobalToLocalIndex(l_idx, l_block_idx, l_entry_idx);
|
|
31238
|
-
|
|
31239
|
-
idx_t r_block_idx;
|
|
31240
|
-
idx_t r_entry_idx;
|
|
31241
|
-
r.GlobalToLocalIndex(r_idx, r_block_idx, r_entry_idx);
|
|
31248
|
+
l.sb->GlobalToLocalIndex(l_idx, l.block_idx, l.entry_idx);
|
|
31249
|
+
r.sb->GlobalToLocalIndex(r_idx, r.block_idx, r.entry_idx);
|
|
31242
31250
|
|
|
31243
|
-
l.PinRadix(
|
|
31244
|
-
r.PinRadix(
|
|
31245
|
-
data_ptr_t l_ptr = l.radix_handle->Ptr() +
|
|
31246
|
-
data_ptr_t r_ptr = r.radix_handle->Ptr() +
|
|
31251
|
+
l.PinRadix(l.block_idx);
|
|
31252
|
+
r.PinRadix(r.block_idx);
|
|
31253
|
+
data_ptr_t l_ptr = l.radix_handle->Ptr() + l.entry_idx * sort_layout.entry_size;
|
|
31254
|
+
data_ptr_t r_ptr = r.radix_handle->Ptr() + r.entry_idx * sort_layout.entry_size;
|
|
31247
31255
|
|
|
31248
31256
|
int comp_res;
|
|
31249
31257
|
if (sort_layout.all_constant) {
|
|
31250
31258
|
comp_res = FastMemcmp(l_ptr, r_ptr, sort_layout.comparison_size);
|
|
31251
31259
|
} else {
|
|
31252
|
-
l.blob_sorting_data
|
|
31253
|
-
|
|
31254
|
-
l.blob_sorting_data->Pin();
|
|
31255
|
-
r.blob_sorting_data->block_idx = r_block_idx;
|
|
31256
|
-
r.blob_sorting_data->entry_idx = r_entry_idx;
|
|
31257
|
-
r.blob_sorting_data->Pin();
|
|
31260
|
+
l.PinData(*l.sb->blob_sorting_data);
|
|
31261
|
+
r.PinData(*r.sb->blob_sorting_data);
|
|
31258
31262
|
comp_res = Comparators::CompareTuple(l, r, l_ptr, r_ptr, sort_layout, state.external);
|
|
31259
31263
|
}
|
|
31260
31264
|
return comp_res;
|
|
31261
31265
|
}
|
|
31262
31266
|
|
|
31263
|
-
void MergeSorter::GetIntersection(
|
|
31264
|
-
const idx_t l_count =
|
|
31265
|
-
const idx_t r_count =
|
|
31267
|
+
void MergeSorter::GetIntersection(const idx_t diagonal, idx_t &l_idx, idx_t &r_idx) {
|
|
31268
|
+
const idx_t l_count = left->sb->Count();
|
|
31269
|
+
const idx_t r_count = right->sb->Count();
|
|
31266
31270
|
// Cover some edge cases
|
|
31267
31271
|
// Code coverage off because these edge cases cannot happen unless other code changes
|
|
31268
31272
|
// Edge cases have been tested extensively while developing Merge Path in a script
|
|
@@ -31292,16 +31296,16 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di
|
|
|
31292
31296
|
const idx_t search_space = diagonal > MaxValue(l_count, r_count) ? l_count + r_count - diagonal
|
|
31293
31297
|
: MinValue(diagonal, MinValue(l_count, r_count));
|
|
31294
31298
|
// Double binary search
|
|
31295
|
-
idx_t
|
|
31296
|
-
idx_t
|
|
31299
|
+
idx_t li = 0;
|
|
31300
|
+
idx_t ri = search_space - 1;
|
|
31297
31301
|
idx_t middle;
|
|
31298
31302
|
int comp_res;
|
|
31299
|
-
while (
|
|
31300
|
-
middle = (
|
|
31303
|
+
while (li <= ri) {
|
|
31304
|
+
middle = (li + ri) / 2;
|
|
31301
31305
|
l_idx = l_offset - middle;
|
|
31302
31306
|
r_idx = r_offset + middle;
|
|
31303
31307
|
if (l_idx == l_count || r_idx == 0) {
|
|
31304
|
-
comp_res = CompareUsingGlobalIndex(
|
|
31308
|
+
comp_res = CompareUsingGlobalIndex(*left, *right, l_idx - 1, r_idx);
|
|
31305
31309
|
if (comp_res > 0) {
|
|
31306
31310
|
l_idx--;
|
|
31307
31311
|
r_idx++;
|
|
@@ -31318,15 +31322,15 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di
|
|
|
31318
31322
|
break;
|
|
31319
31323
|
}
|
|
31320
31324
|
}
|
|
31321
|
-
comp_res = CompareUsingGlobalIndex(
|
|
31325
|
+
comp_res = CompareUsingGlobalIndex(*left, *right, l_idx, r_idx);
|
|
31322
31326
|
if (comp_res > 0) {
|
|
31323
|
-
|
|
31327
|
+
li = middle + 1;
|
|
31324
31328
|
} else {
|
|
31325
|
-
|
|
31329
|
+
ri = middle - 1;
|
|
31326
31330
|
}
|
|
31327
31331
|
}
|
|
31328
|
-
int l_r_min1 = CompareUsingGlobalIndex(
|
|
31329
|
-
int l_min1_r = CompareUsingGlobalIndex(
|
|
31332
|
+
int l_r_min1 = CompareUsingGlobalIndex(*left, *right, l_idx, r_idx - 1);
|
|
31333
|
+
int l_min1_r = CompareUsingGlobalIndex(*left, *right, l_idx - 1, r_idx);
|
|
31330
31334
|
if (l_r_min1 > 0 && l_min1_r < 0) {
|
|
31331
31335
|
return;
|
|
31332
31336
|
} else if (l_r_min1 > 0) {
|
|
@@ -31339,13 +31343,15 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di
|
|
|
31339
31343
|
}
|
|
31340
31344
|
|
|
31341
31345
|
void MergeSorter::ComputeMerge(const idx_t &count, bool left_smaller[]) {
|
|
31342
|
-
auto &
|
|
31343
|
-
auto &
|
|
31344
|
-
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
idx_t
|
|
31348
|
-
idx_t
|
|
31346
|
+
auto &l = *left;
|
|
31347
|
+
auto &r = *right;
|
|
31348
|
+
auto &l_sorted_block = *l.sb;
|
|
31349
|
+
auto &r_sorted_block = *r.sb;
|
|
31350
|
+
// Save indices to restore afterwards
|
|
31351
|
+
idx_t l_block_idx_before = l.block_idx;
|
|
31352
|
+
idx_t l_entry_idx_before = l.entry_idx;
|
|
31353
|
+
idx_t r_block_idx_before = r.block_idx;
|
|
31354
|
+
idx_t r_entry_idx_before = r.entry_idx;
|
|
31349
31355
|
// Data pointers for both sides
|
|
31350
31356
|
data_ptr_t l_radix_ptr;
|
|
31351
31357
|
data_ptr_t r_radix_ptr;
|
|
@@ -31353,91 +31359,84 @@ void MergeSorter::ComputeMerge(const idx_t &count, bool left_smaller[]) {
|
|
|
31353
31359
|
idx_t compared = 0;
|
|
31354
31360
|
while (compared < count) {
|
|
31355
31361
|
// Move to the next block (if needed)
|
|
31356
|
-
if (
|
|
31357
|
-
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31364
|
-
|
|
31365
|
-
|
|
31366
|
-
|
|
31367
|
-
|
|
31368
|
-
if (!sort_layout.all_constant) {
|
|
31369
|
-
right.blob_sorting_data->block_idx = r_block_idx;
|
|
31370
|
-
right.blob_sorting_data->entry_idx = r_entry_idx;
|
|
31371
|
-
}
|
|
31372
|
-
}
|
|
31373
|
-
const bool l_done = l_block_idx == left.radix_sorting_data.size();
|
|
31374
|
-
const bool r_done = r_block_idx == right.radix_sorting_data.size();
|
|
31362
|
+
if (l.block_idx < l_sorted_block.radix_sorting_data.size() &&
|
|
31363
|
+
l.entry_idx == l_sorted_block.radix_sorting_data[l.block_idx].count) {
|
|
31364
|
+
l.block_idx++;
|
|
31365
|
+
l.entry_idx = 0;
|
|
31366
|
+
}
|
|
31367
|
+
if (r.block_idx < r_sorted_block.radix_sorting_data.size() &&
|
|
31368
|
+
r.entry_idx == r_sorted_block.radix_sorting_data[r.block_idx].count) {
|
|
31369
|
+
r.block_idx++;
|
|
31370
|
+
r.entry_idx = 0;
|
|
31371
|
+
}
|
|
31372
|
+
const bool l_done = l.block_idx == l_sorted_block.radix_sorting_data.size();
|
|
31373
|
+
const bool r_done = r.block_idx == r_sorted_block.radix_sorting_data.size();
|
|
31375
31374
|
if (l_done || r_done) {
|
|
31376
31375
|
// One of the sides is exhausted, no need to compare
|
|
31377
31376
|
break;
|
|
31378
31377
|
}
|
|
31379
31378
|
// Pin the radix sorting data
|
|
31380
31379
|
if (!l_done) {
|
|
31381
|
-
left
|
|
31382
|
-
l_radix_ptr = left
|
|
31380
|
+
left->PinRadix(l.block_idx);
|
|
31381
|
+
l_radix_ptr = left->RadixPtr();
|
|
31383
31382
|
}
|
|
31384
31383
|
if (!r_done) {
|
|
31385
|
-
right
|
|
31386
|
-
r_radix_ptr = right
|
|
31384
|
+
right->PinRadix(r.block_idx);
|
|
31385
|
+
r_radix_ptr = right->RadixPtr();
|
|
31387
31386
|
}
|
|
31388
|
-
const idx_t &l_count = !l_done ?
|
|
31389
|
-
const idx_t &r_count = !r_done ?
|
|
31387
|
+
const idx_t &l_count = !l_done ? l_sorted_block.radix_sorting_data[l.block_idx].count : 0;
|
|
31388
|
+
const idx_t &r_count = !r_done ? r_sorted_block.radix_sorting_data[r.block_idx].count : 0;
|
|
31390
31389
|
// Compute the merge
|
|
31391
31390
|
if (sort_layout.all_constant) {
|
|
31392
31391
|
// All sorting columns are constant size
|
|
31393
|
-
for (; compared < count &&
|
|
31392
|
+
for (; compared < count && l.entry_idx < l_count && r.entry_idx < r_count; compared++) {
|
|
31394
31393
|
left_smaller[compared] = FastMemcmp(l_radix_ptr, r_radix_ptr, sort_layout.comparison_size) < 0;
|
|
31395
31394
|
const bool &l_smaller = left_smaller[compared];
|
|
31396
31395
|
const bool r_smaller = !l_smaller;
|
|
31397
31396
|
// Use comparison bool (0 or 1) to increment entries and pointers
|
|
31398
|
-
|
|
31399
|
-
|
|
31397
|
+
l.entry_idx += l_smaller;
|
|
31398
|
+
r.entry_idx += r_smaller;
|
|
31400
31399
|
l_radix_ptr += l_smaller * sort_layout.entry_size;
|
|
31401
31400
|
r_radix_ptr += r_smaller * sort_layout.entry_size;
|
|
31402
31401
|
}
|
|
31403
31402
|
} else {
|
|
31404
31403
|
// Pin the blob data
|
|
31405
31404
|
if (!l_done) {
|
|
31406
|
-
left.blob_sorting_data
|
|
31405
|
+
left->PinData(*l_sorted_block.blob_sorting_data);
|
|
31407
31406
|
}
|
|
31408
31407
|
if (!r_done) {
|
|
31409
|
-
right.blob_sorting_data
|
|
31408
|
+
right->PinData(*r_sorted_block.blob_sorting_data);
|
|
31410
31409
|
}
|
|
31411
31410
|
// Merge with variable size sorting columns
|
|
31412
|
-
for (; compared < count &&
|
|
31413
|
-
D_ASSERT(l_block_idx == left.blob_sorting_data->block_idx &&
|
|
31414
|
-
l_entry_idx == left.blob_sorting_data->entry_idx);
|
|
31415
|
-
D_ASSERT(r_block_idx == right.blob_sorting_data->block_idx &&
|
|
31416
|
-
r_entry_idx == right.blob_sorting_data->entry_idx);
|
|
31411
|
+
for (; compared < count && l.entry_idx < l_count && r.entry_idx < r_count; compared++) {
|
|
31417
31412
|
left_smaller[compared] =
|
|
31418
|
-
Comparators::CompareTuple(left, right, l_radix_ptr, r_radix_ptr, sort_layout, state.external) < 0;
|
|
31413
|
+
Comparators::CompareTuple(*left, *right, l_radix_ptr, r_radix_ptr, sort_layout, state.external) < 0;
|
|
31419
31414
|
const bool &l_smaller = left_smaller[compared];
|
|
31420
31415
|
const bool r_smaller = !l_smaller;
|
|
31421
31416
|
// Use comparison bool (0 or 1) to increment entries and pointers
|
|
31422
|
-
|
|
31423
|
-
|
|
31417
|
+
l.entry_idx += l_smaller;
|
|
31418
|
+
r.entry_idx += r_smaller;
|
|
31424
31419
|
l_radix_ptr += l_smaller * sort_layout.entry_size;
|
|
31425
31420
|
r_radix_ptr += r_smaller * sort_layout.entry_size;
|
|
31426
|
-
left.blob_sorting_data->Advance(l_smaller);
|
|
31427
|
-
right.blob_sorting_data->Advance(r_smaller);
|
|
31428
31421
|
}
|
|
31429
31422
|
}
|
|
31430
31423
|
}
|
|
31431
|
-
// Reset block indices
|
|
31432
|
-
|
|
31433
|
-
|
|
31434
|
-
right.blob_sorting_data->ResetIndices(right.block_idx, right.entry_idx);
|
|
31435
|
-
}
|
|
31424
|
+
// Reset block indices
|
|
31425
|
+
left->SetIndices(l_block_idx_before, l_entry_idx_before);
|
|
31426
|
+
right->SetIndices(r_block_idx_before, r_entry_idx_before);
|
|
31436
31427
|
}
|
|
31437
31428
|
|
|
31438
31429
|
void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) {
|
|
31439
|
-
auto &
|
|
31440
|
-
auto &
|
|
31430
|
+
auto &l = *left;
|
|
31431
|
+
auto &r = *right;
|
|
31432
|
+
// Save indices to restore afterwards
|
|
31433
|
+
idx_t l_block_idx_before = l.block_idx;
|
|
31434
|
+
idx_t l_entry_idx_before = l.entry_idx;
|
|
31435
|
+
idx_t r_block_idx_before = r.block_idx;
|
|
31436
|
+
idx_t r_entry_idx_before = r.entry_idx;
|
|
31437
|
+
|
|
31438
|
+
auto &l_blocks = l.sb->radix_sorting_data;
|
|
31439
|
+
auto &r_blocks = r.sb->radix_sorting_data;
|
|
31441
31440
|
RowDataBlock *l_block;
|
|
31442
31441
|
RowDataBlock *r_block;
|
|
31443
31442
|
|
|
@@ -31451,54 +31450,63 @@ void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) {
|
|
|
31451
31450
|
idx_t copied = 0;
|
|
31452
31451
|
while (copied < count) {
|
|
31453
31452
|
// Move to the next block (if needed)
|
|
31454
|
-
if (
|
|
31455
|
-
left.entry_idx == left.radix_sorting_data[left.block_idx].count) {
|
|
31453
|
+
if (l.block_idx < l_blocks.size() && l.entry_idx == l_blocks[l.block_idx].count) {
|
|
31456
31454
|
// Delete reference to previous block
|
|
31457
|
-
|
|
31455
|
+
l_blocks[l.block_idx].block = nullptr;
|
|
31458
31456
|
// Advance block
|
|
31459
|
-
|
|
31460
|
-
|
|
31457
|
+
l.block_idx++;
|
|
31458
|
+
l.entry_idx = 0;
|
|
31461
31459
|
}
|
|
31462
|
-
if (
|
|
31463
|
-
right.entry_idx == right.radix_sorting_data[right.block_idx].count) {
|
|
31460
|
+
if (r.block_idx < r_blocks.size() && r.entry_idx == r_blocks[r.block_idx].count) {
|
|
31464
31461
|
// Delete reference to previous block
|
|
31465
|
-
|
|
31462
|
+
r_blocks[r.block_idx].block = nullptr;
|
|
31466
31463
|
// Advance block
|
|
31467
|
-
|
|
31468
|
-
|
|
31464
|
+
r.block_idx++;
|
|
31465
|
+
r.entry_idx = 0;
|
|
31469
31466
|
}
|
|
31470
|
-
const bool l_done =
|
|
31471
|
-
const bool r_done =
|
|
31467
|
+
const bool l_done = l.block_idx == l_blocks.size();
|
|
31468
|
+
const bool r_done = r.block_idx == r_blocks.size();
|
|
31472
31469
|
// Pin the radix sortable blocks
|
|
31473
31470
|
if (!l_done) {
|
|
31474
|
-
l_block = &
|
|
31475
|
-
left
|
|
31476
|
-
l_ptr =
|
|
31471
|
+
l_block = &l_blocks[l.block_idx];
|
|
31472
|
+
left->PinRadix(l.block_idx);
|
|
31473
|
+
l_ptr = l.RadixPtr();
|
|
31477
31474
|
}
|
|
31478
31475
|
if (!r_done) {
|
|
31479
|
-
r_block = &
|
|
31480
|
-
|
|
31481
|
-
r_ptr =
|
|
31476
|
+
r_block = &r_blocks[r.block_idx];
|
|
31477
|
+
r.PinRadix(r.block_idx);
|
|
31478
|
+
r_ptr = r.RadixPtr();
|
|
31482
31479
|
}
|
|
31483
31480
|
const idx_t &l_count = !l_done ? l_block->count : 0;
|
|
31484
31481
|
const idx_t &r_count = !r_done ? r_block->count : 0;
|
|
31485
31482
|
// Copy using computed merge
|
|
31486
31483
|
if (!l_done && !r_done) {
|
|
31487
31484
|
// Both sides have data - merge
|
|
31488
|
-
MergeRows(l_ptr,
|
|
31485
|
+
MergeRows(l_ptr, l.entry_idx, l_count, r_ptr, r.entry_idx, r_count, result_block, result_ptr,
|
|
31489
31486
|
sort_layout.entry_size, left_smaller, copied, count);
|
|
31490
31487
|
} else if (r_done) {
|
|
31491
31488
|
// Right side is exhausted
|
|
31492
|
-
FlushRows(l_ptr,
|
|
31489
|
+
FlushRows(l_ptr, l.entry_idx, l_count, result_block, result_ptr, sort_layout.entry_size, copied, count);
|
|
31493
31490
|
} else {
|
|
31494
31491
|
// Left side is exhausted
|
|
31495
|
-
FlushRows(r_ptr,
|
|
31492
|
+
FlushRows(r_ptr, r.entry_idx, r_count, result_block, result_ptr, sort_layout.entry_size, copied, count);
|
|
31496
31493
|
}
|
|
31497
31494
|
}
|
|
31495
|
+
// Reset block indices
|
|
31496
|
+
left->SetIndices(l_block_idx_before, l_entry_idx_before);
|
|
31497
|
+
right->SetIndices(r_block_idx_before, r_entry_idx_before);
|
|
31498
31498
|
}
|
|
31499
31499
|
|
|
31500
31500
|
void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedData &r_data, const idx_t &count,
|
|
31501
|
-
const bool left_smaller[], idx_t next_entry_sizes[]) {
|
|
31501
|
+
const bool left_smaller[], idx_t next_entry_sizes[], bool reset_indices) {
|
|
31502
|
+
auto &l = *left;
|
|
31503
|
+
auto &r = *right;
|
|
31504
|
+
// Save indices to restore afterwards
|
|
31505
|
+
idx_t l_block_idx_before = l.block_idx;
|
|
31506
|
+
idx_t l_entry_idx_before = l.entry_idx;
|
|
31507
|
+
idx_t r_block_idx_before = r.block_idx;
|
|
31508
|
+
idx_t r_entry_idx_before = r.entry_idx;
|
|
31509
|
+
|
|
31502
31510
|
const auto &layout = result_data.layout;
|
|
31503
31511
|
const idx_t row_width = layout.GetRowWidth();
|
|
31504
31512
|
const idx_t heap_pointer_offset = layout.GetHeapPointerOffset();
|
|
@@ -31527,76 +31535,70 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD
|
|
|
31527
31535
|
idx_t copied = 0;
|
|
31528
31536
|
while (copied < count) {
|
|
31529
31537
|
// Move to new data blocks (if needed)
|
|
31530
|
-
if (
|
|
31531
|
-
l_data.entry_idx == l_data.data_blocks[l_data.block_idx].count) {
|
|
31538
|
+
if (l.block_idx < l_data.data_blocks.size() && l.entry_idx == l_data.data_blocks[l.block_idx].count) {
|
|
31532
31539
|
// Delete reference to previous block
|
|
31533
|
-
l_data.data_blocks[
|
|
31540
|
+
l_data.data_blocks[l.block_idx].block = nullptr;
|
|
31534
31541
|
if (!layout.AllConstant() && state.external) {
|
|
31535
|
-
l_data.heap_blocks[
|
|
31542
|
+
l_data.heap_blocks[l.block_idx].block = nullptr;
|
|
31536
31543
|
}
|
|
31537
31544
|
// Advance block
|
|
31538
|
-
|
|
31539
|
-
|
|
31545
|
+
l.block_idx++;
|
|
31546
|
+
l.entry_idx = 0;
|
|
31540
31547
|
}
|
|
31541
|
-
if (
|
|
31542
|
-
r_data.entry_idx == r_data.data_blocks[r_data.block_idx].count) {
|
|
31548
|
+
if (r.block_idx < r_data.data_blocks.size() && r.entry_idx == r_data.data_blocks[r.block_idx].count) {
|
|
31543
31549
|
// Delete reference to previous block
|
|
31544
|
-
r_data.data_blocks[
|
|
31550
|
+
r_data.data_blocks[r.block_idx].block = nullptr;
|
|
31545
31551
|
if (!layout.AllConstant() && state.external) {
|
|
31546
|
-
r_data.heap_blocks[
|
|
31552
|
+
r_data.heap_blocks[r.block_idx].block = nullptr;
|
|
31547
31553
|
}
|
|
31548
31554
|
// Advance block
|
|
31549
|
-
|
|
31550
|
-
|
|
31555
|
+
r.block_idx++;
|
|
31556
|
+
r.entry_idx = 0;
|
|
31551
31557
|
}
|
|
31552
|
-
const bool l_done =
|
|
31553
|
-
const bool r_done =
|
|
31558
|
+
const bool l_done = l.block_idx == l_data.data_blocks.size();
|
|
31559
|
+
const bool r_done = r.block_idx == r_data.data_blocks.size();
|
|
31554
31560
|
// Pin the row data blocks
|
|
31555
31561
|
if (!l_done) {
|
|
31556
|
-
|
|
31557
|
-
l_ptr =
|
|
31562
|
+
l.PinData(l_data);
|
|
31563
|
+
l_ptr = l.DataPtr(l_data);
|
|
31558
31564
|
}
|
|
31559
31565
|
if (!r_done) {
|
|
31560
|
-
|
|
31561
|
-
r_ptr =
|
|
31566
|
+
r.PinData(r_data);
|
|
31567
|
+
r_ptr = r.DataPtr(r_data);
|
|
31562
31568
|
}
|
|
31563
|
-
const idx_t &l_count = !l_done ? l_data.data_blocks[
|
|
31564
|
-
const idx_t &r_count = !r_done ? r_data.data_blocks[
|
|
31569
|
+
const idx_t &l_count = !l_done ? l_data.data_blocks[l.block_idx].count : 0;
|
|
31570
|
+
const idx_t &r_count = !r_done ? r_data.data_blocks[r.block_idx].count : 0;
|
|
31565
31571
|
// Perform the merge
|
|
31566
31572
|
if (layout.AllConstant() || !state.external) {
|
|
31567
31573
|
// If all constant size, or if we are doing an in-memory sort, we do not need to touch the heap
|
|
31568
31574
|
if (!l_done && !r_done) {
|
|
31569
31575
|
// Both sides have data - merge
|
|
31570
|
-
MergeRows(l_ptr,
|
|
31571
|
-
|
|
31576
|
+
MergeRows(l_ptr, l.entry_idx, l_count, r_ptr, r.entry_idx, r_count, result_data_block, result_data_ptr,
|
|
31577
|
+
row_width, left_smaller, copied, count);
|
|
31572
31578
|
} else if (r_done) {
|
|
31573
31579
|
// Right side is exhausted
|
|
31574
|
-
FlushRows(l_ptr,
|
|
31575
|
-
count);
|
|
31580
|
+
FlushRows(l_ptr, l.entry_idx, l_count, result_data_block, result_data_ptr, row_width, copied, count);
|
|
31576
31581
|
} else {
|
|
31577
31582
|
// Left side is exhausted
|
|
31578
|
-
FlushRows(r_ptr,
|
|
31579
|
-
count);
|
|
31583
|
+
FlushRows(r_ptr, r.entry_idx, r_count, result_data_block, result_data_ptr, row_width, copied, count);
|
|
31580
31584
|
}
|
|
31581
31585
|
} else {
|
|
31582
31586
|
// External sorting with variable size data. Pin the heap blocks too
|
|
31583
31587
|
if (!l_done) {
|
|
31584
|
-
l_heap_ptr =
|
|
31585
|
-
D_ASSERT(l_heap_ptr -
|
|
31586
|
-
D_ASSERT((idx_t)(l_heap_ptr -
|
|
31587
|
-
l_data.heap_blocks[l_data.block_idx].byte_offset);
|
|
31588
|
+
l_heap_ptr = l.BaseHeapPtr(l_data) + Load<idx_t>(l_ptr + heap_pointer_offset);
|
|
31589
|
+
D_ASSERT(l_heap_ptr - l.BaseHeapPtr(l_data) >= 0);
|
|
31590
|
+
D_ASSERT((idx_t)(l_heap_ptr - l.BaseHeapPtr(l_data)) < l_data.heap_blocks[l.block_idx].byte_offset);
|
|
31588
31591
|
}
|
|
31589
31592
|
if (!r_done) {
|
|
31590
|
-
r_heap_ptr =
|
|
31591
|
-
D_ASSERT(r_heap_ptr -
|
|
31592
|
-
D_ASSERT((idx_t)(r_heap_ptr -
|
|
31593
|
-
r_data.heap_blocks[r_data.block_idx].byte_offset);
|
|
31593
|
+
r_heap_ptr = r.BaseHeapPtr(r_data) + Load<idx_t>(r_ptr + heap_pointer_offset);
|
|
31594
|
+
D_ASSERT(r_heap_ptr - r.BaseHeapPtr(r_data) >= 0);
|
|
31595
|
+
D_ASSERT((idx_t)(r_heap_ptr - r.BaseHeapPtr(r_data)) < r_data.heap_blocks[r.block_idx].byte_offset);
|
|
31594
31596
|
}
|
|
31595
31597
|
// Both the row and heap data need to be dealt with
|
|
31596
31598
|
if (!l_done && !r_done) {
|
|
31597
31599
|
// Both sides have data - merge
|
|
31598
|
-
idx_t l_idx_copy =
|
|
31599
|
-
idx_t r_idx_copy =
|
|
31600
|
+
idx_t l_idx_copy = l.entry_idx;
|
|
31601
|
+
idx_t r_idx_copy = r.entry_idx;
|
|
31600
31602
|
data_ptr_t result_data_ptr_copy = result_data_ptr;
|
|
31601
31603
|
idx_t copied_copy = copied;
|
|
31602
31604
|
// Merge row data
|
|
@@ -31618,10 +31620,10 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD
|
|
|
31618
31620
|
entry_size =
|
|
31619
31621
|
l_smaller * Load<uint32_t>(l_heap_ptr_copy) + r_smaller * Load<uint32_t>(r_heap_ptr_copy);
|
|
31620
31622
|
D_ASSERT(entry_size >= sizeof(uint32_t));
|
|
31621
|
-
D_ASSERT(l_heap_ptr_copy -
|
|
31622
|
-
l_data.heap_blocks[
|
|
31623
|
-
D_ASSERT(r_heap_ptr_copy -
|
|
31624
|
-
r_data.heap_blocks[
|
|
31623
|
+
D_ASSERT(l_heap_ptr_copy - l.BaseHeapPtr(l_data) + l_smaller * entry_size <=
|
|
31624
|
+
l_data.heap_blocks[l.block_idx].byte_offset);
|
|
31625
|
+
D_ASSERT(r_heap_ptr_copy - r.BaseHeapPtr(r_data) + r_smaller * entry_size <=
|
|
31626
|
+
r_data.heap_blocks[r.block_idx].byte_offset);
|
|
31625
31627
|
l_heap_ptr_copy += l_smaller * entry_size;
|
|
31626
31628
|
r_heap_ptr_copy += r_smaller * entry_size;
|
|
31627
31629
|
copy_bytes += entry_size;
|
|
@@ -31645,8 +31647,8 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD
|
|
|
31645
31647
|
result_heap_ptr += entry_size;
|
|
31646
31648
|
l_heap_ptr += l_smaller * entry_size;
|
|
31647
31649
|
r_heap_ptr += r_smaller * entry_size;
|
|
31648
|
-
|
|
31649
|
-
|
|
31650
|
+
l.entry_idx += l_smaller;
|
|
31651
|
+
r.entry_idx += r_smaller;
|
|
31650
31652
|
}
|
|
31651
31653
|
// Update result indices and pointers
|
|
31652
31654
|
result_heap_block->count += merged;
|
|
@@ -31654,16 +31656,20 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD
|
|
|
31654
31656
|
copied += merged;
|
|
31655
31657
|
} else if (r_done) {
|
|
31656
31658
|
// Right side is exhausted - flush left
|
|
31657
|
-
FlushBlobs(layout, l_count, l_ptr,
|
|
31659
|
+
FlushBlobs(layout, l_count, l_ptr, l.entry_idx, l_heap_ptr, result_data_block, result_data_ptr,
|
|
31658
31660
|
result_heap_block, *result_heap_handle, result_heap_ptr, copied, count);
|
|
31659
31661
|
} else {
|
|
31660
31662
|
// Left side is exhausted - flush right
|
|
31661
|
-
FlushBlobs(layout, r_count, r_ptr,
|
|
31663
|
+
FlushBlobs(layout, r_count, r_ptr, r.entry_idx, r_heap_ptr, result_data_block, result_data_ptr,
|
|
31662
31664
|
result_heap_block, *result_heap_handle, result_heap_ptr, copied, count);
|
|
31663
31665
|
}
|
|
31664
31666
|
D_ASSERT(result_data_block->count == result_heap_block->count);
|
|
31665
31667
|
}
|
|
31666
31668
|
}
|
|
31669
|
+
if (reset_indices) {
|
|
31670
|
+
left->SetIndices(l_block_idx_before, l_entry_idx_before);
|
|
31671
|
+
right->SetIndices(r_block_idx_before, r_entry_idx_before);
|
|
31672
|
+
}
|
|
31667
31673
|
}
|
|
31668
31674
|
|
|
31669
31675
|
void MergeSorter::MergeRows(data_ptr_t &l_ptr, idx_t &l_entry_idx, const idx_t &l_count, data_ptr_t &r_ptr,
|
|
@@ -32638,8 +32644,9 @@ void GlobalSortState::CompleteMergeRound() {
|
|
|
32638
32644
|
|
|
32639
32645
|
namespace duckdb {
|
|
32640
32646
|
|
|
32641
|
-
SortedData::SortedData(const RowLayout &layout, BufferManager &buffer_manager,
|
|
32642
|
-
|
|
32647
|
+
SortedData::SortedData(SortedDataType type, const RowLayout &layout, BufferManager &buffer_manager,
|
|
32648
|
+
GlobalSortState &state)
|
|
32649
|
+
: type(type), layout(layout), swizzled(false), buffer_manager(buffer_manager), state(state) {
|
|
32643
32650
|
}
|
|
32644
32651
|
|
|
32645
32652
|
idx_t SortedData::Count() {
|
|
@@ -32652,37 +32659,6 @@ idx_t SortedData::Count() {
|
|
|
32652
32659
|
return count;
|
|
32653
32660
|
}
|
|
32654
32661
|
|
|
32655
|
-
void SortedData::Pin() {
|
|
32656
|
-
PinData();
|
|
32657
|
-
if (!layout.AllConstant() && state.external) {
|
|
32658
|
-
PinHeap();
|
|
32659
|
-
}
|
|
32660
|
-
}
|
|
32661
|
-
|
|
32662
|
-
data_ptr_t SortedData::DataPtr() const {
|
|
32663
|
-
D_ASSERT(data_blocks[block_idx].block->Readers() != 0 &&
|
|
32664
|
-
data_handle->handle->BlockId() == data_blocks[block_idx].block->BlockId());
|
|
32665
|
-
return data_ptr + entry_idx * layout.GetRowWidth();
|
|
32666
|
-
}
|
|
32667
|
-
|
|
32668
|
-
data_ptr_t SortedData::HeapPtr() const {
|
|
32669
|
-
D_ASSERT(!layout.AllConstant() && state.external);
|
|
32670
|
-
D_ASSERT(heap_blocks[block_idx].block->Readers() != 0 &&
|
|
32671
|
-
heap_handle->handle->BlockId() == heap_blocks[block_idx].block->BlockId());
|
|
32672
|
-
return heap_ptr + Load<idx_t>(DataPtr() + layout.GetHeapPointerOffset());
|
|
32673
|
-
}
|
|
32674
|
-
|
|
32675
|
-
void SortedData::Advance(const bool &adv) {
|
|
32676
|
-
entry_idx += adv;
|
|
32677
|
-
if (entry_idx == data_blocks[block_idx].count) {
|
|
32678
|
-
block_idx++;
|
|
32679
|
-
entry_idx = 0;
|
|
32680
|
-
if (block_idx < data_blocks.size()) {
|
|
32681
|
-
Pin();
|
|
32682
|
-
}
|
|
32683
|
-
}
|
|
32684
|
-
}
|
|
32685
|
-
|
|
32686
32662
|
void SortedData::CreateBlock() {
|
|
32687
32663
|
auto capacity =
|
|
32688
32664
|
MaxValue(((idx_t)Storage::BLOCK_SIZE + layout.GetRowWidth() - 1) / layout.GetRowWidth(), state.block_capacity);
|
|
@@ -32693,15 +32669,9 @@ void SortedData::CreateBlock() {
|
|
|
32693
32669
|
}
|
|
32694
32670
|
}
|
|
32695
32671
|
|
|
32696
|
-
|
|
32697
|
-
block_idx = block_idx_to;
|
|
32698
|
-
entry_idx = entry_idx_to;
|
|
32699
|
-
}
|
|
32700
|
-
|
|
32701
|
-
unique_ptr<SortedData> SortedData::CreateSlice(idx_t start_block_index, idx_t start_entry_index, idx_t end_block_index,
|
|
32702
|
-
idx_t end_entry_index) {
|
|
32672
|
+
unique_ptr<SortedData> SortedData::CreateSlice(idx_t start_block_index, idx_t end_block_index, idx_t end_entry_index) {
|
|
32703
32673
|
// Add the corresponding blocks to the result
|
|
32704
|
-
auto result = make_unique<SortedData>(layout, buffer_manager, state);
|
|
32674
|
+
auto result = make_unique<SortedData>(type, layout, buffer_manager, state);
|
|
32705
32675
|
for (idx_t i = start_block_index; i <= end_block_index; i++) {
|
|
32706
32676
|
result->data_blocks.push_back(data_blocks[i]);
|
|
32707
32677
|
if (!layout.AllConstant() && state.external) {
|
|
@@ -32716,7 +32686,6 @@ unique_ptr<SortedData> SortedData::CreateSlice(idx_t start_block_index, idx_t st
|
|
|
32716
32686
|
}
|
|
32717
32687
|
}
|
|
32718
32688
|
// Use start and end entry indices to set the boundaries
|
|
32719
|
-
result->entry_idx = start_entry_index;
|
|
32720
32689
|
D_ASSERT(end_entry_index <= result->data_blocks.back().count);
|
|
32721
32690
|
result->data_blocks.back().count = end_entry_index;
|
|
32722
32691
|
if (!layout.AllConstant() && state.external) {
|
|
@@ -32742,29 +32711,11 @@ void SortedData::Unswizzle() {
|
|
|
32742
32711
|
heap_blocks.clear();
|
|
32743
32712
|
}
|
|
32744
32713
|
|
|
32745
|
-
void SortedData::PinData() {
|
|
32746
|
-
D_ASSERT(block_idx < data_blocks.size());
|
|
32747
|
-
auto &block = data_blocks[block_idx];
|
|
32748
|
-
if (!data_handle || data_handle->handle->BlockId() != block.block->BlockId()) {
|
|
32749
|
-
data_handle = buffer_manager.Pin(data_blocks[block_idx].block);
|
|
32750
|
-
}
|
|
32751
|
-
data_ptr = data_handle->Ptr();
|
|
32752
|
-
}
|
|
32753
|
-
|
|
32754
|
-
void SortedData::PinHeap() {
|
|
32755
|
-
D_ASSERT(!layout.AllConstant() && state.external);
|
|
32756
|
-
auto &block = heap_blocks[block_idx];
|
|
32757
|
-
if (!heap_handle || heap_handle->handle->BlockId() != block.block->BlockId()) {
|
|
32758
|
-
heap_handle = buffer_manager.Pin(heap_blocks[block_idx].block);
|
|
32759
|
-
}
|
|
32760
|
-
heap_ptr = heap_handle->Ptr();
|
|
32761
|
-
}
|
|
32762
|
-
|
|
32763
32714
|
SortedBlock::SortedBlock(BufferManager &buffer_manager, GlobalSortState &state)
|
|
32764
|
-
:
|
|
32715
|
+
: buffer_manager(buffer_manager), state(state), sort_layout(state.sort_layout),
|
|
32765
32716
|
payload_layout(state.payload_layout) {
|
|
32766
|
-
blob_sorting_data = make_unique<SortedData>(sort_layout.blob_layout, buffer_manager, state);
|
|
32767
|
-
payload_data = make_unique<SortedData>(payload_layout, buffer_manager, state);
|
|
32717
|
+
blob_sorting_data = make_unique<SortedData>(SortedDataType::BLOB, sort_layout.blob_layout, buffer_manager, state);
|
|
32718
|
+
payload_data = make_unique<SortedData>(SortedDataType::PAYLOAD, payload_layout, buffer_manager, state);
|
|
32768
32719
|
}
|
|
32769
32720
|
|
|
32770
32721
|
idx_t SortedBlock::Count() const {
|
|
@@ -32777,17 +32728,6 @@ idx_t SortedBlock::Count() const {
|
|
|
32777
32728
|
return count;
|
|
32778
32729
|
}
|
|
32779
32730
|
|
|
32780
|
-
idx_t SortedBlock::Remaining() const {
|
|
32781
|
-
idx_t remaining = 0;
|
|
32782
|
-
if (block_idx < radix_sorting_data.size()) {
|
|
32783
|
-
remaining += radix_sorting_data[block_idx].count - entry_idx;
|
|
32784
|
-
for (idx_t i = block_idx + 1; i < radix_sorting_data.size(); i++) {
|
|
32785
|
-
remaining += radix_sorting_data[i].count;
|
|
32786
|
-
}
|
|
32787
|
-
}
|
|
32788
|
-
return remaining;
|
|
32789
|
-
}
|
|
32790
|
-
|
|
32791
32731
|
void SortedBlock::InitializeWrite() {
|
|
32792
32732
|
CreateBlock();
|
|
32793
32733
|
if (!sort_layout.all_constant) {
|
|
@@ -32802,14 +32742,6 @@ void SortedBlock::CreateBlock() {
|
|
|
32802
32742
|
radix_sorting_data.emplace_back(buffer_manager, capacity, sort_layout.entry_size);
|
|
32803
32743
|
}
|
|
32804
32744
|
|
|
32805
|
-
void SortedBlock::PinRadix(idx_t pin_block_idx) {
|
|
32806
|
-
D_ASSERT(pin_block_idx < radix_sorting_data.size());
|
|
32807
|
-
auto &block = radix_sorting_data[pin_block_idx];
|
|
32808
|
-
if (!radix_handle || radix_handle->handle->BlockId() != block.block->BlockId()) {
|
|
32809
|
-
radix_handle = buffer_manager.Pin(block.block);
|
|
32810
|
-
}
|
|
32811
|
-
}
|
|
32812
|
-
|
|
32813
32745
|
void SortedBlock::AppendSortedBlocks(vector<unique_ptr<SortedBlock>> &sorted_blocks) {
|
|
32814
32746
|
D_ASSERT(Count() == 0);
|
|
32815
32747
|
for (auto &sb : sorted_blocks) {
|
|
@@ -32854,7 +32786,7 @@ void SortedBlock::GlobalToLocalIndex(const idx_t &global_idx, idx_t &local_block
|
|
|
32854
32786
|
D_ASSERT(local_entry_index < radix_sorting_data[local_block_index].count);
|
|
32855
32787
|
}
|
|
32856
32788
|
|
|
32857
|
-
unique_ptr<SortedBlock> SortedBlock::CreateSlice(const idx_t start, const idx_t end) {
|
|
32789
|
+
unique_ptr<SortedBlock> SortedBlock::CreateSlice(const idx_t start, const idx_t end, idx_t &entry_idx) {
|
|
32858
32790
|
// Identify blocks/entry indices of this slice
|
|
32859
32791
|
idx_t start_block_index;
|
|
32860
32792
|
idx_t start_entry_index;
|
|
@@ -32872,18 +32804,15 @@ unique_ptr<SortedBlock> SortedBlock::CreateSlice(const idx_t start, const idx_t
|
|
|
32872
32804
|
radix_sorting_data[i].block = nullptr;
|
|
32873
32805
|
}
|
|
32874
32806
|
// Use start and end entry indices to set the boundaries
|
|
32875
|
-
|
|
32807
|
+
entry_idx = start_entry_index;
|
|
32876
32808
|
D_ASSERT(end_entry_index <= result->radix_sorting_data.back().count);
|
|
32877
32809
|
result->radix_sorting_data.back().count = end_entry_index;
|
|
32878
32810
|
// Same for the var size sorting data
|
|
32879
32811
|
if (!sort_layout.all_constant) {
|
|
32880
|
-
result->blob_sorting_data =
|
|
32881
|
-
blob_sorting_data->CreateSlice(start_block_index, start_entry_index, end_block_index, end_entry_index);
|
|
32812
|
+
result->blob_sorting_data = blob_sorting_data->CreateSlice(start_block_index, end_block_index, end_entry_index);
|
|
32882
32813
|
}
|
|
32883
32814
|
// And the payload data
|
|
32884
|
-
result->payload_data =
|
|
32885
|
-
payload_data->CreateSlice(start_block_index, start_entry_index, end_block_index, end_entry_index);
|
|
32886
|
-
D_ASSERT(result->Remaining() == end - start);
|
|
32815
|
+
result->payload_data = payload_data->CreateSlice(start_block_index, end_block_index, end_entry_index);
|
|
32887
32816
|
return result;
|
|
32888
32817
|
}
|
|
32889
32818
|
|
|
@@ -32918,19 +32847,90 @@ idx_t SortedBlock::SizeInBytes() const {
|
|
|
32918
32847
|
return bytes;
|
|
32919
32848
|
}
|
|
32920
32849
|
|
|
32921
|
-
|
|
32922
|
-
:
|
|
32923
|
-
|
|
32850
|
+
SBScanState::SBScanState(BufferManager &buffer_manager, GlobalSortState &state)
|
|
32851
|
+
: buffer_manager(buffer_manager), sort_layout(state.sort_layout), state(state), block_idx(0), entry_idx(0) {
|
|
32852
|
+
}
|
|
32853
|
+
|
|
32854
|
+
void SBScanState::PinRadix(idx_t block_idx_to) {
|
|
32855
|
+
auto &radix_sorting_data = sb->radix_sorting_data;
|
|
32856
|
+
D_ASSERT(block_idx_to < radix_sorting_data.size());
|
|
32857
|
+
auto &block = radix_sorting_data[block_idx_to];
|
|
32858
|
+
if (!radix_handle || radix_handle->handle->BlockId() != block.block->BlockId()) {
|
|
32859
|
+
radix_handle = buffer_manager.Pin(block.block);
|
|
32860
|
+
}
|
|
32861
|
+
}
|
|
32862
|
+
|
|
32863
|
+
void SBScanState::PinData(SortedData &sd) {
|
|
32864
|
+
D_ASSERT(block_idx < sd.data_blocks.size());
|
|
32865
|
+
auto &data_handle = sd.type == SortedDataType::BLOB ? blob_sorting_data_handle : payload_data_handle;
|
|
32866
|
+
auto &heap_handle = sd.type == SortedDataType::BLOB ? blob_sorting_heap_handle : payload_heap_handle;
|
|
32867
|
+
|
|
32868
|
+
auto &data_block = sd.data_blocks[block_idx];
|
|
32869
|
+
if (!data_handle || data_handle->handle->BlockId() != data_block.block->BlockId()) {
|
|
32870
|
+
data_handle = buffer_manager.Pin(data_block.block);
|
|
32871
|
+
}
|
|
32872
|
+
if (sd.layout.AllConstant() || !state.external) {
|
|
32873
|
+
return;
|
|
32874
|
+
}
|
|
32875
|
+
auto &heap_block = sd.heap_blocks[block_idx];
|
|
32876
|
+
if (!heap_handle || heap_handle->handle->BlockId() != heap_block.block->BlockId()) {
|
|
32877
|
+
heap_handle = buffer_manager.Pin(heap_block.block);
|
|
32878
|
+
}
|
|
32879
|
+
}
|
|
32880
|
+
|
|
32881
|
+
data_ptr_t SBScanState::RadixPtr() const {
|
|
32882
|
+
return radix_handle->Ptr() + entry_idx * sort_layout.entry_size;
|
|
32883
|
+
}
|
|
32884
|
+
|
|
32885
|
+
data_ptr_t SBScanState::DataPtr(SortedData &sd) const {
|
|
32886
|
+
auto &data_handle = sd.type == SortedDataType::BLOB ? *blob_sorting_data_handle : *payload_data_handle;
|
|
32887
|
+
D_ASSERT(sd.data_blocks[block_idx].block->Readers() != 0 &&
|
|
32888
|
+
data_handle.handle->BlockId() == sd.data_blocks[block_idx].block->BlockId());
|
|
32889
|
+
return data_handle.Ptr() + entry_idx * sd.layout.GetRowWidth();
|
|
32890
|
+
}
|
|
32891
|
+
|
|
32892
|
+
data_ptr_t SBScanState::HeapPtr(SortedData &sd) const {
|
|
32893
|
+
return BaseHeapPtr(sd) + Load<idx_t>(DataPtr(sd) + sd.layout.GetHeapPointerOffset());
|
|
32924
32894
|
}
|
|
32925
32895
|
|
|
32926
|
-
|
|
32896
|
+
data_ptr_t SBScanState::BaseHeapPtr(SortedData &sd) const {
|
|
32897
|
+
auto &heap_handle = sd.type == SortedDataType::BLOB ? *blob_sorting_heap_handle : *payload_heap_handle;
|
|
32898
|
+
D_ASSERT(!sd.layout.AllConstant() && state.external);
|
|
32899
|
+
D_ASSERT(sd.heap_blocks[block_idx].block->Readers() != 0 &&
|
|
32900
|
+
heap_handle.handle->BlockId() == sd.heap_blocks[block_idx].block->BlockId());
|
|
32901
|
+
return heap_handle.Ptr();
|
|
32902
|
+
}
|
|
32903
|
+
|
|
32904
|
+
idx_t SBScanState::Remaining() const {
|
|
32905
|
+
const auto &blocks = sb->radix_sorting_data;
|
|
32906
|
+
idx_t remaining = 0;
|
|
32907
|
+
if (block_idx < blocks.size()) {
|
|
32908
|
+
remaining += blocks[block_idx].count - entry_idx;
|
|
32909
|
+
for (idx_t i = block_idx + 1; i < blocks.size(); i++) {
|
|
32910
|
+
remaining += blocks[i].count;
|
|
32911
|
+
}
|
|
32912
|
+
}
|
|
32913
|
+
return remaining;
|
|
32914
|
+
}
|
|
32915
|
+
|
|
32916
|
+
void SBScanState::SetIndices(idx_t block_idx_to, idx_t entry_idx_to) {
|
|
32917
|
+
block_idx = block_idx_to;
|
|
32918
|
+
entry_idx = entry_idx_to;
|
|
32919
|
+
}
|
|
32920
|
+
|
|
32921
|
+
PayloadScanner::PayloadScanner(SortedData &sorted_data, GlobalSortState &global_sort_state)
|
|
32922
|
+
: sorted_data(sorted_data), read_state(global_sort_state.buffer_manager, global_sort_state),
|
|
32923
|
+
total_count(sorted_data.Count()), global_sort_state(global_sort_state), total_scanned(0) {
|
|
32924
|
+
}
|
|
32925
|
+
|
|
32926
|
+
void PayloadScanner::Scan(DataChunk &chunk) {
|
|
32927
32927
|
auto count = MinValue((idx_t)STANDARD_VECTOR_SIZE, total_count - total_scanned);
|
|
32928
32928
|
if (count == 0) {
|
|
32929
|
-
D_ASSERT(
|
|
32929
|
+
D_ASSERT(read_state.block_idx == sorted_data.data_blocks.size());
|
|
32930
32930
|
return;
|
|
32931
32931
|
}
|
|
32932
32932
|
// Eagerly delete references to blocks that we've passed
|
|
32933
|
-
for (idx_t i = 0; i <
|
|
32933
|
+
for (idx_t i = 0; i < read_state.block_idx; i++) {
|
|
32934
32934
|
sorted_data.data_blocks[i].block = nullptr;
|
|
32935
32935
|
}
|
|
32936
32936
|
const idx_t &row_width = sorted_data.layout.GetRowWidth();
|
|
@@ -32938,10 +32938,10 @@ void SortedDataScanner::Scan(DataChunk &chunk) {
|
|
|
32938
32938
|
idx_t scanned = 0;
|
|
32939
32939
|
auto data_pointers = FlatVector::GetData<data_ptr_t>(addresses);
|
|
32940
32940
|
while (scanned < count) {
|
|
32941
|
-
|
|
32942
|
-
auto &data_block = sorted_data.data_blocks[
|
|
32943
|
-
idx_t next = MinValue(data_block.count -
|
|
32944
|
-
const data_ptr_t data_ptr =
|
|
32941
|
+
read_state.PinData(sorted_data);
|
|
32942
|
+
auto &data_block = sorted_data.data_blocks[read_state.block_idx];
|
|
32943
|
+
idx_t next = MinValue(data_block.count - read_state.entry_idx, count - scanned);
|
|
32944
|
+
const data_ptr_t data_ptr = read_state.payload_data_handle->Ptr() + read_state.entry_idx * row_width;
|
|
32945
32945
|
// Set up the next pointers
|
|
32946
32946
|
data_ptr_t row_ptr = data_ptr;
|
|
32947
32947
|
for (idx_t i = 0; i < next; i++) {
|
|
@@ -32950,14 +32950,15 @@ void SortedDataScanner::Scan(DataChunk &chunk) {
|
|
|
32950
32950
|
}
|
|
32951
32951
|
// Unswizzle the offsets back to pointers (if needed)
|
|
32952
32952
|
if (!sorted_data.layout.AllConstant() && global_sort_state.external) {
|
|
32953
|
-
RowOperations::UnswizzleHeapPointer(sorted_data.layout, data_ptr,
|
|
32953
|
+
RowOperations::UnswizzleHeapPointer(sorted_data.layout, data_ptr, read_state.payload_heap_handle->Ptr(),
|
|
32954
|
+
next);
|
|
32954
32955
|
RowOperations::UnswizzleColumns(sorted_data.layout, data_ptr, next);
|
|
32955
32956
|
}
|
|
32956
32957
|
// Update state indices
|
|
32957
|
-
|
|
32958
|
-
if (
|
|
32959
|
-
|
|
32960
|
-
|
|
32958
|
+
read_state.entry_idx += next;
|
|
32959
|
+
if (read_state.entry_idx == data_block.count) {
|
|
32960
|
+
read_state.block_idx++;
|
|
32961
|
+
read_state.entry_idx = 0;
|
|
32961
32962
|
}
|
|
32962
32963
|
scanned += next;
|
|
32963
32964
|
}
|
|
@@ -56551,7 +56552,7 @@ static void ScanSortedPartition(WindowOperatorState &state, ChunkCollection &inp
|
|
|
56551
56552
|
payload_types.insert(payload_types.end(), over_types.begin(), over_types.end());
|
|
56552
56553
|
|
|
56553
56554
|
// scan the sorted row data
|
|
56554
|
-
|
|
56555
|
+
PayloadScanner scanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state);
|
|
56555
56556
|
for (;;) {
|
|
56556
56557
|
DataChunk payload_chunk;
|
|
56557
56558
|
payload_chunk.Initialize(payload_types);
|
|
@@ -62364,7 +62365,7 @@ void PhysicalOrder::ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGl
|
|
|
62364
62365
|
class PhysicalOrderOperatorState : public GlobalSourceState {
|
|
62365
62366
|
public:
|
|
62366
62367
|
//! Payload scanner
|
|
62367
|
-
unique_ptr<
|
|
62368
|
+
unique_ptr<PayloadScanner> scanner;
|
|
62368
62369
|
};
|
|
62369
62370
|
|
|
62370
62371
|
unique_ptr<GlobalSourceState> PhysicalOrder::GetGlobalSourceState(ClientContext &context) const {
|
|
@@ -62383,7 +62384,7 @@ void PhysicalOrder::GetData(ExecutionContext &context, DataChunk &chunk, GlobalS
|
|
|
62383
62384
|
return;
|
|
62384
62385
|
}
|
|
62385
62386
|
state.scanner =
|
|
62386
|
-
make_unique<
|
|
62387
|
+
make_unique<PayloadScanner>(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state);
|
|
62387
62388
|
}
|
|
62388
62389
|
|
|
62389
62390
|
// Scan the next data chunk
|
|
@@ -62483,7 +62484,7 @@ PhysicalTopN::PhysicalTopN(vector<LogicalType> types, vector<BoundOrderByNode> o
|
|
|
62483
62484
|
class TopNHeap;
|
|
62484
62485
|
|
|
62485
62486
|
struct TopNScanState {
|
|
62486
|
-
unique_ptr<
|
|
62487
|
+
unique_ptr<PayloadScanner> scanner;
|
|
62487
62488
|
idx_t pos;
|
|
62488
62489
|
bool exclude_offset;
|
|
62489
62490
|
};
|
|
@@ -62613,7 +62614,7 @@ void TopNSortState::InitializeScan(TopNScanState &state, bool exclude_offset) {
|
|
|
62613
62614
|
state.scanner = nullptr;
|
|
62614
62615
|
} else {
|
|
62615
62616
|
D_ASSERT(global_state->sorted_blocks.size() == 1);
|
|
62616
|
-
state.scanner = make_unique<
|
|
62617
|
+
state.scanner = make_unique<PayloadScanner>(*global_state->sorted_blocks[0]->payload_data, *global_state);
|
|
62617
62618
|
}
|
|
62618
62619
|
state.pos = 0;
|
|
62619
62620
|
state.exclude_offset = exclude_offset && heap.offset > 0;
|
|
@@ -80621,6 +80622,11 @@ struct RLEFun {
|
|
|
80621
80622
|
static bool TypeIsSupported(PhysicalType type);
|
|
80622
80623
|
};
|
|
80623
80624
|
|
|
80625
|
+
struct BitpackingFun {
|
|
80626
|
+
static CompressionFunction GetFunction(PhysicalType type);
|
|
80627
|
+
static bool TypeIsSupported(PhysicalType type);
|
|
80628
|
+
};
|
|
80629
|
+
|
|
80624
80630
|
} // namespace duckdb
|
|
80625
80631
|
|
|
80626
80632
|
|
|
@@ -80640,6 +80646,7 @@ static DefaultCompressionMethod internal_compression_methods[] = {
|
|
|
80640
80646
|
{CompressionType::COMPRESSION_CONSTANT, ConstantFun::GetFunction, ConstantFun::TypeIsSupported},
|
|
80641
80647
|
{CompressionType::COMPRESSION_UNCOMPRESSED, UncompressedFun::GetFunction, UncompressedFun::TypeIsSupported},
|
|
80642
80648
|
{CompressionType::COMPRESSION_RLE, RLEFun::GetFunction, RLEFun::TypeIsSupported},
|
|
80649
|
+
{CompressionType::COMPRESSION_BITPACKING, BitpackingFun::GetFunction, BitpackingFun::TypeIsSupported},
|
|
80643
80650
|
{CompressionType::COMPRESSION_AUTO, nullptr, nullptr}};
|
|
80644
80651
|
|
|
80645
80652
|
static CompressionFunction *FindCompressionFunction(CompressionFunctionSet &set, CompressionType type,
|
|
@@ -80688,6 +80695,7 @@ vector<CompressionFunction *> DBConfig::GetCompressionFunctions(PhysicalType dat
|
|
|
80688
80695
|
vector<CompressionFunction *> result;
|
|
80689
80696
|
TryLoadCompression(*this, result, CompressionType::COMPRESSION_UNCOMPRESSED, data_type);
|
|
80690
80697
|
TryLoadCompression(*this, result, CompressionType::COMPRESSION_RLE, data_type);
|
|
80698
|
+
TryLoadCompression(*this, result, CompressionType::COMPRESSION_BITPACKING, data_type);
|
|
80691
80699
|
return result;
|
|
80692
80700
|
}
|
|
80693
80701
|
|
|
@@ -159282,56 +159290,1170 @@ void PartialBlock::FlushToDisk(DatabaseInstance &db) {
|
|
|
159282
159290
|
}
|
|
159283
159291
|
|
|
159284
159292
|
} // namespace duckdb
|
|
159285
|
-
//===----------------------------------------------------------------------===//
|
|
159286
|
-
// DuckDB
|
|
159287
|
-
//
|
|
159288
|
-
// duckdb/storage/segment/uncompressed.hpp
|
|
159289
|
-
//
|
|
159290
|
-
//
|
|
159291
|
-
//===----------------------------------------------------------------------===//
|
|
159292
159293
|
|
|
159293
159294
|
|
|
159295
|
+
// LICENSE_CHANGE_BEGIN
|
|
159296
|
+
// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10
|
|
159297
|
+
// See the end of this file for a list
|
|
159294
159298
|
|
|
159299
|
+
/**
|
|
159300
|
+
* This code is released under the
|
|
159301
|
+
* Apache License Version 2.0 http://www.apache.org/licenses/.
|
|
159302
|
+
*
|
|
159303
|
+
* (c) Daniel Lemire, http://lemire.me/en/
|
|
159304
|
+
*/
|
|
159295
159305
|
|
|
159296
159306
|
|
|
159297
|
-
namespace duckdb {
|
|
159298
|
-
class DatabaseInstance;
|
|
159299
159307
|
|
|
159300
|
-
|
|
159301
|
-
|
|
159302
|
-
|
|
159303
|
-
|
|
159304
|
-
|
|
159305
|
-
|
|
159308
|
+
// LICENSE_CHANGE_BEGIN
|
|
159309
|
+
// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10
|
|
159310
|
+
// See the end of this file for a list
|
|
159311
|
+
|
|
159312
|
+
/**
|
|
159313
|
+
* This code is released under the
|
|
159314
|
+
* Apache License Version 2.0 http://www.apache.org/licenses/.
|
|
159315
|
+
*
|
|
159316
|
+
* (c) Daniel Lemire, http://fastpforlib.me/en/
|
|
159317
|
+
*/
|
|
159318
|
+
|
|
159319
|
+
#include <cinttypes>
|
|
159320
|
+
#include <string>
|
|
159321
|
+
|
|
159322
|
+
namespace duckdb_fastpforlib {
|
|
159323
|
+
namespace internal {
|
|
159324
|
+
|
|
159325
|
+
// Unpacks 8 uint8_t values
|
|
159326
|
+
void __fastunpack0(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159327
|
+
void __fastunpack1(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159328
|
+
void __fastunpack2(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159329
|
+
void __fastunpack3(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159330
|
+
void __fastunpack4(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159331
|
+
void __fastunpack5(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159332
|
+
void __fastunpack6(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159333
|
+
void __fastunpack7(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159334
|
+
void __fastunpack8(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159335
|
+
|
|
159336
|
+
// Unpacks 16 uint16_t values
|
|
159337
|
+
void __fastunpack0(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159338
|
+
void __fastunpack1(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159339
|
+
void __fastunpack2(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159340
|
+
void __fastunpack3(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159341
|
+
void __fastunpack4(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159342
|
+
void __fastunpack5(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159343
|
+
void __fastunpack6(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159344
|
+
void __fastunpack7(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159345
|
+
void __fastunpack8(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159346
|
+
void __fastunpack9(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159347
|
+
void __fastunpack10(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159348
|
+
void __fastunpack11(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159349
|
+
void __fastunpack12(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159350
|
+
void __fastunpack13(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159351
|
+
void __fastunpack14(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159352
|
+
void __fastunpack15(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159353
|
+
void __fastunpack16(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159354
|
+
|
|
159355
|
+
// Unpacks 32 uint32_t values
|
|
159356
|
+
void __fastunpack0(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159357
|
+
void __fastunpack1(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159358
|
+
void __fastunpack2(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159359
|
+
void __fastunpack3(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159360
|
+
void __fastunpack4(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159361
|
+
void __fastunpack5(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159362
|
+
void __fastunpack6(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159363
|
+
void __fastunpack7(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159364
|
+
void __fastunpack8(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159365
|
+
void __fastunpack9(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159366
|
+
void __fastunpack10(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159367
|
+
void __fastunpack11(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159368
|
+
void __fastunpack12(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159369
|
+
void __fastunpack13(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159370
|
+
void __fastunpack14(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159371
|
+
void __fastunpack15(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159372
|
+
void __fastunpack16(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159373
|
+
void __fastunpack17(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159374
|
+
void __fastunpack18(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159375
|
+
void __fastunpack19(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159376
|
+
void __fastunpack20(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159377
|
+
void __fastunpack21(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159378
|
+
void __fastunpack22(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159379
|
+
void __fastunpack23(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159380
|
+
void __fastunpack24(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159381
|
+
void __fastunpack25(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159382
|
+
void __fastunpack26(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159383
|
+
void __fastunpack27(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159384
|
+
void __fastunpack28(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159385
|
+
void __fastunpack29(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159386
|
+
void __fastunpack30(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159387
|
+
void __fastunpack31(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159388
|
+
void __fastunpack32(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159389
|
+
|
|
159390
|
+
// Unpacks 32 uint64_t values
|
|
159391
|
+
void __fastunpack0(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159392
|
+
void __fastunpack1(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159393
|
+
void __fastunpack2(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159394
|
+
void __fastunpack3(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159395
|
+
void __fastunpack4(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159396
|
+
void __fastunpack5(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159397
|
+
void __fastunpack6(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159398
|
+
void __fastunpack7(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159399
|
+
void __fastunpack8(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159400
|
+
void __fastunpack9(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159401
|
+
void __fastunpack10(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159402
|
+
void __fastunpack11(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159403
|
+
void __fastunpack12(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159404
|
+
void __fastunpack13(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159405
|
+
void __fastunpack14(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159406
|
+
void __fastunpack15(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159407
|
+
void __fastunpack16(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159408
|
+
void __fastunpack17(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159409
|
+
void __fastunpack18(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159410
|
+
void __fastunpack19(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159411
|
+
void __fastunpack20(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159412
|
+
void __fastunpack21(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159413
|
+
void __fastunpack22(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159414
|
+
void __fastunpack23(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159415
|
+
void __fastunpack24(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159416
|
+
void __fastunpack25(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159417
|
+
void __fastunpack26(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159418
|
+
void __fastunpack27(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159419
|
+
void __fastunpack28(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159420
|
+
void __fastunpack29(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159421
|
+
void __fastunpack30(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159422
|
+
void __fastunpack31(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159423
|
+
void __fastunpack32(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159424
|
+
void __fastunpack33(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159425
|
+
void __fastunpack34(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159426
|
+
void __fastunpack35(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159427
|
+
void __fastunpack36(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159428
|
+
void __fastunpack37(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159429
|
+
void __fastunpack38(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159430
|
+
void __fastunpack39(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159431
|
+
void __fastunpack40(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159432
|
+
void __fastunpack41(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159433
|
+
void __fastunpack42(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159434
|
+
void __fastunpack43(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159435
|
+
void __fastunpack44(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159436
|
+
void __fastunpack45(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159437
|
+
void __fastunpack46(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159438
|
+
void __fastunpack47(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159439
|
+
void __fastunpack48(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159440
|
+
void __fastunpack49(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159441
|
+
void __fastunpack50(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159442
|
+
void __fastunpack51(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159443
|
+
void __fastunpack52(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159444
|
+
void __fastunpack53(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159445
|
+
void __fastunpack54(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159446
|
+
void __fastunpack55(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159447
|
+
void __fastunpack56(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159448
|
+
void __fastunpack57(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159449
|
+
void __fastunpack58(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159450
|
+
void __fastunpack59(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159451
|
+
void __fastunpack60(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159452
|
+
void __fastunpack61(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159453
|
+
void __fastunpack62(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159454
|
+
void __fastunpack63(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159455
|
+
void __fastunpack64(const uint32_t *__restrict in, uint64_t *__restrict out);
|
|
159456
|
+
|
|
159457
|
+
// Packs 8 int8_t values
|
|
159458
|
+
void __fastpack0(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159459
|
+
void __fastpack1(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159460
|
+
void __fastpack2(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159461
|
+
void __fastpack3(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159462
|
+
void __fastpack4(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159463
|
+
void __fastpack5(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159464
|
+
void __fastpack6(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159465
|
+
void __fastpack7(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159466
|
+
void __fastpack8(const uint8_t *__restrict in, uint8_t *__restrict out);
|
|
159467
|
+
|
|
159468
|
+
// Packs 16 int16_t values
|
|
159469
|
+
void __fastpack0(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159470
|
+
void __fastpack1(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159471
|
+
void __fastpack2(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159472
|
+
void __fastpack3(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159473
|
+
void __fastpack4(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159474
|
+
void __fastpack5(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159475
|
+
void __fastpack6(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159476
|
+
void __fastpack7(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159477
|
+
void __fastpack8(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159478
|
+
void __fastpack9(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159479
|
+
void __fastpack10(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159480
|
+
void __fastpack11(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159481
|
+
void __fastpack12(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159482
|
+
void __fastpack13(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159483
|
+
void __fastpack14(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159484
|
+
void __fastpack15(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159485
|
+
void __fastpack16(const uint16_t *__restrict in, uint16_t *__restrict out);
|
|
159486
|
+
|
|
159487
|
+
// Packs 32 int32_t values
|
|
159488
|
+
void __fastpack0(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159489
|
+
void __fastpack1(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159490
|
+
void __fastpack2(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159491
|
+
void __fastpack3(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159492
|
+
void __fastpack4(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159493
|
+
void __fastpack5(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159494
|
+
void __fastpack6(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159495
|
+
void __fastpack7(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159496
|
+
void __fastpack8(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159497
|
+
void __fastpack9(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159498
|
+
void __fastpack10(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159499
|
+
void __fastpack11(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159500
|
+
void __fastpack12(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159501
|
+
void __fastpack13(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159502
|
+
void __fastpack14(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159503
|
+
void __fastpack15(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159504
|
+
void __fastpack16(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159505
|
+
void __fastpack17(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159506
|
+
void __fastpack18(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159507
|
+
void __fastpack19(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159508
|
+
void __fastpack20(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159509
|
+
void __fastpack21(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159510
|
+
void __fastpack22(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159511
|
+
void __fastpack23(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159512
|
+
void __fastpack24(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159513
|
+
void __fastpack25(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159514
|
+
void __fastpack26(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159515
|
+
void __fastpack27(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159516
|
+
void __fastpack28(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159517
|
+
void __fastpack29(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159518
|
+
void __fastpack30(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159519
|
+
void __fastpack31(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159520
|
+
void __fastpack32(const uint32_t *__restrict in, uint32_t *__restrict out);
|
|
159521
|
+
|
|
159522
|
+
// Packs 32 int64_t values
|
|
159523
|
+
void __fastpack0(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159524
|
+
void __fastpack1(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159525
|
+
void __fastpack2(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159526
|
+
void __fastpack3(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159527
|
+
void __fastpack4(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159528
|
+
void __fastpack5(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159529
|
+
void __fastpack6(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159530
|
+
void __fastpack7(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159531
|
+
void __fastpack8(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159532
|
+
void __fastpack9(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159533
|
+
void __fastpack10(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159534
|
+
void __fastpack11(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159535
|
+
void __fastpack12(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159536
|
+
void __fastpack13(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159537
|
+
void __fastpack14(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159538
|
+
void __fastpack15(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159539
|
+
void __fastpack16(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159540
|
+
void __fastpack17(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159541
|
+
void __fastpack18(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159542
|
+
void __fastpack19(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159543
|
+
void __fastpack20(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159544
|
+
void __fastpack21(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159545
|
+
void __fastpack22(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159546
|
+
void __fastpack23(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159547
|
+
void __fastpack24(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159548
|
+
void __fastpack25(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159549
|
+
void __fastpack26(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159550
|
+
void __fastpack27(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159551
|
+
void __fastpack28(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159552
|
+
void __fastpack29(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159553
|
+
void __fastpack30(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159554
|
+
void __fastpack31(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159555
|
+
void __fastpack32(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159556
|
+
void __fastpack33(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159557
|
+
void __fastpack34(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159558
|
+
void __fastpack35(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159559
|
+
void __fastpack36(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159560
|
+
void __fastpack37(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159561
|
+
void __fastpack38(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159562
|
+
void __fastpack39(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159563
|
+
void __fastpack40(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159564
|
+
void __fastpack41(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159565
|
+
void __fastpack42(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159566
|
+
void __fastpack43(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159567
|
+
void __fastpack44(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159568
|
+
void __fastpack45(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159569
|
+
void __fastpack46(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159570
|
+
void __fastpack47(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159571
|
+
void __fastpack48(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159572
|
+
void __fastpack49(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159573
|
+
void __fastpack50(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159574
|
+
void __fastpack51(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159575
|
+
void __fastpack52(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159576
|
+
void __fastpack53(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159577
|
+
void __fastpack54(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159578
|
+
void __fastpack55(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159579
|
+
void __fastpack56(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159580
|
+
void __fastpack57(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159581
|
+
void __fastpack58(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159582
|
+
void __fastpack59(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159583
|
+
void __fastpack60(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159584
|
+
void __fastpack61(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159585
|
+
void __fastpack62(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159586
|
+
void __fastpack63(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159587
|
+
void __fastpack64(const uint64_t *__restrict in, uint32_t *__restrict out);
|
|
159588
|
+
} // namespace internal
|
|
159589
|
+
} // namespace duckdb_fastpforlib
|
|
159590
|
+
|
|
159591
|
+
|
|
159592
|
+
// LICENSE_CHANGE_END
|
|
159593
|
+
|
|
159594
|
+
|
|
159595
|
+
#include <stdexcept>
|
|
159596
|
+
|
|
159597
|
+
namespace duckdb_fastpforlib {
|
|
159598
|
+
|
|
159599
|
+
namespace internal {
|
|
159600
|
+
|
|
159601
|
+
// Note that this only packs 8 values
|
|
159602
|
+
inline void fastunpack_quarter(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) {
|
|
159603
|
+
// Could have used function pointers instead of switch.
|
|
159604
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159605
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159606
|
+
switch (bit) {
|
|
159607
|
+
case 0:
|
|
159608
|
+
internal::__fastunpack0(in, out);
|
|
159609
|
+
break;
|
|
159610
|
+
case 1:
|
|
159611
|
+
internal::__fastunpack1(in, out);
|
|
159612
|
+
break;
|
|
159613
|
+
case 2:
|
|
159614
|
+
internal::__fastunpack2(in, out);
|
|
159615
|
+
break;
|
|
159616
|
+
case 3:
|
|
159617
|
+
internal::__fastunpack3(in, out);
|
|
159618
|
+
break;
|
|
159619
|
+
case 4:
|
|
159620
|
+
internal::__fastunpack4(in, out);
|
|
159621
|
+
break;
|
|
159622
|
+
case 5:
|
|
159623
|
+
internal::__fastunpack5(in, out);
|
|
159624
|
+
break;
|
|
159625
|
+
case 6:
|
|
159626
|
+
internal::__fastunpack6(in, out);
|
|
159627
|
+
break;
|
|
159628
|
+
case 7:
|
|
159629
|
+
internal::__fastunpack7(in, out);
|
|
159630
|
+
break;
|
|
159631
|
+
case 8:
|
|
159632
|
+
internal::__fastunpack8(in, out);
|
|
159633
|
+
break;
|
|
159634
|
+
default:
|
|
159635
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
159306
159636
|
}
|
|
159307
|
-
}
|
|
159637
|
+
}
|
|
159308
159638
|
|
|
159309
|
-
|
|
159310
|
-
|
|
159311
|
-
|
|
159639
|
+
// Note that this only packs 8 values
|
|
159640
|
+
inline void fastpack_quarter(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) {
|
|
159641
|
+
// Could have used function pointers instead of switch.
|
|
159642
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159643
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159644
|
+
switch (bit) {
|
|
159645
|
+
case 0:
|
|
159646
|
+
internal::__fastpack0(in, out);
|
|
159647
|
+
break;
|
|
159648
|
+
case 1:
|
|
159649
|
+
internal::__fastpack1(in, out);
|
|
159650
|
+
break;
|
|
159651
|
+
case 2:
|
|
159652
|
+
internal::__fastpack2(in, out);
|
|
159653
|
+
break;
|
|
159654
|
+
case 3:
|
|
159655
|
+
internal::__fastpack3(in, out);
|
|
159656
|
+
break;
|
|
159657
|
+
case 4:
|
|
159658
|
+
internal::__fastpack4(in, out);
|
|
159659
|
+
break;
|
|
159660
|
+
case 5:
|
|
159661
|
+
internal::__fastpack5(in, out);
|
|
159662
|
+
break;
|
|
159663
|
+
case 6:
|
|
159664
|
+
internal::__fastpack6(in, out);
|
|
159665
|
+
break;
|
|
159666
|
+
case 7:
|
|
159667
|
+
internal::__fastpack7(in, out);
|
|
159668
|
+
break;
|
|
159669
|
+
case 8:
|
|
159670
|
+
internal::__fastpack8(in, out);
|
|
159671
|
+
break;
|
|
159672
|
+
default:
|
|
159673
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
159674
|
+
}
|
|
159675
|
+
}
|
|
159312
159676
|
|
|
159313
|
-
|
|
159314
|
-
|
|
159315
|
-
|
|
159677
|
+
// Note that this only packs 16 values
|
|
159678
|
+
inline void fastunpack_half(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) {
|
|
159679
|
+
// Could have used function pointers instead of switch.
|
|
159680
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159681
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159682
|
+
switch (bit) {
|
|
159683
|
+
case 0:
|
|
159684
|
+
internal::__fastunpack0(in, out);
|
|
159685
|
+
break;
|
|
159686
|
+
case 1:
|
|
159687
|
+
internal::__fastunpack1(in, out);
|
|
159688
|
+
break;
|
|
159689
|
+
case 2:
|
|
159690
|
+
internal::__fastunpack2(in, out);
|
|
159691
|
+
break;
|
|
159692
|
+
case 3:
|
|
159693
|
+
internal::__fastunpack3(in, out);
|
|
159694
|
+
break;
|
|
159695
|
+
case 4:
|
|
159696
|
+
internal::__fastunpack4(in, out);
|
|
159697
|
+
break;
|
|
159698
|
+
case 5:
|
|
159699
|
+
internal::__fastunpack5(in, out);
|
|
159700
|
+
break;
|
|
159701
|
+
case 6:
|
|
159702
|
+
internal::__fastunpack6(in, out);
|
|
159703
|
+
break;
|
|
159704
|
+
case 7:
|
|
159705
|
+
internal::__fastunpack7(in, out);
|
|
159706
|
+
break;
|
|
159707
|
+
case 8:
|
|
159708
|
+
internal::__fastunpack8(in, out);
|
|
159709
|
+
break;
|
|
159710
|
+
case 9:
|
|
159711
|
+
internal::__fastunpack9(in, out);
|
|
159712
|
+
break;
|
|
159713
|
+
case 10:
|
|
159714
|
+
internal::__fastunpack10(in, out);
|
|
159715
|
+
break;
|
|
159716
|
+
case 11:
|
|
159717
|
+
internal::__fastunpack11(in, out);
|
|
159718
|
+
break;
|
|
159719
|
+
case 12:
|
|
159720
|
+
internal::__fastunpack12(in, out);
|
|
159721
|
+
break;
|
|
159722
|
+
case 13:
|
|
159723
|
+
internal::__fastunpack13(in, out);
|
|
159724
|
+
break;
|
|
159725
|
+
case 14:
|
|
159726
|
+
internal::__fastunpack14(in, out);
|
|
159727
|
+
break;
|
|
159728
|
+
case 15:
|
|
159729
|
+
internal::__fastunpack15(in, out);
|
|
159730
|
+
break;
|
|
159731
|
+
case 16:
|
|
159732
|
+
internal::__fastunpack16(in, out);
|
|
159733
|
+
break;
|
|
159734
|
+
default:
|
|
159735
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
159736
|
+
}
|
|
159737
|
+
}
|
|
159316
159738
|
|
|
159317
|
-
|
|
159318
|
-
|
|
159319
|
-
|
|
159320
|
-
|
|
159739
|
+
// Note that this only packs 16 values
|
|
159740
|
+
inline void fastpack_half(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) {
|
|
159741
|
+
// Could have used function pointers instead of switch.
|
|
159742
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159743
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159744
|
+
switch (bit) {
|
|
159745
|
+
case 0:
|
|
159746
|
+
internal::__fastpack0(in, out);
|
|
159747
|
+
break;
|
|
159748
|
+
case 1:
|
|
159749
|
+
internal::__fastpack1(in, out);
|
|
159750
|
+
break;
|
|
159751
|
+
case 2:
|
|
159752
|
+
internal::__fastpack2(in, out);
|
|
159753
|
+
break;
|
|
159754
|
+
case 3:
|
|
159755
|
+
internal::__fastpack3(in, out);
|
|
159756
|
+
break;
|
|
159757
|
+
case 4:
|
|
159758
|
+
internal::__fastpack4(in, out);
|
|
159759
|
+
break;
|
|
159760
|
+
case 5:
|
|
159761
|
+
internal::__fastpack5(in, out);
|
|
159762
|
+
break;
|
|
159763
|
+
case 6:
|
|
159764
|
+
internal::__fastpack6(in, out);
|
|
159765
|
+
break;
|
|
159766
|
+
case 7:
|
|
159767
|
+
internal::__fastpack7(in, out);
|
|
159768
|
+
break;
|
|
159769
|
+
case 8:
|
|
159770
|
+
internal::__fastpack8(in, out);
|
|
159771
|
+
break;
|
|
159772
|
+
case 9:
|
|
159773
|
+
internal::__fastpack9(in, out);
|
|
159774
|
+
break;
|
|
159775
|
+
case 10:
|
|
159776
|
+
internal::__fastpack10(in, out);
|
|
159777
|
+
break;
|
|
159778
|
+
case 11:
|
|
159779
|
+
internal::__fastpack11(in, out);
|
|
159780
|
+
break;
|
|
159781
|
+
case 12:
|
|
159782
|
+
internal::__fastpack12(in, out);
|
|
159783
|
+
break;
|
|
159784
|
+
case 13:
|
|
159785
|
+
internal::__fastpack13(in, out);
|
|
159786
|
+
break;
|
|
159787
|
+
case 14:
|
|
159788
|
+
internal::__fastpack14(in, out);
|
|
159789
|
+
break;
|
|
159790
|
+
case 15:
|
|
159791
|
+
internal::__fastpack15(in, out);
|
|
159792
|
+
break;
|
|
159793
|
+
case 16:
|
|
159794
|
+
internal::__fastpack16(in, out);
|
|
159795
|
+
break;
|
|
159796
|
+
default:
|
|
159797
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
159798
|
+
}
|
|
159799
|
+
}
|
|
159800
|
+
}
|
|
159321
159801
|
|
|
159322
|
-
|
|
159323
|
-
|
|
159324
|
-
|
|
159802
|
+
inline void fastunpack(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) {
|
|
159803
|
+
for (uint8_t i = 0; i < 4; i++) {
|
|
159804
|
+
internal::fastunpack_quarter(in + (i*bit), out+(i*8), bit);
|
|
159805
|
+
}
|
|
159806
|
+
}
|
|
159325
159807
|
|
|
159326
|
-
|
|
159327
|
-
|
|
159328
|
-
|
|
159329
|
-
|
|
159330
|
-
};
|
|
159808
|
+
inline void fastunpack(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) {
|
|
159809
|
+
internal::fastunpack_half(in, out, bit);
|
|
159810
|
+
internal::fastunpack_half(in + bit, out+16, bit);
|
|
159811
|
+
}
|
|
159331
159812
|
|
|
159332
|
-
|
|
159813
|
+
inline void fastunpack(const uint32_t *__restrict in,
|
|
159814
|
+
uint32_t *__restrict out, const uint32_t bit) {
|
|
159815
|
+
// Could have used function pointers instead of switch.
|
|
159816
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159817
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159818
|
+
switch (bit) {
|
|
159819
|
+
case 0:
|
|
159820
|
+
internal::__fastunpack0(in, out);
|
|
159821
|
+
break;
|
|
159822
|
+
case 1:
|
|
159823
|
+
internal::__fastunpack1(in, out);
|
|
159824
|
+
break;
|
|
159825
|
+
case 2:
|
|
159826
|
+
internal::__fastunpack2(in, out);
|
|
159827
|
+
break;
|
|
159828
|
+
case 3:
|
|
159829
|
+
internal::__fastunpack3(in, out);
|
|
159830
|
+
break;
|
|
159831
|
+
case 4:
|
|
159832
|
+
internal::__fastunpack4(in, out);
|
|
159833
|
+
break;
|
|
159834
|
+
case 5:
|
|
159835
|
+
internal::__fastunpack5(in, out);
|
|
159836
|
+
break;
|
|
159837
|
+
case 6:
|
|
159838
|
+
internal::__fastunpack6(in, out);
|
|
159839
|
+
break;
|
|
159840
|
+
case 7:
|
|
159841
|
+
internal::__fastunpack7(in, out);
|
|
159842
|
+
break;
|
|
159843
|
+
case 8:
|
|
159844
|
+
internal::__fastunpack8(in, out);
|
|
159845
|
+
break;
|
|
159846
|
+
case 9:
|
|
159847
|
+
internal::__fastunpack9(in, out);
|
|
159848
|
+
break;
|
|
159849
|
+
case 10:
|
|
159850
|
+
internal::__fastunpack10(in, out);
|
|
159851
|
+
break;
|
|
159852
|
+
case 11:
|
|
159853
|
+
internal::__fastunpack11(in, out);
|
|
159854
|
+
break;
|
|
159855
|
+
case 12:
|
|
159856
|
+
internal::__fastunpack12(in, out);
|
|
159857
|
+
break;
|
|
159858
|
+
case 13:
|
|
159859
|
+
internal::__fastunpack13(in, out);
|
|
159860
|
+
break;
|
|
159861
|
+
case 14:
|
|
159862
|
+
internal::__fastunpack14(in, out);
|
|
159863
|
+
break;
|
|
159864
|
+
case 15:
|
|
159865
|
+
internal::__fastunpack15(in, out);
|
|
159866
|
+
break;
|
|
159867
|
+
case 16:
|
|
159868
|
+
internal::__fastunpack16(in, out);
|
|
159869
|
+
break;
|
|
159870
|
+
case 17:
|
|
159871
|
+
internal::__fastunpack17(in, out);
|
|
159872
|
+
break;
|
|
159873
|
+
case 18:
|
|
159874
|
+
internal::__fastunpack18(in, out);
|
|
159875
|
+
break;
|
|
159876
|
+
case 19:
|
|
159877
|
+
internal::__fastunpack19(in, out);
|
|
159878
|
+
break;
|
|
159879
|
+
case 20:
|
|
159880
|
+
internal::__fastunpack20(in, out);
|
|
159881
|
+
break;
|
|
159882
|
+
case 21:
|
|
159883
|
+
internal::__fastunpack21(in, out);
|
|
159884
|
+
break;
|
|
159885
|
+
case 22:
|
|
159886
|
+
internal::__fastunpack22(in, out);
|
|
159887
|
+
break;
|
|
159888
|
+
case 23:
|
|
159889
|
+
internal::__fastunpack23(in, out);
|
|
159890
|
+
break;
|
|
159891
|
+
case 24:
|
|
159892
|
+
internal::__fastunpack24(in, out);
|
|
159893
|
+
break;
|
|
159894
|
+
case 25:
|
|
159895
|
+
internal::__fastunpack25(in, out);
|
|
159896
|
+
break;
|
|
159897
|
+
case 26:
|
|
159898
|
+
internal::__fastunpack26(in, out);
|
|
159899
|
+
break;
|
|
159900
|
+
case 27:
|
|
159901
|
+
internal::__fastunpack27(in, out);
|
|
159902
|
+
break;
|
|
159903
|
+
case 28:
|
|
159904
|
+
internal::__fastunpack28(in, out);
|
|
159905
|
+
break;
|
|
159906
|
+
case 29:
|
|
159907
|
+
internal::__fastunpack29(in, out);
|
|
159908
|
+
break;
|
|
159909
|
+
case 30:
|
|
159910
|
+
internal::__fastunpack30(in, out);
|
|
159911
|
+
break;
|
|
159912
|
+
case 31:
|
|
159913
|
+
internal::__fastunpack31(in, out);
|
|
159914
|
+
break;
|
|
159915
|
+
case 32:
|
|
159916
|
+
internal::__fastunpack32(in, out);
|
|
159917
|
+
break;
|
|
159918
|
+
default:
|
|
159919
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
159920
|
+
}
|
|
159921
|
+
}
|
|
159333
159922
|
|
|
159923
|
+
inline void fastunpack(const uint32_t *__restrict in,
|
|
159924
|
+
uint64_t *__restrict out, const uint32_t bit) {
|
|
159925
|
+
// Could have used function pointers instead of switch.
|
|
159926
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
159927
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
159928
|
+
switch (bit) {
|
|
159929
|
+
case 0:
|
|
159930
|
+
internal::__fastunpack0(in, out);
|
|
159931
|
+
break;
|
|
159932
|
+
case 1:
|
|
159933
|
+
internal::__fastunpack1(in, out);
|
|
159934
|
+
break;
|
|
159935
|
+
case 2:
|
|
159936
|
+
internal::__fastunpack2(in, out);
|
|
159937
|
+
break;
|
|
159938
|
+
case 3:
|
|
159939
|
+
internal::__fastunpack3(in, out);
|
|
159940
|
+
break;
|
|
159941
|
+
case 4:
|
|
159942
|
+
internal::__fastunpack4(in, out);
|
|
159943
|
+
break;
|
|
159944
|
+
case 5:
|
|
159945
|
+
internal::__fastunpack5(in, out);
|
|
159946
|
+
break;
|
|
159947
|
+
case 6:
|
|
159948
|
+
internal::__fastunpack6(in, out);
|
|
159949
|
+
break;
|
|
159950
|
+
case 7:
|
|
159951
|
+
internal::__fastunpack7(in, out);
|
|
159952
|
+
break;
|
|
159953
|
+
case 8:
|
|
159954
|
+
internal::__fastunpack8(in, out);
|
|
159955
|
+
break;
|
|
159956
|
+
case 9:
|
|
159957
|
+
internal::__fastunpack9(in, out);
|
|
159958
|
+
break;
|
|
159959
|
+
case 10:
|
|
159960
|
+
internal::__fastunpack10(in, out);
|
|
159961
|
+
break;
|
|
159962
|
+
case 11:
|
|
159963
|
+
internal::__fastunpack11(in, out);
|
|
159964
|
+
break;
|
|
159965
|
+
case 12:
|
|
159966
|
+
internal::__fastunpack12(in, out);
|
|
159967
|
+
break;
|
|
159968
|
+
case 13:
|
|
159969
|
+
internal::__fastunpack13(in, out);
|
|
159970
|
+
break;
|
|
159971
|
+
case 14:
|
|
159972
|
+
internal::__fastunpack14(in, out);
|
|
159973
|
+
break;
|
|
159974
|
+
case 15:
|
|
159975
|
+
internal::__fastunpack15(in, out);
|
|
159976
|
+
break;
|
|
159977
|
+
case 16:
|
|
159978
|
+
internal::__fastunpack16(in, out);
|
|
159979
|
+
break;
|
|
159980
|
+
case 17:
|
|
159981
|
+
internal::__fastunpack17(in, out);
|
|
159982
|
+
break;
|
|
159983
|
+
case 18:
|
|
159984
|
+
internal::__fastunpack18(in, out);
|
|
159985
|
+
break;
|
|
159986
|
+
case 19:
|
|
159987
|
+
internal::__fastunpack19(in, out);
|
|
159988
|
+
break;
|
|
159989
|
+
case 20:
|
|
159990
|
+
internal::__fastunpack20(in, out);
|
|
159991
|
+
break;
|
|
159992
|
+
case 21:
|
|
159993
|
+
internal::__fastunpack21(in, out);
|
|
159994
|
+
break;
|
|
159995
|
+
case 22:
|
|
159996
|
+
internal::__fastunpack22(in, out);
|
|
159997
|
+
break;
|
|
159998
|
+
case 23:
|
|
159999
|
+
internal::__fastunpack23(in, out);
|
|
160000
|
+
break;
|
|
160001
|
+
case 24:
|
|
160002
|
+
internal::__fastunpack24(in, out);
|
|
160003
|
+
break;
|
|
160004
|
+
case 25:
|
|
160005
|
+
internal::__fastunpack25(in, out);
|
|
160006
|
+
break;
|
|
160007
|
+
case 26:
|
|
160008
|
+
internal::__fastunpack26(in, out);
|
|
160009
|
+
break;
|
|
160010
|
+
case 27:
|
|
160011
|
+
internal::__fastunpack27(in, out);
|
|
160012
|
+
break;
|
|
160013
|
+
case 28:
|
|
160014
|
+
internal::__fastunpack28(in, out);
|
|
160015
|
+
break;
|
|
160016
|
+
case 29:
|
|
160017
|
+
internal::__fastunpack29(in, out);
|
|
160018
|
+
break;
|
|
160019
|
+
case 30:
|
|
160020
|
+
internal::__fastunpack30(in, out);
|
|
160021
|
+
break;
|
|
160022
|
+
case 31:
|
|
160023
|
+
internal::__fastunpack31(in, out);
|
|
160024
|
+
break;
|
|
160025
|
+
case 32:
|
|
160026
|
+
internal::__fastunpack32(in, out);
|
|
160027
|
+
break;
|
|
160028
|
+
case 33:
|
|
160029
|
+
internal::__fastunpack33(in, out);
|
|
160030
|
+
break;
|
|
160031
|
+
case 34:
|
|
160032
|
+
internal::__fastunpack34(in, out);
|
|
160033
|
+
break;
|
|
160034
|
+
case 35:
|
|
160035
|
+
internal::__fastunpack35(in, out);
|
|
160036
|
+
break;
|
|
160037
|
+
case 36:
|
|
160038
|
+
internal::__fastunpack36(in, out);
|
|
160039
|
+
break;
|
|
160040
|
+
case 37:
|
|
160041
|
+
internal::__fastunpack37(in, out);
|
|
160042
|
+
break;
|
|
160043
|
+
case 38:
|
|
160044
|
+
internal::__fastunpack38(in, out);
|
|
160045
|
+
break;
|
|
160046
|
+
case 39:
|
|
160047
|
+
internal::__fastunpack39(in, out);
|
|
160048
|
+
break;
|
|
160049
|
+
case 40:
|
|
160050
|
+
internal::__fastunpack40(in, out);
|
|
160051
|
+
break;
|
|
160052
|
+
case 41:
|
|
160053
|
+
internal::__fastunpack41(in, out);
|
|
160054
|
+
break;
|
|
160055
|
+
case 42:
|
|
160056
|
+
internal::__fastunpack42(in, out);
|
|
160057
|
+
break;
|
|
160058
|
+
case 43:
|
|
160059
|
+
internal::__fastunpack43(in, out);
|
|
160060
|
+
break;
|
|
160061
|
+
case 44:
|
|
160062
|
+
internal::__fastunpack44(in, out);
|
|
160063
|
+
break;
|
|
160064
|
+
case 45:
|
|
160065
|
+
internal::__fastunpack45(in, out);
|
|
160066
|
+
break;
|
|
160067
|
+
case 46:
|
|
160068
|
+
internal::__fastunpack46(in, out);
|
|
160069
|
+
break;
|
|
160070
|
+
case 47:
|
|
160071
|
+
internal::__fastunpack47(in, out);
|
|
160072
|
+
break;
|
|
160073
|
+
case 48:
|
|
160074
|
+
internal::__fastunpack48(in, out);
|
|
160075
|
+
break;
|
|
160076
|
+
case 49:
|
|
160077
|
+
internal::__fastunpack49(in, out);
|
|
160078
|
+
break;
|
|
160079
|
+
case 50:
|
|
160080
|
+
internal::__fastunpack50(in, out);
|
|
160081
|
+
break;
|
|
160082
|
+
case 51:
|
|
160083
|
+
internal::__fastunpack51(in, out);
|
|
160084
|
+
break;
|
|
160085
|
+
case 52:
|
|
160086
|
+
internal::__fastunpack52(in, out);
|
|
160087
|
+
break;
|
|
160088
|
+
case 53:
|
|
160089
|
+
internal::__fastunpack53(in, out);
|
|
160090
|
+
break;
|
|
160091
|
+
case 54:
|
|
160092
|
+
internal::__fastunpack54(in, out);
|
|
160093
|
+
break;
|
|
160094
|
+
case 55:
|
|
160095
|
+
internal::__fastunpack55(in, out);
|
|
160096
|
+
break;
|
|
160097
|
+
case 56:
|
|
160098
|
+
internal::__fastunpack56(in, out);
|
|
160099
|
+
break;
|
|
160100
|
+
case 57:
|
|
160101
|
+
internal::__fastunpack57(in, out);
|
|
160102
|
+
break;
|
|
160103
|
+
case 58:
|
|
160104
|
+
internal::__fastunpack58(in, out);
|
|
160105
|
+
break;
|
|
160106
|
+
case 59:
|
|
160107
|
+
internal::__fastunpack59(in, out);
|
|
160108
|
+
break;
|
|
160109
|
+
case 60:
|
|
160110
|
+
internal::__fastunpack60(in, out);
|
|
160111
|
+
break;
|
|
160112
|
+
case 61:
|
|
160113
|
+
internal::__fastunpack61(in, out);
|
|
160114
|
+
break;
|
|
160115
|
+
case 62:
|
|
160116
|
+
internal::__fastunpack62(in, out);
|
|
160117
|
+
break;
|
|
160118
|
+
case 63:
|
|
160119
|
+
internal::__fastunpack63(in, out);
|
|
160120
|
+
break;
|
|
160121
|
+
case 64:
|
|
160122
|
+
internal::__fastunpack64(in, out);
|
|
160123
|
+
break;
|
|
160124
|
+
default:
|
|
160125
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
160126
|
+
}
|
|
160127
|
+
}
|
|
160128
|
+
|
|
160129
|
+
inline void fastpack(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) {
|
|
160130
|
+
|
|
160131
|
+
for (uint8_t i = 0; i < 4; i++) {
|
|
160132
|
+
internal::fastpack_quarter(in+(i*8), out + (i*bit), bit);
|
|
160133
|
+
}
|
|
160134
|
+
}
|
|
160135
|
+
|
|
160136
|
+
inline void fastpack(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) {
|
|
160137
|
+
internal::fastpack_half(in, out, bit);
|
|
160138
|
+
internal::fastpack_half(in+16, out + bit, bit);
|
|
160139
|
+
}
|
|
160140
|
+
|
|
160141
|
+
inline void fastpack(const uint32_t *__restrict in,
|
|
160142
|
+
uint32_t *__restrict out, const uint32_t bit) {
|
|
160143
|
+
// Could have used function pointers instead of switch.
|
|
160144
|
+
// Switch calls do offer the compiler more opportunities for optimization in
|
|
160145
|
+
// theory. In this case, it makes no difference with a good compiler.
|
|
160146
|
+
switch (bit) {
|
|
160147
|
+
case 0:
|
|
160148
|
+
internal::__fastpack0(in, out);
|
|
160149
|
+
break;
|
|
160150
|
+
case 1:
|
|
160151
|
+
internal::__fastpack1(in, out);
|
|
160152
|
+
break;
|
|
160153
|
+
case 2:
|
|
160154
|
+
internal::__fastpack2(in, out);
|
|
160155
|
+
break;
|
|
160156
|
+
case 3:
|
|
160157
|
+
internal::__fastpack3(in, out);
|
|
160158
|
+
break;
|
|
160159
|
+
case 4:
|
|
160160
|
+
internal::__fastpack4(in, out);
|
|
160161
|
+
break;
|
|
160162
|
+
case 5:
|
|
160163
|
+
internal::__fastpack5(in, out);
|
|
160164
|
+
break;
|
|
160165
|
+
case 6:
|
|
160166
|
+
internal::__fastpack6(in, out);
|
|
160167
|
+
break;
|
|
160168
|
+
case 7:
|
|
160169
|
+
internal::__fastpack7(in, out);
|
|
160170
|
+
break;
|
|
160171
|
+
case 8:
|
|
160172
|
+
internal::__fastpack8(in, out);
|
|
160173
|
+
break;
|
|
160174
|
+
case 9:
|
|
160175
|
+
internal::__fastpack9(in, out);
|
|
160176
|
+
break;
|
|
160177
|
+
case 10:
|
|
160178
|
+
internal::__fastpack10(in, out);
|
|
160179
|
+
break;
|
|
160180
|
+
case 11:
|
|
160181
|
+
internal::__fastpack11(in, out);
|
|
160182
|
+
break;
|
|
160183
|
+
case 12:
|
|
160184
|
+
internal::__fastpack12(in, out);
|
|
160185
|
+
break;
|
|
160186
|
+
case 13:
|
|
160187
|
+
internal::__fastpack13(in, out);
|
|
160188
|
+
break;
|
|
160189
|
+
case 14:
|
|
160190
|
+
internal::__fastpack14(in, out);
|
|
160191
|
+
break;
|
|
160192
|
+
case 15:
|
|
160193
|
+
internal::__fastpack15(in, out);
|
|
160194
|
+
break;
|
|
160195
|
+
case 16:
|
|
160196
|
+
internal::__fastpack16(in, out);
|
|
160197
|
+
break;
|
|
160198
|
+
case 17:
|
|
160199
|
+
internal::__fastpack17(in, out);
|
|
160200
|
+
break;
|
|
160201
|
+
case 18:
|
|
160202
|
+
internal::__fastpack18(in, out);
|
|
160203
|
+
break;
|
|
160204
|
+
case 19:
|
|
160205
|
+
internal::__fastpack19(in, out);
|
|
160206
|
+
break;
|
|
160207
|
+
case 20:
|
|
160208
|
+
internal::__fastpack20(in, out);
|
|
160209
|
+
break;
|
|
160210
|
+
case 21:
|
|
160211
|
+
internal::__fastpack21(in, out);
|
|
160212
|
+
break;
|
|
160213
|
+
case 22:
|
|
160214
|
+
internal::__fastpack22(in, out);
|
|
160215
|
+
break;
|
|
160216
|
+
case 23:
|
|
160217
|
+
internal::__fastpack23(in, out);
|
|
160218
|
+
break;
|
|
160219
|
+
case 24:
|
|
160220
|
+
internal::__fastpack24(in, out);
|
|
160221
|
+
break;
|
|
160222
|
+
case 25:
|
|
160223
|
+
internal::__fastpack25(in, out);
|
|
160224
|
+
break;
|
|
160225
|
+
case 26:
|
|
160226
|
+
internal::__fastpack26(in, out);
|
|
160227
|
+
break;
|
|
160228
|
+
case 27:
|
|
160229
|
+
internal::__fastpack27(in, out);
|
|
160230
|
+
break;
|
|
160231
|
+
case 28:
|
|
160232
|
+
internal::__fastpack28(in, out);
|
|
160233
|
+
break;
|
|
160234
|
+
case 29:
|
|
160235
|
+
internal::__fastpack29(in, out);
|
|
160236
|
+
break;
|
|
160237
|
+
case 30:
|
|
160238
|
+
internal::__fastpack30(in, out);
|
|
160239
|
+
break;
|
|
160240
|
+
case 31:
|
|
160241
|
+
internal::__fastpack31(in, out);
|
|
160242
|
+
break;
|
|
160243
|
+
case 32:
|
|
160244
|
+
internal::__fastpack32(in, out);
|
|
160245
|
+
break;
|
|
160246
|
+
default:
|
|
160247
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
160248
|
+
}
|
|
160249
|
+
}
|
|
159334
160250
|
|
|
160251
|
+
inline void fastpack(const uint64_t *__restrict in,
|
|
160252
|
+
uint32_t *__restrict out, const uint32_t bit) {
|
|
160253
|
+
switch (bit) {
|
|
160254
|
+
case 0:
|
|
160255
|
+
internal::__fastpack0(in, out);
|
|
160256
|
+
break;
|
|
160257
|
+
case 1:
|
|
160258
|
+
internal::__fastpack1(in, out);
|
|
160259
|
+
break;
|
|
160260
|
+
case 2:
|
|
160261
|
+
internal::__fastpack2(in, out);
|
|
160262
|
+
break;
|
|
160263
|
+
case 3:
|
|
160264
|
+
internal::__fastpack3(in, out);
|
|
160265
|
+
break;
|
|
160266
|
+
case 4:
|
|
160267
|
+
internal::__fastpack4(in, out);
|
|
160268
|
+
break;
|
|
160269
|
+
case 5:
|
|
160270
|
+
internal::__fastpack5(in, out);
|
|
160271
|
+
break;
|
|
160272
|
+
case 6:
|
|
160273
|
+
internal::__fastpack6(in, out);
|
|
160274
|
+
break;
|
|
160275
|
+
case 7:
|
|
160276
|
+
internal::__fastpack7(in, out);
|
|
160277
|
+
break;
|
|
160278
|
+
case 8:
|
|
160279
|
+
internal::__fastpack8(in, out);
|
|
160280
|
+
break;
|
|
160281
|
+
case 9:
|
|
160282
|
+
internal::__fastpack9(in, out);
|
|
160283
|
+
break;
|
|
160284
|
+
case 10:
|
|
160285
|
+
internal::__fastpack10(in, out);
|
|
160286
|
+
break;
|
|
160287
|
+
case 11:
|
|
160288
|
+
internal::__fastpack11(in, out);
|
|
160289
|
+
break;
|
|
160290
|
+
case 12:
|
|
160291
|
+
internal::__fastpack12(in, out);
|
|
160292
|
+
break;
|
|
160293
|
+
case 13:
|
|
160294
|
+
internal::__fastpack13(in, out);
|
|
160295
|
+
break;
|
|
160296
|
+
case 14:
|
|
160297
|
+
internal::__fastpack14(in, out);
|
|
160298
|
+
break;
|
|
160299
|
+
case 15:
|
|
160300
|
+
internal::__fastpack15(in, out);
|
|
160301
|
+
break;
|
|
160302
|
+
case 16:
|
|
160303
|
+
internal::__fastpack16(in, out);
|
|
160304
|
+
break;
|
|
160305
|
+
case 17:
|
|
160306
|
+
internal::__fastpack17(in, out);
|
|
160307
|
+
break;
|
|
160308
|
+
case 18:
|
|
160309
|
+
internal::__fastpack18(in, out);
|
|
160310
|
+
break;
|
|
160311
|
+
case 19:
|
|
160312
|
+
internal::__fastpack19(in, out);
|
|
160313
|
+
break;
|
|
160314
|
+
case 20:
|
|
160315
|
+
internal::__fastpack20(in, out);
|
|
160316
|
+
break;
|
|
160317
|
+
case 21:
|
|
160318
|
+
internal::__fastpack21(in, out);
|
|
160319
|
+
break;
|
|
160320
|
+
case 22:
|
|
160321
|
+
internal::__fastpack22(in, out);
|
|
160322
|
+
break;
|
|
160323
|
+
case 23:
|
|
160324
|
+
internal::__fastpack23(in, out);
|
|
160325
|
+
break;
|
|
160326
|
+
case 24:
|
|
160327
|
+
internal::__fastpack24(in, out);
|
|
160328
|
+
break;
|
|
160329
|
+
case 25:
|
|
160330
|
+
internal::__fastpack25(in, out);
|
|
160331
|
+
break;
|
|
160332
|
+
case 26:
|
|
160333
|
+
internal::__fastpack26(in, out);
|
|
160334
|
+
break;
|
|
160335
|
+
case 27:
|
|
160336
|
+
internal::__fastpack27(in, out);
|
|
160337
|
+
break;
|
|
160338
|
+
case 28:
|
|
160339
|
+
internal::__fastpack28(in, out);
|
|
160340
|
+
break;
|
|
160341
|
+
case 29:
|
|
160342
|
+
internal::__fastpack29(in, out);
|
|
160343
|
+
break;
|
|
160344
|
+
case 30:
|
|
160345
|
+
internal::__fastpack30(in, out);
|
|
160346
|
+
break;
|
|
160347
|
+
case 31:
|
|
160348
|
+
internal::__fastpack31(in, out);
|
|
160349
|
+
break;
|
|
160350
|
+
case 32:
|
|
160351
|
+
internal::__fastpack32(in, out);
|
|
160352
|
+
break;
|
|
160353
|
+
case 33:
|
|
160354
|
+
internal::__fastpack33(in, out);
|
|
160355
|
+
break;
|
|
160356
|
+
case 34:
|
|
160357
|
+
internal::__fastpack34(in, out);
|
|
160358
|
+
break;
|
|
160359
|
+
case 35:
|
|
160360
|
+
internal::__fastpack35(in, out);
|
|
160361
|
+
break;
|
|
160362
|
+
case 36:
|
|
160363
|
+
internal::__fastpack36(in, out);
|
|
160364
|
+
break;
|
|
160365
|
+
case 37:
|
|
160366
|
+
internal::__fastpack37(in, out);
|
|
160367
|
+
break;
|
|
160368
|
+
case 38:
|
|
160369
|
+
internal::__fastpack38(in, out);
|
|
160370
|
+
break;
|
|
160371
|
+
case 39:
|
|
160372
|
+
internal::__fastpack39(in, out);
|
|
160373
|
+
break;
|
|
160374
|
+
case 40:
|
|
160375
|
+
internal::__fastpack40(in, out);
|
|
160376
|
+
break;
|
|
160377
|
+
case 41:
|
|
160378
|
+
internal::__fastpack41(in, out);
|
|
160379
|
+
break;
|
|
160380
|
+
case 42:
|
|
160381
|
+
internal::__fastpack42(in, out);
|
|
160382
|
+
break;
|
|
160383
|
+
case 43:
|
|
160384
|
+
internal::__fastpack43(in, out);
|
|
160385
|
+
break;
|
|
160386
|
+
case 44:
|
|
160387
|
+
internal::__fastpack44(in, out);
|
|
160388
|
+
break;
|
|
160389
|
+
case 45:
|
|
160390
|
+
internal::__fastpack45(in, out);
|
|
160391
|
+
break;
|
|
160392
|
+
case 46:
|
|
160393
|
+
internal::__fastpack46(in, out);
|
|
160394
|
+
break;
|
|
160395
|
+
case 47:
|
|
160396
|
+
internal::__fastpack47(in, out);
|
|
160397
|
+
break;
|
|
160398
|
+
case 48:
|
|
160399
|
+
internal::__fastpack48(in, out);
|
|
160400
|
+
break;
|
|
160401
|
+
case 49:
|
|
160402
|
+
internal::__fastpack49(in, out);
|
|
160403
|
+
break;
|
|
160404
|
+
case 50:
|
|
160405
|
+
internal::__fastpack50(in, out);
|
|
160406
|
+
break;
|
|
160407
|
+
case 51:
|
|
160408
|
+
internal::__fastpack51(in, out);
|
|
160409
|
+
break;
|
|
160410
|
+
case 52:
|
|
160411
|
+
internal::__fastpack52(in, out);
|
|
160412
|
+
break;
|
|
160413
|
+
case 53:
|
|
160414
|
+
internal::__fastpack53(in, out);
|
|
160415
|
+
break;
|
|
160416
|
+
case 54:
|
|
160417
|
+
internal::__fastpack54(in, out);
|
|
160418
|
+
break;
|
|
160419
|
+
case 55:
|
|
160420
|
+
internal::__fastpack55(in, out);
|
|
160421
|
+
break;
|
|
160422
|
+
case 56:
|
|
160423
|
+
internal::__fastpack56(in, out);
|
|
160424
|
+
break;
|
|
160425
|
+
case 57:
|
|
160426
|
+
internal::__fastpack57(in, out);
|
|
160427
|
+
break;
|
|
160428
|
+
case 58:
|
|
160429
|
+
internal::__fastpack58(in, out);
|
|
160430
|
+
break;
|
|
160431
|
+
case 59:
|
|
160432
|
+
internal::__fastpack59(in, out);
|
|
160433
|
+
break;
|
|
160434
|
+
case 60:
|
|
160435
|
+
internal::__fastpack60(in, out);
|
|
160436
|
+
break;
|
|
160437
|
+
case 61:
|
|
160438
|
+
internal::__fastpack61(in, out);
|
|
160439
|
+
break;
|
|
160440
|
+
case 62:
|
|
160441
|
+
internal::__fastpack62(in, out);
|
|
160442
|
+
break;
|
|
160443
|
+
case 63:
|
|
160444
|
+
internal::__fastpack63(in, out);
|
|
160445
|
+
break;
|
|
160446
|
+
case 64:
|
|
160447
|
+
internal::__fastpack64(in, out);
|
|
160448
|
+
break;
|
|
160449
|
+
default:
|
|
160450
|
+
throw std::logic_error("Invalid bit width for bitpacking");
|
|
160451
|
+
}
|
|
160452
|
+
}
|
|
160453
|
+
} // namespace fastpfor_lib
|
|
160454
|
+
|
|
160455
|
+
|
|
160456
|
+
// LICENSE_CHANGE_END
|
|
159335
160457
|
|
|
159336
160458
|
|
|
159337
160459
|
|
|
@@ -159578,6 +160700,691 @@ private:
|
|
|
159578
160700
|
} // namespace duckdb
|
|
159579
160701
|
|
|
159580
160702
|
|
|
160703
|
+
|
|
160704
|
+
#include <functional>
|
|
160705
|
+
|
|
160706
|
+
namespace duckdb {
|
|
160707
|
+
|
|
160708
|
+
using bitpacking_width_t = uint8_t;
|
|
160709
|
+
|
|
160710
|
+
// Note that optimizations in scanning only work if this value is equal to STANDARD_VECTOR_SIZE, however we keep them
|
|
160711
|
+
// separated to prevent the code from break on lower vector sizes
|
|
160712
|
+
static constexpr const idx_t BITPACKING_WIDTH_GROUP_SIZE = 1024;
|
|
160713
|
+
|
|
160714
|
+
class BitpackingPrimitives {
|
|
160715
|
+
public:
|
|
160716
|
+
static constexpr const idx_t BITPACKING_ALGORITHM_GROUP_SIZE = 32;
|
|
160717
|
+
static constexpr const idx_t BITPACKING_HEADER_SIZE = sizeof(uint64_t);
|
|
160718
|
+
static constexpr const bool BYTE_ALIGNED = false;
|
|
160719
|
+
|
|
160720
|
+
// Packs a block of BITPACKING_ALGORITHM_GROUP_SIZE values
|
|
160721
|
+
template <class T>
|
|
160722
|
+
inline static void PackBlock(data_ptr_t dst, T *src, bitpacking_width_t width) {
|
|
160723
|
+
return PackGroup<T>(dst, src, width);
|
|
160724
|
+
}
|
|
160725
|
+
|
|
160726
|
+
// Unpacks a block of BITPACKING_ALGORITHM_GROUP_SIZE values
|
|
160727
|
+
template <class T>
|
|
160728
|
+
inline static void UnPackBlock(data_ptr_t dst, data_ptr_t src, bitpacking_width_t width,
|
|
160729
|
+
bool skip_sign_extension = false) {
|
|
160730
|
+
return UnPackGroup<T>(dst, src, width, skip_sign_extension);
|
|
160731
|
+
}
|
|
160732
|
+
|
|
160733
|
+
// Calculates the minimum required number of bits per value that can store all values
|
|
160734
|
+
template <class T>
|
|
160735
|
+
inline static bitpacking_width_t MinimumBitWidth(T *values, idx_t count) {
|
|
160736
|
+
return FindMinimumBitWidth<T, BYTE_ALIGNED>(values, count);
|
|
160737
|
+
}
|
|
160738
|
+
|
|
160739
|
+
private:
|
|
160740
|
+
template <class T>
|
|
160741
|
+
static bitpacking_width_t MinimumBitWidth(T min_value, T max_value) {
|
|
160742
|
+
bitpacking_width_t required_bits;
|
|
160743
|
+
|
|
160744
|
+
if (std::is_signed<T>::value) {
|
|
160745
|
+
if (min_value == NumericLimits<T>::Minimum()) {
|
|
160746
|
+
// handle special case of the minimal value, as it cannot be negated like all other values.
|
|
160747
|
+
return sizeof(T) * 8;
|
|
160748
|
+
} else {
|
|
160749
|
+
max_value = MaxValue((T)-min_value, max_value);
|
|
160750
|
+
}
|
|
160751
|
+
}
|
|
160752
|
+
|
|
160753
|
+
if (max_value == 0) {
|
|
160754
|
+
return 0;
|
|
160755
|
+
}
|
|
160756
|
+
|
|
160757
|
+
if (std::is_signed<T>::value) {
|
|
160758
|
+
required_bits = 1;
|
|
160759
|
+
} else {
|
|
160760
|
+
required_bits = 0;
|
|
160761
|
+
}
|
|
160762
|
+
|
|
160763
|
+
while (max_value) {
|
|
160764
|
+
required_bits++;
|
|
160765
|
+
max_value >>= 1;
|
|
160766
|
+
}
|
|
160767
|
+
|
|
160768
|
+
return GetEffectiveWidth<T>(required_bits);
|
|
160769
|
+
}
|
|
160770
|
+
|
|
160771
|
+
template <class T, bool round_to_next_byte = false>
|
|
160772
|
+
static bitpacking_width_t FindMinimumBitWidth(T *values, idx_t count) {
|
|
160773
|
+
T min_value = values[0];
|
|
160774
|
+
T max_value = values[0];
|
|
160775
|
+
|
|
160776
|
+
for (idx_t i = 1; i < count; i++) {
|
|
160777
|
+
if (values[i] > max_value) {
|
|
160778
|
+
max_value = values[i];
|
|
160779
|
+
}
|
|
160780
|
+
|
|
160781
|
+
if (std::is_signed<T>::value) {
|
|
160782
|
+
if (values[i] < min_value) {
|
|
160783
|
+
min_value = values[i];
|
|
160784
|
+
}
|
|
160785
|
+
}
|
|
160786
|
+
}
|
|
160787
|
+
|
|
160788
|
+
bitpacking_width_t calc_width = MinimumBitWidth<T>(std::is_signed<T>::value ? min_value : 0, max_value);
|
|
160789
|
+
|
|
160790
|
+
// Assert results are correct
|
|
160791
|
+
#ifdef DEBUG
|
|
160792
|
+
if (calc_width < sizeof(T) * 8 && calc_width != 0) {
|
|
160793
|
+
if (std::is_signed<T>::value) {
|
|
160794
|
+
D_ASSERT((int64_t)max_value <= (int64_t)(1L << (calc_width - 1)) - 1);
|
|
160795
|
+
D_ASSERT((int64_t)min_value >= (int64_t)(-1 * ((1L << (calc_width - 1)) - 1) - 1));
|
|
160796
|
+
} else {
|
|
160797
|
+
D_ASSERT((uint64_t)max_value <= (uint64_t)(1L << (calc_width)) - 1);
|
|
160798
|
+
}
|
|
160799
|
+
}
|
|
160800
|
+
#endif
|
|
160801
|
+
if (round_to_next_byte) {
|
|
160802
|
+
return (calc_width / 8 + (calc_width % 8 != 0)) * 8;
|
|
160803
|
+
} else {
|
|
160804
|
+
return calc_width;
|
|
160805
|
+
}
|
|
160806
|
+
}
|
|
160807
|
+
|
|
160808
|
+
template <class T>
|
|
160809
|
+
static void UnPackGroup(data_ptr_t dst, data_ptr_t src, bitpacking_width_t width,
|
|
160810
|
+
bool skip_sign_extension = false) {
|
|
160811
|
+
if (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value) {
|
|
160812
|
+
duckdb_fastpforlib::fastunpack((const uint8_t *)src, (uint8_t *)dst, (uint32_t)width);
|
|
160813
|
+
} else if (std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value) {
|
|
160814
|
+
duckdb_fastpforlib::fastunpack((const uint16_t *)src, (uint16_t *)dst, (uint32_t)width);
|
|
160815
|
+
} else if (std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value) {
|
|
160816
|
+
duckdb_fastpforlib::fastunpack((const uint32_t *)src, (uint32_t *)dst, (uint32_t)width);
|
|
160817
|
+
} else if (std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value) {
|
|
160818
|
+
duckdb_fastpforlib::fastunpack((const uint32_t *)src, (uint64_t *)dst, (uint32_t)width);
|
|
160819
|
+
} else {
|
|
160820
|
+
throw InternalException("Unsupported type found in bitpacking.");
|
|
160821
|
+
}
|
|
160822
|
+
|
|
160823
|
+
if (NumericLimits<T>::IsSigned() && !skip_sign_extension && width > 0 && width < sizeof(T) * 8) {
|
|
160824
|
+
SignExtend<T>(dst, width);
|
|
160825
|
+
}
|
|
160826
|
+
}
|
|
160827
|
+
|
|
160828
|
+
// Prevent compression at widths that are ineffective
|
|
160829
|
+
template <class T>
|
|
160830
|
+
static bitpacking_width_t GetEffectiveWidth(bitpacking_width_t width) {
|
|
160831
|
+
if (width > 56) {
|
|
160832
|
+
return 64;
|
|
160833
|
+
}
|
|
160834
|
+
|
|
160835
|
+
if (width > 28 && (std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value)) {
|
|
160836
|
+
return 32;
|
|
160837
|
+
}
|
|
160838
|
+
|
|
160839
|
+
else if (width > 14 && (std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value)) {
|
|
160840
|
+
return 16;
|
|
160841
|
+
}
|
|
160842
|
+
|
|
160843
|
+
return width;
|
|
160844
|
+
}
|
|
160845
|
+
|
|
160846
|
+
// Sign bit extension
|
|
160847
|
+
template <class T, class T_U = typename std::make_unsigned<T>::type>
|
|
160848
|
+
static void SignExtend(data_ptr_t dst, bitpacking_width_t width) {
|
|
160849
|
+
T const mask = ((T_U)1) << (width - 1);
|
|
160850
|
+
for (idx_t i = 0; i < BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; ++i) {
|
|
160851
|
+
T value = Load<T>(dst + i * sizeof(T));
|
|
160852
|
+
value = value & ((((T_U)1) << width) - ((T_U)1));
|
|
160853
|
+
T result = (value ^ mask) - mask;
|
|
160854
|
+
Store(result, dst + i * sizeof(T));
|
|
160855
|
+
}
|
|
160856
|
+
}
|
|
160857
|
+
|
|
160858
|
+
template <class T>
|
|
160859
|
+
static void PackGroup(data_ptr_t dst, T *values, bitpacking_width_t width) {
|
|
160860
|
+
if (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value) {
|
|
160861
|
+
duckdb_fastpforlib::fastpack((const uint8_t *)values, (uint8_t *)dst, (uint32_t)width);
|
|
160862
|
+
} else if (std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value) {
|
|
160863
|
+
duckdb_fastpforlib::fastpack((const uint16_t *)values, (uint16_t *)dst, (uint32_t)width);
|
|
160864
|
+
} else if (std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value) {
|
|
160865
|
+
duckdb_fastpforlib::fastpack((const uint32_t *)values, (uint32_t *)dst, (uint32_t)width);
|
|
160866
|
+
} else if (std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value) {
|
|
160867
|
+
duckdb_fastpforlib::fastpack((const uint64_t *)values, (uint32_t *)dst, (uint32_t)width);
|
|
160868
|
+
} else {
|
|
160869
|
+
throw InternalException("Unsupported type found in bitpacking.");
|
|
160870
|
+
}
|
|
160871
|
+
}
|
|
160872
|
+
};
|
|
160873
|
+
|
|
160874
|
+
struct EmptyBitpackingWriter {
|
|
160875
|
+
template <class T>
|
|
160876
|
+
static void Operation(T *values, bool *validity, bitpacking_width_t width, idx_t count, void *data_ptr) {
|
|
160877
|
+
}
|
|
160878
|
+
};
|
|
160879
|
+
|
|
160880
|
+
template <class T>
|
|
160881
|
+
struct BitpackingState {
|
|
160882
|
+
public:
|
|
160883
|
+
BitpackingState() : compression_buffer_idx(0), total_size(0), data_ptr(nullptr) {
|
|
160884
|
+
}
|
|
160885
|
+
|
|
160886
|
+
T compression_buffer[BITPACKING_WIDTH_GROUP_SIZE];
|
|
160887
|
+
bool compression_buffer_validity[BITPACKING_WIDTH_GROUP_SIZE];
|
|
160888
|
+
idx_t compression_buffer_idx;
|
|
160889
|
+
idx_t total_size;
|
|
160890
|
+
void *data_ptr;
|
|
160891
|
+
|
|
160892
|
+
public:
|
|
160893
|
+
template <class OP>
|
|
160894
|
+
void Flush() {
|
|
160895
|
+
bitpacking_width_t width = BitpackingPrimitives::MinimumBitWidth<T>(compression_buffer, compression_buffer_idx);
|
|
160896
|
+
OP::Operation(compression_buffer, compression_buffer_validity, width, compression_buffer_idx, data_ptr);
|
|
160897
|
+
total_size += (BITPACKING_WIDTH_GROUP_SIZE * width) / 8 + sizeof(bitpacking_width_t);
|
|
160898
|
+
compression_buffer_idx = 0;
|
|
160899
|
+
}
|
|
160900
|
+
|
|
160901
|
+
template <class OP = EmptyBitpackingWriter>
|
|
160902
|
+
void Update(T *data, ValidityMask &validity, idx_t idx) {
|
|
160903
|
+
|
|
160904
|
+
if (validity.RowIsValid(idx)) {
|
|
160905
|
+
compression_buffer_validity[compression_buffer_idx] = true;
|
|
160906
|
+
compression_buffer[compression_buffer_idx++] = data[idx];
|
|
160907
|
+
} else {
|
|
160908
|
+
// We write zero for easy bitwidth analysis of the compression buffer later
|
|
160909
|
+
compression_buffer_validity[compression_buffer_idx] = false;
|
|
160910
|
+
compression_buffer[compression_buffer_idx++] = 0;
|
|
160911
|
+
}
|
|
160912
|
+
|
|
160913
|
+
if (compression_buffer_idx == BITPACKING_WIDTH_GROUP_SIZE) {
|
|
160914
|
+
// Calculate bitpacking width;
|
|
160915
|
+
Flush<OP>();
|
|
160916
|
+
}
|
|
160917
|
+
}
|
|
160918
|
+
};
|
|
160919
|
+
|
|
160920
|
+
//===--------------------------------------------------------------------===//
|
|
160921
|
+
// Analyze
|
|
160922
|
+
//===--------------------------------------------------------------------===//
|
|
160923
|
+
template <class T>
|
|
160924
|
+
struct BitpackingAnalyzeState : public AnalyzeState {
|
|
160925
|
+
BitpackingState<T> state;
|
|
160926
|
+
};
|
|
160927
|
+
|
|
160928
|
+
template <class T>
|
|
160929
|
+
unique_ptr<AnalyzeState> BitpackingInitAnalyze(ColumnData &col_data, PhysicalType type) {
|
|
160930
|
+
return make_unique<BitpackingAnalyzeState<T>>();
|
|
160931
|
+
}
|
|
160932
|
+
|
|
160933
|
+
template <class T>
|
|
160934
|
+
bool BitpackingAnalyze(AnalyzeState &state, Vector &input, idx_t count) {
|
|
160935
|
+
auto &analyze_state = (BitpackingAnalyzeState<T> &)state;
|
|
160936
|
+
VectorData vdata;
|
|
160937
|
+
input.Orrify(count, vdata);
|
|
160938
|
+
|
|
160939
|
+
auto data = (T *)vdata.data;
|
|
160940
|
+
for (idx_t i = 0; i < count; i++) {
|
|
160941
|
+
auto idx = vdata.sel->get_index(i);
|
|
160942
|
+
analyze_state.state.template Update<EmptyBitpackingWriter>(data, vdata.validity, idx);
|
|
160943
|
+
}
|
|
160944
|
+
|
|
160945
|
+
return true;
|
|
160946
|
+
}
|
|
160947
|
+
|
|
160948
|
+
template <class T>
|
|
160949
|
+
idx_t BitpackingFinalAnalyze(AnalyzeState &state) {
|
|
160950
|
+
auto &bitpacking_state = (BitpackingAnalyzeState<T> &)state;
|
|
160951
|
+
bitpacking_state.state.template Flush<EmptyBitpackingWriter>();
|
|
160952
|
+
return bitpacking_state.state.total_size;
|
|
160953
|
+
}
|
|
160954
|
+
|
|
160955
|
+
//===--------------------------------------------------------------------===//
|
|
160956
|
+
// Compress
|
|
160957
|
+
//===--------------------------------------------------------------------===//
|
|
160958
|
+
template <class T>
|
|
160959
|
+
struct BitpackingCompressState : public CompressionState {
|
|
160960
|
+
public:
|
|
160961
|
+
explicit BitpackingCompressState(ColumnDataCheckpointer &checkpointer) : checkpointer(checkpointer) {
|
|
160962
|
+
auto &db = checkpointer.GetDatabase();
|
|
160963
|
+
auto &type = checkpointer.GetType();
|
|
160964
|
+
auto &config = DBConfig::GetConfig(db);
|
|
160965
|
+
function = config.GetCompressionFunction(CompressionType::COMPRESSION_BITPACKING, type.InternalType());
|
|
160966
|
+
CreateEmptySegment(checkpointer.GetRowGroup().start);
|
|
160967
|
+
|
|
160968
|
+
state.data_ptr = (void *)this;
|
|
160969
|
+
}
|
|
160970
|
+
|
|
160971
|
+
ColumnDataCheckpointer &checkpointer;
|
|
160972
|
+
CompressionFunction *function;
|
|
160973
|
+
unique_ptr<ColumnSegment> current_segment;
|
|
160974
|
+
unique_ptr<BufferHandle> handle;
|
|
160975
|
+
|
|
160976
|
+
// Ptr to next free spot in segment;
|
|
160977
|
+
data_ptr_t data_ptr;
|
|
160978
|
+
// Ptr to next free spot for storing bitwidths (growing downwards).
|
|
160979
|
+
data_ptr_t width_ptr;
|
|
160980
|
+
|
|
160981
|
+
BitpackingState<T> state;
|
|
160982
|
+
|
|
160983
|
+
public:
|
|
160984
|
+
struct BitpackingWriter {
|
|
160985
|
+
template <class VALUE_TYPE>
|
|
160986
|
+
static void Operation(VALUE_TYPE *values, bool *validity, bitpacking_width_t width, idx_t count,
|
|
160987
|
+
void *data_ptr) {
|
|
160988
|
+
auto state = (BitpackingCompressState<T> *)data_ptr;
|
|
160989
|
+
|
|
160990
|
+
if (state->RemainingSize() < (width * BITPACKING_WIDTH_GROUP_SIZE) / 8 + sizeof(bitpacking_width_t)) {
|
|
160991
|
+
// Segment is full
|
|
160992
|
+
auto row_start = state->current_segment->start + state->current_segment->count;
|
|
160993
|
+
state->FlushSegment();
|
|
160994
|
+
state->CreateEmptySegment(row_start);
|
|
160995
|
+
}
|
|
160996
|
+
|
|
160997
|
+
for (idx_t i = 0; i < count; i++) {
|
|
160998
|
+
if (validity[i]) {
|
|
160999
|
+
NumericStatistics::Update<T>(state->current_segment->stats, values[i]);
|
|
161000
|
+
}
|
|
161001
|
+
}
|
|
161002
|
+
|
|
161003
|
+
state->WriteValues(values, width, count);
|
|
161004
|
+
}
|
|
161005
|
+
};
|
|
161006
|
+
|
|
161007
|
+
// Space remaining between the width_ptr growing down and data ptr growing up
|
|
161008
|
+
idx_t RemainingSize() {
|
|
161009
|
+
return width_ptr - data_ptr;
|
|
161010
|
+
}
|
|
161011
|
+
|
|
161012
|
+
void CreateEmptySegment(idx_t row_start) {
|
|
161013
|
+
auto &db = checkpointer.GetDatabase();
|
|
161014
|
+
auto &type = checkpointer.GetType();
|
|
161015
|
+
auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start);
|
|
161016
|
+
compressed_segment->function = function;
|
|
161017
|
+
current_segment = move(compressed_segment);
|
|
161018
|
+
auto &buffer_manager = BufferManager::GetBufferManager(db);
|
|
161019
|
+
handle = buffer_manager.Pin(current_segment->block);
|
|
161020
|
+
|
|
161021
|
+
data_ptr = handle->Ptr() + current_segment->GetBlockOffset() + BitpackingPrimitives::BITPACKING_HEADER_SIZE;
|
|
161022
|
+
width_ptr =
|
|
161023
|
+
handle->Ptr() + current_segment->GetBlockOffset() + Storage::BLOCK_SIZE - sizeof(bitpacking_width_t);
|
|
161024
|
+
}
|
|
161025
|
+
|
|
161026
|
+
void Append(VectorData &vdata, idx_t count) {
|
|
161027
|
+
// TODO Optimization: avoid use of compression buffer if we can compress straight to result vector
|
|
161028
|
+
auto data = (T *)vdata.data;
|
|
161029
|
+
|
|
161030
|
+
for (idx_t i = 0; i < count; i++) {
|
|
161031
|
+
auto idx = vdata.sel->get_index(i);
|
|
161032
|
+
state.template Update<BitpackingCompressState<T>::BitpackingWriter>(data, vdata.validity, idx);
|
|
161033
|
+
}
|
|
161034
|
+
}
|
|
161035
|
+
|
|
161036
|
+
void WriteValues(T *values, bitpacking_width_t width, idx_t count) {
|
|
161037
|
+
// TODO we can optimize this by stopping early if count < BITPACKING_WIDTH_GROUP_SIZE
|
|
161038
|
+
idx_t compress_loops = BITPACKING_WIDTH_GROUP_SIZE / BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE;
|
|
161039
|
+
for (idx_t i = 0; i < compress_loops; i++) {
|
|
161040
|
+
BitpackingPrimitives::PackBlock<T>(
|
|
161041
|
+
data_ptr, &values[i * BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE], width);
|
|
161042
|
+
data_ptr += (BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE * width) / 8;
|
|
161043
|
+
}
|
|
161044
|
+
|
|
161045
|
+
Store<bitpacking_width_t>(width, width_ptr);
|
|
161046
|
+
width_ptr -= sizeof(bitpacking_width_t);
|
|
161047
|
+
|
|
161048
|
+
current_segment->count += count;
|
|
161049
|
+
}
|
|
161050
|
+
|
|
161051
|
+
void FlushSegment() {
|
|
161052
|
+
auto &state = checkpointer.GetCheckpointState();
|
|
161053
|
+
|
|
161054
|
+
// Compact the segment by moving the widths next to the data.
|
|
161055
|
+
idx_t minimal_widths_offset = AlignValue(data_ptr - handle->node->buffer);
|
|
161056
|
+
idx_t widths_size = handle->node->buffer + Storage::BLOCK_SIZE - width_ptr - 1;
|
|
161057
|
+
idx_t total_segment_size = minimal_widths_offset + widths_size;
|
|
161058
|
+
memmove(handle->node->buffer + minimal_widths_offset, width_ptr + 1, widths_size);
|
|
161059
|
+
|
|
161060
|
+
// Store the offset of the first width (which is at the highest address).
|
|
161061
|
+
Store<idx_t>(minimal_widths_offset + widths_size - 1, handle->node->buffer);
|
|
161062
|
+
handle.reset();
|
|
161063
|
+
|
|
161064
|
+
state.FlushSegment(move(current_segment), total_segment_size);
|
|
161065
|
+
}
|
|
161066
|
+
|
|
161067
|
+
void Finalize() {
|
|
161068
|
+
state.template Flush<BitpackingCompressState<T>::BitpackingWriter>();
|
|
161069
|
+
FlushSegment();
|
|
161070
|
+
current_segment.reset();
|
|
161071
|
+
}
|
|
161072
|
+
};
|
|
161073
|
+
|
|
161074
|
+
template <class T>
|
|
161075
|
+
unique_ptr<CompressionState> BitpackingInitCompression(ColumnDataCheckpointer &checkpointer,
|
|
161076
|
+
unique_ptr<AnalyzeState> state) {
|
|
161077
|
+
return make_unique<BitpackingCompressState<T>>(checkpointer);
|
|
161078
|
+
}
|
|
161079
|
+
|
|
161080
|
+
template <class T>
|
|
161081
|
+
void BitpackingCompress(CompressionState &state_p, Vector &scan_vector, idx_t count) {
|
|
161082
|
+
auto &state = (BitpackingCompressState<T> &)state_p;
|
|
161083
|
+
VectorData vdata;
|
|
161084
|
+
scan_vector.Orrify(count, vdata);
|
|
161085
|
+
state.Append(vdata, count);
|
|
161086
|
+
}
|
|
161087
|
+
|
|
161088
|
+
template <class T>
|
|
161089
|
+
void BitpackingFinalizeCompress(CompressionState &state_p) {
|
|
161090
|
+
auto &state = (BitpackingCompressState<T> &)state_p;
|
|
161091
|
+
state.Finalize();
|
|
161092
|
+
}
|
|
161093
|
+
|
|
161094
|
+
//===--------------------------------------------------------------------===//
|
|
161095
|
+
// Scan
|
|
161096
|
+
//===--------------------------------------------------------------------===//
|
|
161097
|
+
template <class T>
|
|
161098
|
+
struct BitpackingScanState : public SegmentScanState {
|
|
161099
|
+
public:
|
|
161100
|
+
explicit BitpackingScanState(ColumnSegment &segment) {
|
|
161101
|
+
auto &buffer_manager = BufferManager::GetBufferManager(segment.db);
|
|
161102
|
+
handle = buffer_manager.Pin(segment.block);
|
|
161103
|
+
|
|
161104
|
+
current_width_group_ptr =
|
|
161105
|
+
handle->node->buffer + segment.GetBlockOffset() + BitpackingPrimitives::BITPACKING_HEADER_SIZE;
|
|
161106
|
+
|
|
161107
|
+
// load offset to bitpacking widths pointer
|
|
161108
|
+
auto bitpacking_widths_offset = Load<idx_t>(handle->node->buffer + segment.GetBlockOffset());
|
|
161109
|
+
bitpacking_width_ptr = handle->node->buffer + segment.GetBlockOffset() + bitpacking_widths_offset;
|
|
161110
|
+
|
|
161111
|
+
// load the bitwidth of the first vector
|
|
161112
|
+
LoadCurrentBitWidth();
|
|
161113
|
+
}
|
|
161114
|
+
|
|
161115
|
+
unique_ptr<BufferHandle> handle;
|
|
161116
|
+
|
|
161117
|
+
void (*decompress_function)(data_ptr_t, data_ptr_t, bitpacking_width_t, bool skip_sign_extension);
|
|
161118
|
+
T decompression_buffer[BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE];
|
|
161119
|
+
|
|
161120
|
+
idx_t position_in_group = 0;
|
|
161121
|
+
data_ptr_t current_width_group_ptr;
|
|
161122
|
+
data_ptr_t bitpacking_width_ptr;
|
|
161123
|
+
bitpacking_width_t current_width;
|
|
161124
|
+
|
|
161125
|
+
public:
|
|
161126
|
+
void LoadCurrentBitWidth() {
|
|
161127
|
+
D_ASSERT(bitpacking_width_ptr > handle->node->buffer &&
|
|
161128
|
+
bitpacking_width_ptr < handle->node->buffer + Storage::BLOCK_SIZE);
|
|
161129
|
+
current_width = Load<bitpacking_width_t>(bitpacking_width_ptr);
|
|
161130
|
+
LoadDecompressFunction();
|
|
161131
|
+
}
|
|
161132
|
+
|
|
161133
|
+
void Skip(ColumnSegment &segment, idx_t skip_count) {
|
|
161134
|
+
while (skip_count > 0) {
|
|
161135
|
+
if (position_in_group + skip_count < BITPACKING_WIDTH_GROUP_SIZE) {
|
|
161136
|
+
// We're not leaving this bitpacking group, we can perform all skips.
|
|
161137
|
+
position_in_group += skip_count;
|
|
161138
|
+
break;
|
|
161139
|
+
} else {
|
|
161140
|
+
// The skip crosses the current bitpacking group, we skip the remainder of this group.
|
|
161141
|
+
auto skipping = BITPACKING_WIDTH_GROUP_SIZE - position_in_group;
|
|
161142
|
+
position_in_group = 0;
|
|
161143
|
+
current_width_group_ptr += (current_width * BITPACKING_WIDTH_GROUP_SIZE) / 8;
|
|
161144
|
+
|
|
161145
|
+
// Update width pointer and load new width
|
|
161146
|
+
bitpacking_width_ptr -= sizeof(bitpacking_width_t);
|
|
161147
|
+
LoadCurrentBitWidth();
|
|
161148
|
+
|
|
161149
|
+
skip_count -= skipping;
|
|
161150
|
+
}
|
|
161151
|
+
}
|
|
161152
|
+
}
|
|
161153
|
+
|
|
161154
|
+
void LoadDecompressFunction() {
|
|
161155
|
+
decompress_function = &BitpackingPrimitives::UnPackBlock<T>;
|
|
161156
|
+
}
|
|
161157
|
+
};
|
|
161158
|
+
|
|
161159
|
+
template <class T>
|
|
161160
|
+
unique_ptr<SegmentScanState> BitpackingInitScan(ColumnSegment &segment) {
|
|
161161
|
+
auto result = make_unique<BitpackingScanState<T>>(segment);
|
|
161162
|
+
return move(result);
|
|
161163
|
+
}
|
|
161164
|
+
|
|
161165
|
+
//===--------------------------------------------------------------------===//
|
|
161166
|
+
// Scan base data
|
|
161167
|
+
//===--------------------------------------------------------------------===//
|
|
161168
|
+
template <class T>
|
|
161169
|
+
void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result,
|
|
161170
|
+
idx_t result_offset) {
|
|
161171
|
+
auto &scan_state = (BitpackingScanState<T> &)*state.scan_state;
|
|
161172
|
+
|
|
161173
|
+
T *result_data = FlatVector::GetData<T>(result);
|
|
161174
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
161175
|
+
|
|
161176
|
+
// Fast path for when no compression was used, we can do a single memcopy
|
|
161177
|
+
if (STANDARD_VECTOR_SIZE == BITPACKING_WIDTH_GROUP_SIZE) {
|
|
161178
|
+
if (scan_state.current_width == sizeof(T) * 8 && scan_count <= BITPACKING_WIDTH_GROUP_SIZE &&
|
|
161179
|
+
scan_state.position_in_group == 0) {
|
|
161180
|
+
|
|
161181
|
+
memcpy(result_data + result_offset, scan_state.current_width_group_ptr, scan_count * sizeof(T));
|
|
161182
|
+
scan_state.current_width_group_ptr += scan_count * sizeof(T);
|
|
161183
|
+
scan_state.bitpacking_width_ptr -= sizeof(bitpacking_width_t);
|
|
161184
|
+
scan_state.LoadCurrentBitWidth();
|
|
161185
|
+
return;
|
|
161186
|
+
}
|
|
161187
|
+
}
|
|
161188
|
+
|
|
161189
|
+
// Determine if we can skip sign extension during compression
|
|
161190
|
+
auto &nstats = (NumericStatistics &)*segment.stats.statistics;
|
|
161191
|
+
bool skip_sign_extend = std::is_signed<T>::value && nstats.min >= 0;
|
|
161192
|
+
|
|
161193
|
+
idx_t scanned = 0;
|
|
161194
|
+
|
|
161195
|
+
while (scanned < scan_count) {
|
|
161196
|
+
// Exhausted this width group, move pointers to next group and load bitwidth for next group.
|
|
161197
|
+
if (scan_state.position_in_group >= BITPACKING_WIDTH_GROUP_SIZE) {
|
|
161198
|
+
scan_state.position_in_group = 0;
|
|
161199
|
+
scan_state.bitpacking_width_ptr -= sizeof(bitpacking_width_t);
|
|
161200
|
+
scan_state.current_width_group_ptr += (scan_state.current_width * BITPACKING_WIDTH_GROUP_SIZE) / 8;
|
|
161201
|
+
scan_state.LoadCurrentBitWidth();
|
|
161202
|
+
}
|
|
161203
|
+
|
|
161204
|
+
idx_t offset_in_compression_group =
|
|
161205
|
+
scan_state.position_in_group % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE;
|
|
161206
|
+
|
|
161207
|
+
idx_t to_scan = MinValue<idx_t>(scan_count - scanned, BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE -
|
|
161208
|
+
offset_in_compression_group);
|
|
161209
|
+
|
|
161210
|
+
// Calculate start of compression algorithm group
|
|
161211
|
+
data_ptr_t current_position_ptr =
|
|
161212
|
+
scan_state.current_width_group_ptr + scan_state.position_in_group * scan_state.current_width / 8;
|
|
161213
|
+
data_ptr_t decompression_group_start_pointer =
|
|
161214
|
+
current_position_ptr - offset_in_compression_group * scan_state.current_width / 8;
|
|
161215
|
+
|
|
161216
|
+
T *current_result_ptr = result_data + result_offset + scanned;
|
|
161217
|
+
|
|
161218
|
+
if (to_scan == BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE && offset_in_compression_group == 0) {
|
|
161219
|
+
// Decompress directly into result vector
|
|
161220
|
+
scan_state.decompress_function((data_ptr_t)current_result_ptr, decompression_group_start_pointer,
|
|
161221
|
+
scan_state.current_width, skip_sign_extend);
|
|
161222
|
+
} else {
|
|
161223
|
+
// Decompress compression algorithm to buffer
|
|
161224
|
+
scan_state.decompress_function((data_ptr_t)scan_state.decompression_buffer,
|
|
161225
|
+
decompression_group_start_pointer, scan_state.current_width,
|
|
161226
|
+
skip_sign_extend);
|
|
161227
|
+
|
|
161228
|
+
memcpy(current_result_ptr, scan_state.decompression_buffer + offset_in_compression_group,
|
|
161229
|
+
to_scan * sizeof(T));
|
|
161230
|
+
}
|
|
161231
|
+
|
|
161232
|
+
scanned += to_scan;
|
|
161233
|
+
scan_state.position_in_group += to_scan;
|
|
161234
|
+
}
|
|
161235
|
+
}
|
|
161236
|
+
|
|
161237
|
+
template <class T>
|
|
161238
|
+
void BitpackingScan(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result) {
|
|
161239
|
+
BitpackingScanPartial<T>(segment, state, scan_count, result, 0);
|
|
161240
|
+
}
|
|
161241
|
+
|
|
161242
|
+
//===--------------------------------------------------------------------===//
|
|
161243
|
+
// Fetch
|
|
161244
|
+
//===--------------------------------------------------------------------===//
|
|
161245
|
+
template <class T>
|
|
161246
|
+
void BitpackingFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result,
|
|
161247
|
+
idx_t result_idx) {
|
|
161248
|
+
BitpackingScanState<T> scan_state(segment);
|
|
161249
|
+
scan_state.Skip(segment, row_id);
|
|
161250
|
+
auto result_data = FlatVector::GetData<T>(result);
|
|
161251
|
+
T *current_result_ptr = result_data + result_idx;
|
|
161252
|
+
|
|
161253
|
+
// TODO clean up, is reused in partialscan
|
|
161254
|
+
idx_t offset_in_compression_group =
|
|
161255
|
+
scan_state.position_in_group % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE;
|
|
161256
|
+
|
|
161257
|
+
data_ptr_t decompression_group_start_pointer =
|
|
161258
|
+
scan_state.current_width_group_ptr +
|
|
161259
|
+
(scan_state.position_in_group - offset_in_compression_group) * scan_state.current_width / 8;
|
|
161260
|
+
|
|
161261
|
+
auto &nstats = (NumericStatistics &)*segment.stats.statistics;
|
|
161262
|
+
bool skip_sign_extend = std::is_signed<T>::value && nstats.min >= 0;
|
|
161263
|
+
|
|
161264
|
+
scan_state.decompress_function((data_ptr_t)scan_state.decompression_buffer, decompression_group_start_pointer,
|
|
161265
|
+
scan_state.current_width, skip_sign_extend);
|
|
161266
|
+
|
|
161267
|
+
*current_result_ptr = *(T *)(scan_state.decompression_buffer + offset_in_compression_group);
|
|
161268
|
+
}
|
|
161269
|
+
template <class T>
|
|
161270
|
+
void BitpackingSkip(ColumnSegment &segment, ColumnScanState &state, idx_t skip_count) {
|
|
161271
|
+
auto &scan_state = (BitpackingScanState<T> &)*state.scan_state;
|
|
161272
|
+
scan_state.Skip(segment, skip_count);
|
|
161273
|
+
}
|
|
161274
|
+
|
|
161275
|
+
//===--------------------------------------------------------------------===//
|
|
161276
|
+
// Get Function
|
|
161277
|
+
//===--------------------------------------------------------------------===//
|
|
161278
|
+
template <class T>
|
|
161279
|
+
CompressionFunction GetBitpackingFunction(PhysicalType data_type) {
|
|
161280
|
+
return CompressionFunction(CompressionType::COMPRESSION_BITPACKING, data_type, BitpackingInitAnalyze<T>,
|
|
161281
|
+
BitpackingAnalyze<T>, BitpackingFinalAnalyze<T>, BitpackingInitCompression<T>,
|
|
161282
|
+
BitpackingCompress<T>, BitpackingFinalizeCompress<T>, BitpackingInitScan<T>,
|
|
161283
|
+
BitpackingScan<T>, BitpackingScanPartial<T>, BitpackingFetchRow<T>, BitpackingSkip<T>);
|
|
161284
|
+
}
|
|
161285
|
+
|
|
161286
|
+
CompressionFunction BitpackingFun::GetFunction(PhysicalType type) {
|
|
161287
|
+
switch (type) {
|
|
161288
|
+
case PhysicalType::INT8:
|
|
161289
|
+
return GetBitpackingFunction<int8_t>(type);
|
|
161290
|
+
case PhysicalType::INT16:
|
|
161291
|
+
return GetBitpackingFunction<int16_t>(type);
|
|
161292
|
+
case PhysicalType::INT32:
|
|
161293
|
+
return GetBitpackingFunction<int32_t>(type);
|
|
161294
|
+
case PhysicalType::INT64:
|
|
161295
|
+
return GetBitpackingFunction<int64_t>(type);
|
|
161296
|
+
case PhysicalType::BOOL:
|
|
161297
|
+
case PhysicalType::UINT8:
|
|
161298
|
+
return GetBitpackingFunction<uint8_t>(type);
|
|
161299
|
+
case PhysicalType::UINT16:
|
|
161300
|
+
return GetBitpackingFunction<uint16_t>(type);
|
|
161301
|
+
case PhysicalType::UINT32:
|
|
161302
|
+
return GetBitpackingFunction<uint32_t>(type);
|
|
161303
|
+
case PhysicalType::UINT64:
|
|
161304
|
+
return GetBitpackingFunction<uint64_t>(type);
|
|
161305
|
+
default:
|
|
161306
|
+
throw InternalException("Unsupported type for Bitpacking");
|
|
161307
|
+
}
|
|
161308
|
+
}
|
|
161309
|
+
|
|
161310
|
+
bool BitpackingFun::TypeIsSupported(PhysicalType type) {
|
|
161311
|
+
switch (type) {
|
|
161312
|
+
case PhysicalType::BOOL:
|
|
161313
|
+
case PhysicalType::INT8:
|
|
161314
|
+
case PhysicalType::INT16:
|
|
161315
|
+
case PhysicalType::INT32:
|
|
161316
|
+
case PhysicalType::INT64:
|
|
161317
|
+
case PhysicalType::UINT8:
|
|
161318
|
+
case PhysicalType::UINT16:
|
|
161319
|
+
case PhysicalType::UINT32:
|
|
161320
|
+
case PhysicalType::UINT64:
|
|
161321
|
+
return true;
|
|
161322
|
+
default:
|
|
161323
|
+
return false;
|
|
161324
|
+
}
|
|
161325
|
+
}
|
|
161326
|
+
|
|
161327
|
+
} // namespace duckdb
|
|
161328
|
+
//===----------------------------------------------------------------------===//
|
|
161329
|
+
// DuckDB
|
|
161330
|
+
//
|
|
161331
|
+
// duckdb/storage/segment/uncompressed.hpp
|
|
161332
|
+
//
|
|
161333
|
+
//
|
|
161334
|
+
//===----------------------------------------------------------------------===//
|
|
161335
|
+
|
|
161336
|
+
|
|
161337
|
+
|
|
161338
|
+
|
|
161339
|
+
|
|
161340
|
+
namespace duckdb {
|
|
161341
|
+
class DatabaseInstance;
|
|
161342
|
+
|
|
161343
|
+
struct UncompressedFunctions {
|
|
161344
|
+
static unique_ptr<CompressionState> InitCompression(ColumnDataCheckpointer &checkpointer,
|
|
161345
|
+
unique_ptr<AnalyzeState> state);
|
|
161346
|
+
static void Compress(CompressionState &state_p, Vector &data, idx_t count);
|
|
161347
|
+
static void FinalizeCompress(CompressionState &state_p);
|
|
161348
|
+
static void EmptySkip(ColumnSegment &segment, ColumnScanState &state, idx_t skip_count) {
|
|
161349
|
+
}
|
|
161350
|
+
};
|
|
161351
|
+
|
|
161352
|
+
struct FixedSizeUncompressed {
|
|
161353
|
+
static CompressionFunction GetFunction(PhysicalType data_type);
|
|
161354
|
+
};
|
|
161355
|
+
|
|
161356
|
+
struct ValidityUncompressed {
|
|
161357
|
+
public:
|
|
161358
|
+
static CompressionFunction GetFunction(PhysicalType data_type);
|
|
161359
|
+
|
|
161360
|
+
public:
|
|
161361
|
+
static const validity_t LOWER_MASKS[65];
|
|
161362
|
+
static const validity_t UPPER_MASKS[65];
|
|
161363
|
+
};
|
|
161364
|
+
|
|
161365
|
+
struct StringUncompressed {
|
|
161366
|
+
public:
|
|
161367
|
+
static CompressionFunction GetFunction(PhysicalType data_type);
|
|
161368
|
+
|
|
161369
|
+
public:
|
|
161370
|
+
//! The max string size that is allowed within a block. Strings bigger than this will be labeled as a BIG STRING and
|
|
161371
|
+
//! offloaded to the overflow blocks.
|
|
161372
|
+
static constexpr uint16_t STRING_BLOCK_LIMIT = 4096;
|
|
161373
|
+
};
|
|
161374
|
+
|
|
161375
|
+
} // namespace duckdb
|
|
161376
|
+
|
|
161377
|
+
|
|
161378
|
+
|
|
161379
|
+
|
|
161380
|
+
|
|
161381
|
+
|
|
161382
|
+
|
|
161383
|
+
|
|
161384
|
+
|
|
161385
|
+
|
|
161386
|
+
|
|
161387
|
+
|
|
159581
161388
|
namespace duckdb {
|
|
159582
161389
|
|
|
159583
161390
|
//===--------------------------------------------------------------------===//
|
|
@@ -207501,6 +209308,1299 @@ void sdfree(void *ptr) { free(ptr); }
|
|
|
207501
209308
|
// LICENSE_CHANGE_END
|
|
207502
209309
|
|
|
207503
209310
|
|
|
209311
|
+
// LICENSE_CHANGE_BEGIN
|
|
209312
|
+
// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10
|
|
209313
|
+
// See the end of this file for a list
|
|
209314
|
+
|
|
209315
|
+
|
|
209316
|
+
|
|
209317
|
+
#include <cstdint>
|
|
209318
|
+
#include <type_traits>
|
|
209319
|
+
|
|
209320
|
+
namespace duckdb_fastpforlib {
|
|
209321
|
+
namespace internal {
|
|
209322
|
+
|
|
209323
|
+
// Used for uint8_t, uint16_t and uint32_t
|
|
209324
|
+
template <uint8_t DELTA, uint8_t SHR, class TYPE, uint8_t TYPE_SIZE = sizeof(TYPE) * 8>
|
|
209325
|
+
typename std::enable_if<(DELTA + SHR) < TYPE_SIZE>::type unpack_single_out(const TYPE *__restrict in,
|
|
209326
|
+
TYPE *__restrict out) {
|
|
209327
|
+
*out = ((*in) >> SHR) % (1 << DELTA);
|
|
209328
|
+
}
|
|
209329
|
+
|
|
209330
|
+
// Used for uint8_t, uint16_t and uint32_t
|
|
209331
|
+
template <uint8_t DELTA, uint8_t SHR, class TYPE, uint8_t TYPE_SIZE = sizeof(TYPE) * 8>
|
|
209332
|
+
typename std::enable_if<(DELTA + SHR) >= TYPE_SIZE>::type unpack_single_out(const TYPE *__restrict &in,
|
|
209333
|
+
TYPE *__restrict out) {
|
|
209334
|
+
*out = (*in) >> SHR;
|
|
209335
|
+
++in;
|
|
209336
|
+
|
|
209337
|
+
static const TYPE NEXT_SHR = SHR + DELTA - TYPE_SIZE;
|
|
209338
|
+
*out |= ((*in) % (1U << NEXT_SHR)) << (TYPE_SIZE - SHR);
|
|
209339
|
+
}
|
|
209340
|
+
|
|
209341
|
+
template <uint8_t DELTA, uint8_t SHR>
|
|
209342
|
+
typename std::enable_if<(DELTA + SHR) < 32>::type unpack_single_out(const uint32_t *__restrict in,
|
|
209343
|
+
uint64_t *__restrict out) {
|
|
209344
|
+
*out = ((static_cast<uint64_t>(*in)) >> SHR) % (1ULL << DELTA);
|
|
209345
|
+
}
|
|
209346
|
+
|
|
209347
|
+
template <uint8_t DELTA, uint8_t SHR>
|
|
209348
|
+
typename std::enable_if<(DELTA + SHR) >= 32 && (DELTA + SHR) < 64>::type
|
|
209349
|
+
unpack_single_out(const uint32_t *__restrict &in, uint64_t *__restrict out) {
|
|
209350
|
+
*out = static_cast<uint64_t>(*in) >> SHR;
|
|
209351
|
+
++in;
|
|
209352
|
+
if (DELTA + SHR > 32) {
|
|
209353
|
+
static const uint8_t NEXT_SHR = SHR + DELTA - 32;
|
|
209354
|
+
*out |= static_cast<uint64_t>((*in) % (1U << NEXT_SHR)) << (32 - SHR);
|
|
209355
|
+
}
|
|
209356
|
+
}
|
|
209357
|
+
|
|
209358
|
+
template <uint8_t DELTA, uint8_t SHR>
|
|
209359
|
+
typename std::enable_if<(DELTA + SHR) >= 64>::type unpack_single_out(const uint32_t *__restrict &in,
|
|
209360
|
+
uint64_t *__restrict out) {
|
|
209361
|
+
*out = static_cast<uint64_t>(*in) >> SHR;
|
|
209362
|
+
++in;
|
|
209363
|
+
|
|
209364
|
+
*out |= static_cast<uint64_t>(*in) << (32 - SHR);
|
|
209365
|
+
++in;
|
|
209366
|
+
|
|
209367
|
+
if (DELTA + SHR > 64) {
|
|
209368
|
+
static const uint8_t NEXT_SHR = DELTA + SHR - 64;
|
|
209369
|
+
*out |= static_cast<uint64_t>((*in) % (1U << NEXT_SHR)) << (64 - SHR);
|
|
209370
|
+
}
|
|
209371
|
+
}
|
|
209372
|
+
|
|
209373
|
+
// Used for uint8_t, uint16_t and uint32_t
|
|
209374
|
+
template <class TYPE, uint16_t DELTA, uint16_t SHL, TYPE MASK, uint8_t TYPE_SIZE = sizeof(TYPE) * 8>
|
|
209375
|
+
typename std::enable_if < DELTA + SHL<TYPE_SIZE>::type pack_single_in(const TYPE in, TYPE *__restrict out) {
|
|
209376
|
+
if (SHL == 0) {
|
|
209377
|
+
*out = in & MASK;
|
|
209378
|
+
} else {
|
|
209379
|
+
*out |= (in & MASK) << SHL;
|
|
209380
|
+
}
|
|
209381
|
+
}
|
|
209382
|
+
|
|
209383
|
+
// Used for uint8_t, uint16_t and uint32_t
|
|
209384
|
+
template <class TYPE, uint16_t DELTA, uint16_t SHL, TYPE MASK, uint8_t TYPE_SIZE = sizeof(TYPE) * 8>
|
|
209385
|
+
typename std::enable_if<DELTA + SHL >= TYPE_SIZE>::type pack_single_in(const TYPE in, TYPE *__restrict &out) {
|
|
209386
|
+
*out |= in << SHL;
|
|
209387
|
+
++out;
|
|
209388
|
+
|
|
209389
|
+
if (DELTA + SHL > TYPE_SIZE) {
|
|
209390
|
+
*out = (in & MASK) >> (TYPE_SIZE - SHL);
|
|
209391
|
+
}
|
|
209392
|
+
}
|
|
209393
|
+
|
|
209394
|
+
template <uint16_t DELTA, uint16_t SHL, uint64_t MASK>
|
|
209395
|
+
typename std::enable_if < DELTA + SHL<32>::type pack_single_in64(const uint64_t in, uint32_t *__restrict out) {
|
|
209396
|
+
if (SHL == 0) {
|
|
209397
|
+
*out = static_cast<uint32_t>(in & MASK);
|
|
209398
|
+
} else {
|
|
209399
|
+
*out |= (in & MASK) << SHL;
|
|
209400
|
+
}
|
|
209401
|
+
}
|
|
209402
|
+
template <uint16_t DELTA, uint16_t SHL, uint64_t MASK>
|
|
209403
|
+
typename std::enable_if < DELTA + SHL >= 32 &&
|
|
209404
|
+
DELTA + SHL<64>::type pack_single_in64(const uint64_t in, uint32_t *__restrict &out) {
|
|
209405
|
+
if (SHL == 0) {
|
|
209406
|
+
*out = static_cast<uint32_t>(in & MASK);
|
|
209407
|
+
} else {
|
|
209408
|
+
*out |= (in & MASK) << SHL;
|
|
209409
|
+
}
|
|
209410
|
+
|
|
209411
|
+
++out;
|
|
209412
|
+
|
|
209413
|
+
if (DELTA + SHL > 32) {
|
|
209414
|
+
*out = static_cast<uint32_t>((in & MASK) >> (32 - SHL));
|
|
209415
|
+
}
|
|
209416
|
+
}
|
|
209417
|
+
template <uint16_t DELTA, uint16_t SHL, uint64_t MASK>
|
|
209418
|
+
typename std::enable_if<DELTA + SHL >= 64>::type pack_single_in64(const uint64_t in, uint32_t *__restrict &out) {
|
|
209419
|
+
*out |= in << SHL;
|
|
209420
|
+
++out;
|
|
209421
|
+
|
|
209422
|
+
*out = static_cast<uint32_t>((in & MASK) >> (32 - SHL));
|
|
209423
|
+
++out;
|
|
209424
|
+
|
|
209425
|
+
if (DELTA + SHL > 64) {
|
|
209426
|
+
*out = (in & MASK) >> (64 - SHL);
|
|
209427
|
+
}
|
|
209428
|
+
}
|
|
209429
|
+
template <uint16_t DELTA, uint16_t OINDEX = 0>
|
|
209430
|
+
struct Unroller8 {
|
|
209431
|
+
static void Unpack(const uint8_t *__restrict &in, uint8_t *__restrict out) {
|
|
209432
|
+
unpack_single_out<DELTA, (DELTA * OINDEX) % 8>(in, out + OINDEX);
|
|
209433
|
+
|
|
209434
|
+
Unroller8<DELTA, OINDEX + 1>::Unpack(in, out);
|
|
209435
|
+
}
|
|
209436
|
+
|
|
209437
|
+
static void Pack(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209438
|
+
pack_single_in<uint8_t, DELTA, (DELTA * OINDEX) % 8, (1U << DELTA) - 1>(in[OINDEX], out);
|
|
209439
|
+
|
|
209440
|
+
Unroller8<DELTA, OINDEX + 1>::Pack(in, out);
|
|
209441
|
+
}
|
|
209442
|
+
|
|
209443
|
+
};\
|
|
209444
|
+
template <uint16_t DELTA>
|
|
209445
|
+
struct Unroller8<DELTA, 7> {
|
|
209446
|
+
enum { SHIFT = (DELTA * 7) % 8 };
|
|
209447
|
+
|
|
209448
|
+
static void Unpack(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209449
|
+
out[7] = (*in) >> SHIFT;
|
|
209450
|
+
}
|
|
209451
|
+
|
|
209452
|
+
static void Pack(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209453
|
+
*out |= (in[7] << SHIFT);
|
|
209454
|
+
}
|
|
209455
|
+
};
|
|
209456
|
+
|
|
209457
|
+
template <uint16_t DELTA, uint16_t OINDEX = 0>
|
|
209458
|
+
struct Unroller16 {
|
|
209459
|
+
static void Unpack(const uint16_t *__restrict &in, uint16_t *__restrict out) {
|
|
209460
|
+
unpack_single_out<DELTA, (DELTA * OINDEX) % 16>(in, out + OINDEX);
|
|
209461
|
+
|
|
209462
|
+
Unroller16<DELTA, OINDEX + 1>::Unpack(in, out);
|
|
209463
|
+
}
|
|
209464
|
+
|
|
209465
|
+
static void Pack(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209466
|
+
pack_single_in<uint16_t, DELTA, (DELTA * OINDEX) % 16, (1U << DELTA) - 1>(in[OINDEX], out);
|
|
209467
|
+
|
|
209468
|
+
Unroller16<DELTA, OINDEX + 1>::Pack(in, out);
|
|
209469
|
+
}
|
|
209470
|
+
|
|
209471
|
+
};
|
|
209472
|
+
|
|
209473
|
+
template <uint16_t DELTA>
|
|
209474
|
+
struct Unroller16<DELTA, 15> {
|
|
209475
|
+
enum { SHIFT = (DELTA * 15) % 16 };
|
|
209476
|
+
|
|
209477
|
+
static void Unpack(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209478
|
+
out[15] = (*in) >> SHIFT;
|
|
209479
|
+
}
|
|
209480
|
+
|
|
209481
|
+
static void Pack(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209482
|
+
*out |= (in[15] << SHIFT);
|
|
209483
|
+
}
|
|
209484
|
+
};
|
|
209485
|
+
|
|
209486
|
+
template <uint16_t DELTA, uint16_t OINDEX = 0>
|
|
209487
|
+
struct Unroller {
|
|
209488
|
+
static void Unpack(const uint32_t *__restrict &in, uint32_t *__restrict out) {
|
|
209489
|
+
unpack_single_out<DELTA, (DELTA * OINDEX) % 32>(in, out + OINDEX);
|
|
209490
|
+
|
|
209491
|
+
Unroller<DELTA, OINDEX + 1>::Unpack(in, out);
|
|
209492
|
+
}
|
|
209493
|
+
|
|
209494
|
+
static void Unpack(const uint32_t *__restrict &in, uint64_t *__restrict out) {
|
|
209495
|
+
unpack_single_out<DELTA, (DELTA * OINDEX) % 32>(in, out + OINDEX);
|
|
209496
|
+
|
|
209497
|
+
Unroller<DELTA, OINDEX + 1>::Unpack(in, out);
|
|
209498
|
+
}
|
|
209499
|
+
|
|
209500
|
+
static void Pack(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209501
|
+
pack_single_in<uint32_t, DELTA, (DELTA * OINDEX) % 32, (1U << DELTA) - 1>(in[OINDEX], out);
|
|
209502
|
+
|
|
209503
|
+
Unroller<DELTA, OINDEX + 1>::Pack(in, out);
|
|
209504
|
+
}
|
|
209505
|
+
|
|
209506
|
+
static void Pack(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
209507
|
+
pack_single_in64<DELTA, (DELTA * OINDEX) % 32, (1ULL << DELTA) - 1>(in[OINDEX], out);
|
|
209508
|
+
|
|
209509
|
+
Unroller<DELTA, OINDEX + 1>::Pack(in, out);
|
|
209510
|
+
}
|
|
209511
|
+
};
|
|
209512
|
+
|
|
209513
|
+
template <uint16_t DELTA>
|
|
209514
|
+
struct Unroller<DELTA, 31> {
|
|
209515
|
+
enum { SHIFT = (DELTA * 31) % 32 };
|
|
209516
|
+
|
|
209517
|
+
static void Unpack(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209518
|
+
out[31] = (*in) >> SHIFT;
|
|
209519
|
+
}
|
|
209520
|
+
|
|
209521
|
+
static void Unpack(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209522
|
+
out[31] = (*in) >> SHIFT;
|
|
209523
|
+
if (DELTA > 32) {
|
|
209524
|
+
++in;
|
|
209525
|
+
out[31] |= static_cast<uint64_t>(*in) << (32 - SHIFT);
|
|
209526
|
+
}
|
|
209527
|
+
}
|
|
209528
|
+
|
|
209529
|
+
static void Pack(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209530
|
+
*out |= (in[31] << SHIFT);
|
|
209531
|
+
}
|
|
209532
|
+
|
|
209533
|
+
static void Pack(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
209534
|
+
*out |= (in[31] << SHIFT);
|
|
209535
|
+
if (DELTA > 32) {
|
|
209536
|
+
++out;
|
|
209537
|
+
*out = static_cast<uint32_t>(in[31] >> (32 - SHIFT));
|
|
209538
|
+
}
|
|
209539
|
+
}
|
|
209540
|
+
};
|
|
209541
|
+
|
|
209542
|
+
// Special cases
|
|
209543
|
+
void __fastunpack0(const uint8_t *__restrict, uint8_t *__restrict out) {
|
|
209544
|
+
for (uint8_t i = 0; i < 8; ++i)
|
|
209545
|
+
*(out++) = 0;
|
|
209546
|
+
}
|
|
209547
|
+
|
|
209548
|
+
void __fastunpack0(const uint16_t *__restrict, uint16_t *__restrict out) {
|
|
209549
|
+
for (uint16_t i = 0; i < 16; ++i)
|
|
209550
|
+
*(out++) = 0;
|
|
209551
|
+
}
|
|
209552
|
+
|
|
209553
|
+
void __fastunpack0(const uint32_t *__restrict, uint32_t *__restrict out) {
|
|
209554
|
+
for (uint32_t i = 0; i < 32; ++i)
|
|
209555
|
+
*(out++) = 0;
|
|
209556
|
+
}
|
|
209557
|
+
|
|
209558
|
+
void __fastunpack0(const uint32_t *__restrict, uint64_t *__restrict out) {
|
|
209559
|
+
for (uint32_t i = 0; i < 32; ++i)
|
|
209560
|
+
*(out++) = 0;
|
|
209561
|
+
}
|
|
209562
|
+
|
|
209563
|
+
void __fastpack0(const uint8_t *__restrict, uint8_t *__restrict) {
|
|
209564
|
+
}
|
|
209565
|
+
void __fastpack0(const uint16_t *__restrict, uint16_t *__restrict) {
|
|
209566
|
+
}
|
|
209567
|
+
void __fastpack0(const uint32_t *__restrict, uint32_t *__restrict) {
|
|
209568
|
+
}
|
|
209569
|
+
void __fastpack0(const uint64_t *__restrict, uint32_t *__restrict) {
|
|
209570
|
+
}
|
|
209571
|
+
|
|
209572
|
+
// fastunpack for 8 bits
|
|
209573
|
+
void __fastunpack1(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209574
|
+
Unroller8<1>::Unpack(in, out);
|
|
209575
|
+
}
|
|
209576
|
+
|
|
209577
|
+
void __fastunpack2(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209578
|
+
Unroller8<2>::Unpack(in, out);
|
|
209579
|
+
}
|
|
209580
|
+
|
|
209581
|
+
void __fastunpack3(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209582
|
+
Unroller8<3>::Unpack(in, out);
|
|
209583
|
+
}
|
|
209584
|
+
|
|
209585
|
+
void __fastunpack4(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209586
|
+
for (uint8_t outer = 0; outer < 4; ++outer) {
|
|
209587
|
+
for (uint8_t inwordpointer = 0; inwordpointer < 8; inwordpointer += 4)
|
|
209588
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 4);
|
|
209589
|
+
++in;
|
|
209590
|
+
}
|
|
209591
|
+
}
|
|
209592
|
+
|
|
209593
|
+
void __fastunpack5(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209594
|
+
Unroller8<5>::Unpack(in, out);
|
|
209595
|
+
}
|
|
209596
|
+
|
|
209597
|
+
void __fastunpack6(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209598
|
+
Unroller8<6>::Unpack(in, out);
|
|
209599
|
+
}
|
|
209600
|
+
|
|
209601
|
+
void __fastunpack7(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209602
|
+
Unroller8<7>::Unpack(in, out);
|
|
209603
|
+
}
|
|
209604
|
+
|
|
209605
|
+
void __fastunpack8(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
209606
|
+
for (int k = 0; k < 8; ++k)
|
|
209607
|
+
out[k] = in[k];
|
|
209608
|
+
}
|
|
209609
|
+
|
|
209610
|
+
|
|
209611
|
+
// fastunpack for 16 bits
|
|
209612
|
+
void __fastunpack1(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209613
|
+
Unroller16<1>::Unpack(in, out);
|
|
209614
|
+
}
|
|
209615
|
+
|
|
209616
|
+
void __fastunpack2(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209617
|
+
Unroller16<2>::Unpack(in, out);
|
|
209618
|
+
}
|
|
209619
|
+
|
|
209620
|
+
void __fastunpack3(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209621
|
+
Unroller16<3>::Unpack(in, out);
|
|
209622
|
+
}
|
|
209623
|
+
|
|
209624
|
+
void __fastunpack4(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209625
|
+
for (uint16_t outer = 0; outer < 4; ++outer) {
|
|
209626
|
+
for (uint16_t inwordpointer = 0; inwordpointer < 16; inwordpointer += 4)
|
|
209627
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 4);
|
|
209628
|
+
++in;
|
|
209629
|
+
}
|
|
209630
|
+
}
|
|
209631
|
+
|
|
209632
|
+
void __fastunpack5(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209633
|
+
Unroller16<5>::Unpack(in, out);
|
|
209634
|
+
}
|
|
209635
|
+
|
|
209636
|
+
void __fastunpack6(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209637
|
+
Unroller16<6>::Unpack(in, out);
|
|
209638
|
+
}
|
|
209639
|
+
|
|
209640
|
+
void __fastunpack7(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209641
|
+
Unroller16<7>::Unpack(in, out);
|
|
209642
|
+
}
|
|
209643
|
+
|
|
209644
|
+
void __fastunpack8(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209645
|
+
for (uint16_t outer = 0; outer < 8; ++outer) {
|
|
209646
|
+
for (uint16_t inwordpointer = 0; inwordpointer < 16; inwordpointer += 8)
|
|
209647
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 8);
|
|
209648
|
+
++in;
|
|
209649
|
+
}
|
|
209650
|
+
}
|
|
209651
|
+
|
|
209652
|
+
void __fastunpack9(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209653
|
+
Unroller16<9>::Unpack(in, out);
|
|
209654
|
+
}
|
|
209655
|
+
|
|
209656
|
+
void __fastunpack10(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209657
|
+
Unroller16<10>::Unpack(in, out);
|
|
209658
|
+
}
|
|
209659
|
+
|
|
209660
|
+
void __fastunpack11(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209661
|
+
Unroller16<11>::Unpack(in, out);
|
|
209662
|
+
}
|
|
209663
|
+
|
|
209664
|
+
void __fastunpack12(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209665
|
+
Unroller16<12>::Unpack(in, out);
|
|
209666
|
+
}
|
|
209667
|
+
|
|
209668
|
+
void __fastunpack13(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209669
|
+
Unroller16<13>::Unpack(in, out);
|
|
209670
|
+
}
|
|
209671
|
+
|
|
209672
|
+
void __fastunpack14(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209673
|
+
Unroller16<14>::Unpack(in, out);
|
|
209674
|
+
}
|
|
209675
|
+
|
|
209676
|
+
void __fastunpack15(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209677
|
+
Unroller16<15>::Unpack(in, out);
|
|
209678
|
+
}
|
|
209679
|
+
|
|
209680
|
+
void __fastunpack16(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
209681
|
+
for (int k = 0; k < 16; ++k)
|
|
209682
|
+
out[k] = in[k];
|
|
209683
|
+
}
|
|
209684
|
+
|
|
209685
|
+
// fastunpack for 32 bits
|
|
209686
|
+
void __fastunpack1(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209687
|
+
Unroller<1>::Unpack(in, out);
|
|
209688
|
+
}
|
|
209689
|
+
|
|
209690
|
+
void __fastunpack2(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209691
|
+
Unroller<2>::Unpack(in, out);
|
|
209692
|
+
}
|
|
209693
|
+
|
|
209694
|
+
void __fastunpack3(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209695
|
+
Unroller<3>::Unpack(in, out);
|
|
209696
|
+
}
|
|
209697
|
+
|
|
209698
|
+
void __fastunpack4(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209699
|
+
for (uint32_t outer = 0; outer < 4; ++outer) {
|
|
209700
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 4)
|
|
209701
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 4);
|
|
209702
|
+
++in;
|
|
209703
|
+
}
|
|
209704
|
+
}
|
|
209705
|
+
|
|
209706
|
+
void __fastunpack5(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209707
|
+
Unroller<5>::Unpack(in, out);
|
|
209708
|
+
}
|
|
209709
|
+
|
|
209710
|
+
void __fastunpack6(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209711
|
+
Unroller<6>::Unpack(in, out);
|
|
209712
|
+
}
|
|
209713
|
+
|
|
209714
|
+
void __fastunpack7(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209715
|
+
Unroller<7>::Unpack(in, out);
|
|
209716
|
+
}
|
|
209717
|
+
|
|
209718
|
+
void __fastunpack8(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209719
|
+
for (uint32_t outer = 0; outer < 8; ++outer) {
|
|
209720
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 8)
|
|
209721
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 8);
|
|
209722
|
+
++in;
|
|
209723
|
+
}
|
|
209724
|
+
}
|
|
209725
|
+
|
|
209726
|
+
void __fastunpack9(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209727
|
+
Unroller<9>::Unpack(in, out);
|
|
209728
|
+
}
|
|
209729
|
+
|
|
209730
|
+
void __fastunpack10(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209731
|
+
Unroller<10>::Unpack(in, out);
|
|
209732
|
+
}
|
|
209733
|
+
|
|
209734
|
+
void __fastunpack11(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209735
|
+
Unroller<11>::Unpack(in, out);
|
|
209736
|
+
}
|
|
209737
|
+
|
|
209738
|
+
void __fastunpack12(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209739
|
+
Unroller<12>::Unpack(in, out);
|
|
209740
|
+
}
|
|
209741
|
+
|
|
209742
|
+
void __fastunpack13(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209743
|
+
Unroller<13>::Unpack(in, out);
|
|
209744
|
+
}
|
|
209745
|
+
|
|
209746
|
+
void __fastunpack14(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209747
|
+
Unroller<14>::Unpack(in, out);
|
|
209748
|
+
}
|
|
209749
|
+
|
|
209750
|
+
void __fastunpack15(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209751
|
+
Unroller<15>::Unpack(in, out);
|
|
209752
|
+
}
|
|
209753
|
+
|
|
209754
|
+
void __fastunpack16(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209755
|
+
for (uint32_t outer = 0; outer < 16; ++outer) {
|
|
209756
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 16)
|
|
209757
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 16);
|
|
209758
|
+
++in;
|
|
209759
|
+
}
|
|
209760
|
+
}
|
|
209761
|
+
|
|
209762
|
+
void __fastunpack17(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209763
|
+
Unroller<17>::Unpack(in, out);
|
|
209764
|
+
}
|
|
209765
|
+
|
|
209766
|
+
void __fastunpack18(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209767
|
+
Unroller<18>::Unpack(in, out);
|
|
209768
|
+
}
|
|
209769
|
+
|
|
209770
|
+
void __fastunpack19(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209771
|
+
Unroller<19>::Unpack(in, out);
|
|
209772
|
+
}
|
|
209773
|
+
|
|
209774
|
+
void __fastunpack20(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209775
|
+
Unroller<20>::Unpack(in, out);
|
|
209776
|
+
}
|
|
209777
|
+
|
|
209778
|
+
void __fastunpack21(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209779
|
+
Unroller<21>::Unpack(in, out);
|
|
209780
|
+
}
|
|
209781
|
+
|
|
209782
|
+
void __fastunpack22(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209783
|
+
Unroller<22>::Unpack(in, out);
|
|
209784
|
+
}
|
|
209785
|
+
|
|
209786
|
+
void __fastunpack23(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209787
|
+
Unroller<23>::Unpack(in, out);
|
|
209788
|
+
}
|
|
209789
|
+
|
|
209790
|
+
void __fastunpack24(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209791
|
+
Unroller<24>::Unpack(in, out);
|
|
209792
|
+
}
|
|
209793
|
+
|
|
209794
|
+
void __fastunpack25(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209795
|
+
Unroller<25>::Unpack(in, out);
|
|
209796
|
+
}
|
|
209797
|
+
|
|
209798
|
+
void __fastunpack26(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209799
|
+
Unroller<26>::Unpack(in, out);
|
|
209800
|
+
}
|
|
209801
|
+
|
|
209802
|
+
void __fastunpack27(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209803
|
+
Unroller<27>::Unpack(in, out);
|
|
209804
|
+
}
|
|
209805
|
+
|
|
209806
|
+
void __fastunpack28(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209807
|
+
Unroller<28>::Unpack(in, out);
|
|
209808
|
+
}
|
|
209809
|
+
|
|
209810
|
+
void __fastunpack29(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209811
|
+
Unroller<29>::Unpack(in, out);
|
|
209812
|
+
}
|
|
209813
|
+
|
|
209814
|
+
void __fastunpack30(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209815
|
+
Unroller<30>::Unpack(in, out);
|
|
209816
|
+
}
|
|
209817
|
+
|
|
209818
|
+
void __fastunpack31(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209819
|
+
Unroller<31>::Unpack(in, out);
|
|
209820
|
+
}
|
|
209821
|
+
|
|
209822
|
+
void __fastunpack32(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
209823
|
+
for (int k = 0; k < 32; ++k)
|
|
209824
|
+
out[k] = in[k];
|
|
209825
|
+
}
|
|
209826
|
+
|
|
209827
|
+
// fastupack for 64 bits
|
|
209828
|
+
void __fastunpack1(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209829
|
+
Unroller<1>::Unpack(in, out);
|
|
209830
|
+
}
|
|
209831
|
+
|
|
209832
|
+
void __fastunpack2(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209833
|
+
Unroller<2>::Unpack(in, out);
|
|
209834
|
+
}
|
|
209835
|
+
|
|
209836
|
+
void __fastunpack3(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209837
|
+
Unroller<3>::Unpack(in, out);
|
|
209838
|
+
}
|
|
209839
|
+
|
|
209840
|
+
void __fastunpack4(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209841
|
+
for (uint32_t outer = 0; outer < 4; ++outer) {
|
|
209842
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 4)
|
|
209843
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 4);
|
|
209844
|
+
++in;
|
|
209845
|
+
}
|
|
209846
|
+
}
|
|
209847
|
+
|
|
209848
|
+
void __fastunpack5(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209849
|
+
Unroller<5>::Unpack(in, out);
|
|
209850
|
+
}
|
|
209851
|
+
|
|
209852
|
+
void __fastunpack6(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209853
|
+
Unroller<6>::Unpack(in, out);
|
|
209854
|
+
}
|
|
209855
|
+
|
|
209856
|
+
void __fastunpack7(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209857
|
+
Unroller<7>::Unpack(in, out);
|
|
209858
|
+
}
|
|
209859
|
+
|
|
209860
|
+
void __fastunpack8(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209861
|
+
for (uint32_t outer = 0; outer < 8; ++outer) {
|
|
209862
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 8) {
|
|
209863
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 8);
|
|
209864
|
+
}
|
|
209865
|
+
++in;
|
|
209866
|
+
}
|
|
209867
|
+
}
|
|
209868
|
+
|
|
209869
|
+
void __fastunpack9(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209870
|
+
Unroller<9>::Unpack(in, out);
|
|
209871
|
+
}
|
|
209872
|
+
|
|
209873
|
+
void __fastunpack10(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209874
|
+
Unroller<10>::Unpack(in, out);
|
|
209875
|
+
}
|
|
209876
|
+
|
|
209877
|
+
void __fastunpack11(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209878
|
+
Unroller<11>::Unpack(in, out);
|
|
209879
|
+
}
|
|
209880
|
+
|
|
209881
|
+
void __fastunpack12(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209882
|
+
Unroller<12>::Unpack(in, out);
|
|
209883
|
+
}
|
|
209884
|
+
|
|
209885
|
+
void __fastunpack13(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209886
|
+
Unroller<13>::Unpack(in, out);
|
|
209887
|
+
}
|
|
209888
|
+
|
|
209889
|
+
void __fastunpack14(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209890
|
+
Unroller<14>::Unpack(in, out);
|
|
209891
|
+
}
|
|
209892
|
+
|
|
209893
|
+
void __fastunpack15(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209894
|
+
Unroller<15>::Unpack(in, out);
|
|
209895
|
+
}
|
|
209896
|
+
|
|
209897
|
+
void __fastunpack16(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209898
|
+
for (uint32_t outer = 0; outer < 16; ++outer) {
|
|
209899
|
+
for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 16)
|
|
209900
|
+
*(out++) = ((*in) >> inwordpointer) % (1U << 16);
|
|
209901
|
+
++in;
|
|
209902
|
+
}
|
|
209903
|
+
}
|
|
209904
|
+
|
|
209905
|
+
void __fastunpack17(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209906
|
+
Unroller<17>::Unpack(in, out);
|
|
209907
|
+
}
|
|
209908
|
+
|
|
209909
|
+
void __fastunpack18(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209910
|
+
Unroller<18>::Unpack(in, out);
|
|
209911
|
+
}
|
|
209912
|
+
|
|
209913
|
+
void __fastunpack19(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209914
|
+
Unroller<19>::Unpack(in, out);
|
|
209915
|
+
}
|
|
209916
|
+
|
|
209917
|
+
void __fastunpack20(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209918
|
+
Unroller<20>::Unpack(in, out);
|
|
209919
|
+
}
|
|
209920
|
+
|
|
209921
|
+
void __fastunpack21(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209922
|
+
Unroller<21>::Unpack(in, out);
|
|
209923
|
+
}
|
|
209924
|
+
|
|
209925
|
+
void __fastunpack22(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209926
|
+
Unroller<22>::Unpack(in, out);
|
|
209927
|
+
}
|
|
209928
|
+
|
|
209929
|
+
void __fastunpack23(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209930
|
+
Unroller<23>::Unpack(in, out);
|
|
209931
|
+
}
|
|
209932
|
+
|
|
209933
|
+
void __fastunpack24(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209934
|
+
Unroller<24>::Unpack(in, out);
|
|
209935
|
+
}
|
|
209936
|
+
|
|
209937
|
+
void __fastunpack25(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209938
|
+
Unroller<25>::Unpack(in, out);
|
|
209939
|
+
}
|
|
209940
|
+
|
|
209941
|
+
void __fastunpack26(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209942
|
+
Unroller<26>::Unpack(in, out);
|
|
209943
|
+
}
|
|
209944
|
+
|
|
209945
|
+
void __fastunpack27(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209946
|
+
Unroller<27>::Unpack(in, out);
|
|
209947
|
+
}
|
|
209948
|
+
|
|
209949
|
+
void __fastunpack28(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209950
|
+
Unroller<28>::Unpack(in, out);
|
|
209951
|
+
}
|
|
209952
|
+
|
|
209953
|
+
void __fastunpack29(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209954
|
+
Unroller<29>::Unpack(in, out);
|
|
209955
|
+
}
|
|
209956
|
+
|
|
209957
|
+
void __fastunpack30(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209958
|
+
Unroller<30>::Unpack(in, out);
|
|
209959
|
+
}
|
|
209960
|
+
|
|
209961
|
+
void __fastunpack31(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209962
|
+
Unroller<31>::Unpack(in, out);
|
|
209963
|
+
}
|
|
209964
|
+
|
|
209965
|
+
void __fastunpack32(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209966
|
+
for (int k = 0; k < 32; ++k)
|
|
209967
|
+
out[k] = in[k];
|
|
209968
|
+
}
|
|
209969
|
+
|
|
209970
|
+
void __fastunpack33(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209971
|
+
Unroller<33>::Unpack(in, out);
|
|
209972
|
+
}
|
|
209973
|
+
|
|
209974
|
+
void __fastunpack34(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209975
|
+
Unroller<34>::Unpack(in, out);
|
|
209976
|
+
}
|
|
209977
|
+
|
|
209978
|
+
void __fastunpack35(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209979
|
+
Unroller<35>::Unpack(in, out);
|
|
209980
|
+
}
|
|
209981
|
+
|
|
209982
|
+
void __fastunpack36(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209983
|
+
Unroller<36>::Unpack(in, out);
|
|
209984
|
+
}
|
|
209985
|
+
|
|
209986
|
+
void __fastunpack37(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209987
|
+
Unroller<37>::Unpack(in, out);
|
|
209988
|
+
}
|
|
209989
|
+
|
|
209990
|
+
void __fastunpack38(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209991
|
+
Unroller<38>::Unpack(in, out);
|
|
209992
|
+
}
|
|
209993
|
+
|
|
209994
|
+
void __fastunpack39(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209995
|
+
Unroller<39>::Unpack(in, out);
|
|
209996
|
+
}
|
|
209997
|
+
|
|
209998
|
+
void __fastunpack40(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
209999
|
+
Unroller<40>::Unpack(in, out);
|
|
210000
|
+
}
|
|
210001
|
+
|
|
210002
|
+
void __fastunpack41(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210003
|
+
Unroller<41>::Unpack(in, out);
|
|
210004
|
+
}
|
|
210005
|
+
|
|
210006
|
+
void __fastunpack42(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210007
|
+
Unroller<42>::Unpack(in, out);
|
|
210008
|
+
}
|
|
210009
|
+
|
|
210010
|
+
void __fastunpack43(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210011
|
+
Unroller<43>::Unpack(in, out);
|
|
210012
|
+
}
|
|
210013
|
+
|
|
210014
|
+
void __fastunpack44(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210015
|
+
Unroller<44>::Unpack(in, out);
|
|
210016
|
+
}
|
|
210017
|
+
|
|
210018
|
+
void __fastunpack45(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210019
|
+
Unroller<45>::Unpack(in, out);
|
|
210020
|
+
}
|
|
210021
|
+
|
|
210022
|
+
void __fastunpack46(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210023
|
+
Unroller<46>::Unpack(in, out);
|
|
210024
|
+
}
|
|
210025
|
+
|
|
210026
|
+
void __fastunpack47(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210027
|
+
Unroller<47>::Unpack(in, out);
|
|
210028
|
+
}
|
|
210029
|
+
|
|
210030
|
+
void __fastunpack48(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210031
|
+
Unroller<48>::Unpack(in, out);
|
|
210032
|
+
}
|
|
210033
|
+
|
|
210034
|
+
void __fastunpack49(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210035
|
+
Unroller<49>::Unpack(in, out);
|
|
210036
|
+
}
|
|
210037
|
+
|
|
210038
|
+
void __fastunpack50(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210039
|
+
Unroller<50>::Unpack(in, out);
|
|
210040
|
+
}
|
|
210041
|
+
|
|
210042
|
+
void __fastunpack51(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210043
|
+
Unroller<51>::Unpack(in, out);
|
|
210044
|
+
}
|
|
210045
|
+
|
|
210046
|
+
void __fastunpack52(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210047
|
+
Unroller<52>::Unpack(in, out);
|
|
210048
|
+
}
|
|
210049
|
+
|
|
210050
|
+
void __fastunpack53(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210051
|
+
Unroller<53>::Unpack(in, out);
|
|
210052
|
+
}
|
|
210053
|
+
|
|
210054
|
+
void __fastunpack54(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210055
|
+
Unroller<54>::Unpack(in, out);
|
|
210056
|
+
}
|
|
210057
|
+
|
|
210058
|
+
void __fastunpack55(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210059
|
+
Unroller<55>::Unpack(in, out);
|
|
210060
|
+
}
|
|
210061
|
+
|
|
210062
|
+
void __fastunpack56(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210063
|
+
Unroller<56>::Unpack(in, out);
|
|
210064
|
+
}
|
|
210065
|
+
|
|
210066
|
+
void __fastunpack57(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210067
|
+
Unroller<57>::Unpack(in, out);
|
|
210068
|
+
}
|
|
210069
|
+
|
|
210070
|
+
void __fastunpack58(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210071
|
+
Unroller<58>::Unpack(in, out);
|
|
210072
|
+
}
|
|
210073
|
+
|
|
210074
|
+
void __fastunpack59(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210075
|
+
Unroller<59>::Unpack(in, out);
|
|
210076
|
+
}
|
|
210077
|
+
|
|
210078
|
+
void __fastunpack60(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210079
|
+
Unroller<60>::Unpack(in, out);
|
|
210080
|
+
}
|
|
210081
|
+
|
|
210082
|
+
void __fastunpack61(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210083
|
+
Unroller<61>::Unpack(in, out);
|
|
210084
|
+
}
|
|
210085
|
+
|
|
210086
|
+
void __fastunpack62(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210087
|
+
Unroller<62>::Unpack(in, out);
|
|
210088
|
+
}
|
|
210089
|
+
|
|
210090
|
+
void __fastunpack63(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210091
|
+
Unroller<63>::Unpack(in, out);
|
|
210092
|
+
}
|
|
210093
|
+
|
|
210094
|
+
void __fastunpack64(const uint32_t *__restrict in, uint64_t *__restrict out) {
|
|
210095
|
+
for (int k = 0; k < 32; ++k) {
|
|
210096
|
+
out[k] = in[k * 2];
|
|
210097
|
+
out[k] |= static_cast<uint64_t>(in[k * 2 + 1]) << 32;
|
|
210098
|
+
}
|
|
210099
|
+
}
|
|
210100
|
+
|
|
210101
|
+
// fastpack for 8 bits
|
|
210102
|
+
|
|
210103
|
+
void __fastpack1(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210104
|
+
Unroller8<1>::Pack(in, out);
|
|
210105
|
+
}
|
|
210106
|
+
|
|
210107
|
+
void __fastpack2(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210108
|
+
Unroller8<2>::Pack(in, out);
|
|
210109
|
+
}
|
|
210110
|
+
|
|
210111
|
+
void __fastpack3(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210112
|
+
Unroller8<3>::Pack(in, out);
|
|
210113
|
+
}
|
|
210114
|
+
|
|
210115
|
+
void __fastpack4(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210116
|
+
Unroller8<4>::Pack(in, out);
|
|
210117
|
+
}
|
|
210118
|
+
|
|
210119
|
+
void __fastpack5(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210120
|
+
Unroller8<5>::Pack(in, out);
|
|
210121
|
+
}
|
|
210122
|
+
|
|
210123
|
+
void __fastpack6(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210124
|
+
Unroller8<6>::Pack(in, out);
|
|
210125
|
+
}
|
|
210126
|
+
|
|
210127
|
+
void __fastpack7(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210128
|
+
Unroller8<7>::Pack(in, out);
|
|
210129
|
+
}
|
|
210130
|
+
|
|
210131
|
+
void __fastpack8(const uint8_t *__restrict in, uint8_t *__restrict out) {
|
|
210132
|
+
for (int k = 0; k < 8; ++k)
|
|
210133
|
+
out[k] = in[k];
|
|
210134
|
+
}
|
|
210135
|
+
|
|
210136
|
+
// fastpack for 16 bits
|
|
210137
|
+
|
|
210138
|
+
void __fastpack1(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210139
|
+
Unroller16<1>::Pack(in, out);
|
|
210140
|
+
}
|
|
210141
|
+
|
|
210142
|
+
void __fastpack2(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210143
|
+
Unroller16<2>::Pack(in, out);
|
|
210144
|
+
}
|
|
210145
|
+
|
|
210146
|
+
void __fastpack3(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210147
|
+
Unroller16<3>::Pack(in, out);
|
|
210148
|
+
}
|
|
210149
|
+
|
|
210150
|
+
void __fastpack4(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210151
|
+
Unroller16<4>::Pack(in, out);
|
|
210152
|
+
}
|
|
210153
|
+
|
|
210154
|
+
void __fastpack5(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210155
|
+
Unroller16<5>::Pack(in, out);
|
|
210156
|
+
}
|
|
210157
|
+
|
|
210158
|
+
void __fastpack6(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210159
|
+
Unroller16<6>::Pack(in, out);
|
|
210160
|
+
}
|
|
210161
|
+
|
|
210162
|
+
void __fastpack7(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210163
|
+
Unroller16<7>::Pack(in, out);
|
|
210164
|
+
}
|
|
210165
|
+
|
|
210166
|
+
void __fastpack8(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210167
|
+
Unroller16<8>::Pack(in, out);
|
|
210168
|
+
}
|
|
210169
|
+
|
|
210170
|
+
void __fastpack9(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210171
|
+
Unroller16<9>::Pack(in, out);
|
|
210172
|
+
}
|
|
210173
|
+
|
|
210174
|
+
void __fastpack10(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210175
|
+
Unroller16<10>::Pack(in, out);
|
|
210176
|
+
}
|
|
210177
|
+
|
|
210178
|
+
void __fastpack11(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210179
|
+
Unroller16<11>::Pack(in, out);
|
|
210180
|
+
}
|
|
210181
|
+
|
|
210182
|
+
void __fastpack12(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210183
|
+
Unroller16<12>::Pack(in, out);
|
|
210184
|
+
}
|
|
210185
|
+
|
|
210186
|
+
void __fastpack13(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210187
|
+
Unroller16<13>::Pack(in, out);
|
|
210188
|
+
}
|
|
210189
|
+
|
|
210190
|
+
void __fastpack14(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210191
|
+
Unroller16<14>::Pack(in, out);
|
|
210192
|
+
}
|
|
210193
|
+
|
|
210194
|
+
void __fastpack15(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210195
|
+
Unroller16<15>::Pack(in, out);
|
|
210196
|
+
}
|
|
210197
|
+
|
|
210198
|
+
void __fastpack16(const uint16_t *__restrict in, uint16_t *__restrict out) {
|
|
210199
|
+
for (int k = 0; k < 16; ++k)
|
|
210200
|
+
out[k] = in[k];
|
|
210201
|
+
}
|
|
210202
|
+
|
|
210203
|
+
|
|
210204
|
+
// fastpack for 32 bits
|
|
210205
|
+
|
|
210206
|
+
void __fastpack1(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210207
|
+
Unroller<1>::Pack(in, out);
|
|
210208
|
+
}
|
|
210209
|
+
|
|
210210
|
+
void __fastpack2(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210211
|
+
Unroller<2>::Pack(in, out);
|
|
210212
|
+
}
|
|
210213
|
+
|
|
210214
|
+
void __fastpack3(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210215
|
+
Unroller<3>::Pack(in, out);
|
|
210216
|
+
}
|
|
210217
|
+
|
|
210218
|
+
void __fastpack4(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210219
|
+
Unroller<4>::Pack(in, out);
|
|
210220
|
+
}
|
|
210221
|
+
|
|
210222
|
+
void __fastpack5(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210223
|
+
Unroller<5>::Pack(in, out);
|
|
210224
|
+
}
|
|
210225
|
+
|
|
210226
|
+
void __fastpack6(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210227
|
+
Unroller<6>::Pack(in, out);
|
|
210228
|
+
}
|
|
210229
|
+
|
|
210230
|
+
void __fastpack7(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210231
|
+
Unroller<7>::Pack(in, out);
|
|
210232
|
+
}
|
|
210233
|
+
|
|
210234
|
+
void __fastpack8(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210235
|
+
Unroller<8>::Pack(in, out);
|
|
210236
|
+
}
|
|
210237
|
+
|
|
210238
|
+
void __fastpack9(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210239
|
+
Unroller<9>::Pack(in, out);
|
|
210240
|
+
}
|
|
210241
|
+
|
|
210242
|
+
void __fastpack10(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210243
|
+
Unroller<10>::Pack(in, out);
|
|
210244
|
+
}
|
|
210245
|
+
|
|
210246
|
+
void __fastpack11(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210247
|
+
Unroller<11>::Pack(in, out);
|
|
210248
|
+
}
|
|
210249
|
+
|
|
210250
|
+
void __fastpack12(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210251
|
+
Unroller<12>::Pack(in, out);
|
|
210252
|
+
}
|
|
210253
|
+
|
|
210254
|
+
void __fastpack13(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210255
|
+
Unroller<13>::Pack(in, out);
|
|
210256
|
+
}
|
|
210257
|
+
|
|
210258
|
+
void __fastpack14(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210259
|
+
Unroller<14>::Pack(in, out);
|
|
210260
|
+
}
|
|
210261
|
+
|
|
210262
|
+
void __fastpack15(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210263
|
+
Unroller<15>::Pack(in, out);
|
|
210264
|
+
}
|
|
210265
|
+
|
|
210266
|
+
void __fastpack16(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210267
|
+
Unroller<16>::Pack(in, out);
|
|
210268
|
+
}
|
|
210269
|
+
|
|
210270
|
+
void __fastpack17(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210271
|
+
Unroller<17>::Pack(in, out);
|
|
210272
|
+
}
|
|
210273
|
+
|
|
210274
|
+
void __fastpack18(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210275
|
+
Unroller<18>::Pack(in, out);
|
|
210276
|
+
}
|
|
210277
|
+
|
|
210278
|
+
void __fastpack19(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210279
|
+
Unroller<19>::Pack(in, out);
|
|
210280
|
+
}
|
|
210281
|
+
|
|
210282
|
+
void __fastpack20(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210283
|
+
Unroller<20>::Pack(in, out);
|
|
210284
|
+
}
|
|
210285
|
+
|
|
210286
|
+
void __fastpack21(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210287
|
+
Unroller<21>::Pack(in, out);
|
|
210288
|
+
}
|
|
210289
|
+
|
|
210290
|
+
void __fastpack22(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210291
|
+
Unroller<22>::Pack(in, out);
|
|
210292
|
+
}
|
|
210293
|
+
|
|
210294
|
+
void __fastpack23(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210295
|
+
Unroller<23>::Pack(in, out);
|
|
210296
|
+
}
|
|
210297
|
+
|
|
210298
|
+
void __fastpack24(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210299
|
+
Unroller<24>::Pack(in, out);
|
|
210300
|
+
}
|
|
210301
|
+
|
|
210302
|
+
void __fastpack25(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210303
|
+
Unroller<25>::Pack(in, out);
|
|
210304
|
+
}
|
|
210305
|
+
|
|
210306
|
+
void __fastpack26(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210307
|
+
Unroller<26>::Pack(in, out);
|
|
210308
|
+
}
|
|
210309
|
+
|
|
210310
|
+
void __fastpack27(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210311
|
+
Unroller<27>::Pack(in, out);
|
|
210312
|
+
}
|
|
210313
|
+
|
|
210314
|
+
void __fastpack28(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210315
|
+
Unroller<28>::Pack(in, out);
|
|
210316
|
+
}
|
|
210317
|
+
|
|
210318
|
+
void __fastpack29(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210319
|
+
Unroller<29>::Pack(in, out);
|
|
210320
|
+
}
|
|
210321
|
+
|
|
210322
|
+
void __fastpack30(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210323
|
+
Unroller<30>::Pack(in, out);
|
|
210324
|
+
}
|
|
210325
|
+
|
|
210326
|
+
void __fastpack31(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210327
|
+
Unroller<31>::Pack(in, out);
|
|
210328
|
+
}
|
|
210329
|
+
|
|
210330
|
+
void __fastpack32(const uint32_t *__restrict in, uint32_t *__restrict out) {
|
|
210331
|
+
for (int k = 0; k < 32; ++k)
|
|
210332
|
+
out[k] = in[k];
|
|
210333
|
+
}
|
|
210334
|
+
|
|
210335
|
+
// fastpack for 64 bits
|
|
210336
|
+
|
|
210337
|
+
void __fastpack1(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210338
|
+
Unroller<1>::Pack(in, out);
|
|
210339
|
+
}
|
|
210340
|
+
|
|
210341
|
+
void __fastpack2(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210342
|
+
Unroller<2>::Pack(in, out);
|
|
210343
|
+
}
|
|
210344
|
+
|
|
210345
|
+
void __fastpack3(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210346
|
+
Unroller<3>::Pack(in, out);
|
|
210347
|
+
}
|
|
210348
|
+
|
|
210349
|
+
void __fastpack4(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210350
|
+
Unroller<4>::Pack(in, out);
|
|
210351
|
+
}
|
|
210352
|
+
|
|
210353
|
+
void __fastpack5(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210354
|
+
Unroller<5>::Pack(in, out);
|
|
210355
|
+
}
|
|
210356
|
+
|
|
210357
|
+
void __fastpack6(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210358
|
+
Unroller<6>::Pack(in, out);
|
|
210359
|
+
}
|
|
210360
|
+
|
|
210361
|
+
void __fastpack7(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210362
|
+
Unroller<7>::Pack(in, out);
|
|
210363
|
+
}
|
|
210364
|
+
|
|
210365
|
+
void __fastpack8(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210366
|
+
Unroller<8>::Pack(in, out);
|
|
210367
|
+
}
|
|
210368
|
+
|
|
210369
|
+
void __fastpack9(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210370
|
+
Unroller<9>::Pack(in, out);
|
|
210371
|
+
}
|
|
210372
|
+
|
|
210373
|
+
void __fastpack10(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210374
|
+
Unroller<10>::Pack(in, out);
|
|
210375
|
+
}
|
|
210376
|
+
|
|
210377
|
+
void __fastpack11(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210378
|
+
Unroller<11>::Pack(in, out);
|
|
210379
|
+
}
|
|
210380
|
+
|
|
210381
|
+
void __fastpack12(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210382
|
+
Unroller<12>::Pack(in, out);
|
|
210383
|
+
}
|
|
210384
|
+
|
|
210385
|
+
void __fastpack13(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210386
|
+
Unroller<13>::Pack(in, out);
|
|
210387
|
+
}
|
|
210388
|
+
|
|
210389
|
+
void __fastpack14(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210390
|
+
Unroller<14>::Pack(in, out);
|
|
210391
|
+
}
|
|
210392
|
+
|
|
210393
|
+
void __fastpack15(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210394
|
+
Unroller<15>::Pack(in, out);
|
|
210395
|
+
}
|
|
210396
|
+
|
|
210397
|
+
void __fastpack16(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210398
|
+
Unroller<16>::Pack(in, out);
|
|
210399
|
+
}
|
|
210400
|
+
|
|
210401
|
+
void __fastpack17(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210402
|
+
Unroller<17>::Pack(in, out);
|
|
210403
|
+
}
|
|
210404
|
+
|
|
210405
|
+
void __fastpack18(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210406
|
+
Unroller<18>::Pack(in, out);
|
|
210407
|
+
}
|
|
210408
|
+
|
|
210409
|
+
void __fastpack19(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210410
|
+
Unroller<19>::Pack(in, out);
|
|
210411
|
+
}
|
|
210412
|
+
|
|
210413
|
+
void __fastpack20(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210414
|
+
Unroller<20>::Pack(in, out);
|
|
210415
|
+
}
|
|
210416
|
+
|
|
210417
|
+
void __fastpack21(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210418
|
+
Unroller<21>::Pack(in, out);
|
|
210419
|
+
}
|
|
210420
|
+
|
|
210421
|
+
void __fastpack22(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210422
|
+
Unroller<22>::Pack(in, out);
|
|
210423
|
+
}
|
|
210424
|
+
|
|
210425
|
+
void __fastpack23(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210426
|
+
Unroller<23>::Pack(in, out);
|
|
210427
|
+
}
|
|
210428
|
+
|
|
210429
|
+
void __fastpack24(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210430
|
+
Unroller<24>::Pack(in, out);
|
|
210431
|
+
}
|
|
210432
|
+
|
|
210433
|
+
void __fastpack25(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210434
|
+
Unroller<25>::Pack(in, out);
|
|
210435
|
+
}
|
|
210436
|
+
|
|
210437
|
+
void __fastpack26(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210438
|
+
Unroller<26>::Pack(in, out);
|
|
210439
|
+
}
|
|
210440
|
+
|
|
210441
|
+
void __fastpack27(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210442
|
+
Unroller<27>::Pack(in, out);
|
|
210443
|
+
}
|
|
210444
|
+
|
|
210445
|
+
void __fastpack28(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210446
|
+
Unroller<28>::Pack(in, out);
|
|
210447
|
+
}
|
|
210448
|
+
|
|
210449
|
+
void __fastpack29(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210450
|
+
Unroller<29>::Pack(in, out);
|
|
210451
|
+
}
|
|
210452
|
+
|
|
210453
|
+
void __fastpack30(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210454
|
+
Unroller<30>::Pack(in, out);
|
|
210455
|
+
}
|
|
210456
|
+
|
|
210457
|
+
void __fastpack31(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210458
|
+
Unroller<31>::Pack(in, out);
|
|
210459
|
+
}
|
|
210460
|
+
|
|
210461
|
+
void __fastpack32(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210462
|
+
for (int k = 0; k < 32; ++k) {
|
|
210463
|
+
out[k] = static_cast<uint32_t>(in[k]);
|
|
210464
|
+
}
|
|
210465
|
+
}
|
|
210466
|
+
|
|
210467
|
+
void __fastpack33(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210468
|
+
Unroller<33>::Pack(in, out);
|
|
210469
|
+
}
|
|
210470
|
+
|
|
210471
|
+
void __fastpack34(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210472
|
+
Unroller<34>::Pack(in, out);
|
|
210473
|
+
}
|
|
210474
|
+
|
|
210475
|
+
void __fastpack35(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210476
|
+
Unroller<35>::Pack(in, out);
|
|
210477
|
+
}
|
|
210478
|
+
|
|
210479
|
+
void __fastpack36(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210480
|
+
Unroller<36>::Pack(in, out);
|
|
210481
|
+
}
|
|
210482
|
+
|
|
210483
|
+
void __fastpack37(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210484
|
+
Unroller<37>::Pack(in, out);
|
|
210485
|
+
}
|
|
210486
|
+
|
|
210487
|
+
void __fastpack38(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210488
|
+
Unroller<38>::Pack(in, out);
|
|
210489
|
+
}
|
|
210490
|
+
|
|
210491
|
+
void __fastpack39(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210492
|
+
Unroller<39>::Pack(in, out);
|
|
210493
|
+
}
|
|
210494
|
+
|
|
210495
|
+
void __fastpack40(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210496
|
+
Unroller<40>::Pack(in, out);
|
|
210497
|
+
}
|
|
210498
|
+
|
|
210499
|
+
void __fastpack41(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210500
|
+
Unroller<41>::Pack(in, out);
|
|
210501
|
+
}
|
|
210502
|
+
|
|
210503
|
+
void __fastpack42(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210504
|
+
Unroller<42>::Pack(in, out);
|
|
210505
|
+
}
|
|
210506
|
+
|
|
210507
|
+
void __fastpack43(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210508
|
+
Unroller<43>::Pack(in, out);
|
|
210509
|
+
}
|
|
210510
|
+
|
|
210511
|
+
void __fastpack44(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210512
|
+
Unroller<44>::Pack(in, out);
|
|
210513
|
+
}
|
|
210514
|
+
|
|
210515
|
+
void __fastpack45(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210516
|
+
Unroller<45>::Pack(in, out);
|
|
210517
|
+
}
|
|
210518
|
+
|
|
210519
|
+
void __fastpack46(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210520
|
+
Unroller<46>::Pack(in, out);
|
|
210521
|
+
}
|
|
210522
|
+
|
|
210523
|
+
void __fastpack47(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210524
|
+
Unroller<47>::Pack(in, out);
|
|
210525
|
+
}
|
|
210526
|
+
|
|
210527
|
+
void __fastpack48(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210528
|
+
Unroller<48>::Pack(in, out);
|
|
210529
|
+
}
|
|
210530
|
+
|
|
210531
|
+
void __fastpack49(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210532
|
+
Unroller<49>::Pack(in, out);
|
|
210533
|
+
}
|
|
210534
|
+
|
|
210535
|
+
void __fastpack50(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210536
|
+
Unroller<50>::Pack(in, out);
|
|
210537
|
+
}
|
|
210538
|
+
|
|
210539
|
+
void __fastpack51(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210540
|
+
Unroller<51>::Pack(in, out);
|
|
210541
|
+
}
|
|
210542
|
+
|
|
210543
|
+
void __fastpack52(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210544
|
+
Unroller<52>::Pack(in, out);
|
|
210545
|
+
}
|
|
210546
|
+
|
|
210547
|
+
void __fastpack53(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210548
|
+
Unroller<53>::Pack(in, out);
|
|
210549
|
+
}
|
|
210550
|
+
|
|
210551
|
+
void __fastpack54(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210552
|
+
Unroller<54>::Pack(in, out);
|
|
210553
|
+
}
|
|
210554
|
+
|
|
210555
|
+
void __fastpack55(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210556
|
+
Unroller<55>::Pack(in, out);
|
|
210557
|
+
}
|
|
210558
|
+
|
|
210559
|
+
void __fastpack56(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210560
|
+
Unroller<56>::Pack(in, out);
|
|
210561
|
+
}
|
|
210562
|
+
|
|
210563
|
+
void __fastpack57(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210564
|
+
Unroller<57>::Pack(in, out);
|
|
210565
|
+
}
|
|
210566
|
+
|
|
210567
|
+
void __fastpack58(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210568
|
+
Unroller<58>::Pack(in, out);
|
|
210569
|
+
}
|
|
210570
|
+
|
|
210571
|
+
void __fastpack59(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210572
|
+
Unroller<59>::Pack(in, out);
|
|
210573
|
+
}
|
|
210574
|
+
|
|
210575
|
+
void __fastpack60(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210576
|
+
Unroller<60>::Pack(in, out);
|
|
210577
|
+
}
|
|
210578
|
+
|
|
210579
|
+
void __fastpack61(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210580
|
+
Unroller<61>::Pack(in, out);
|
|
210581
|
+
}
|
|
210582
|
+
|
|
210583
|
+
void __fastpack62(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210584
|
+
Unroller<62>::Pack(in, out);
|
|
210585
|
+
}
|
|
210586
|
+
|
|
210587
|
+
void __fastpack63(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210588
|
+
Unroller<63>::Pack(in, out);
|
|
210589
|
+
}
|
|
210590
|
+
|
|
210591
|
+
void __fastpack64(const uint64_t *__restrict in, uint32_t *__restrict out) {
|
|
210592
|
+
for (int i = 0; i < 32; ++i) {
|
|
210593
|
+
out[2 * i] = static_cast<uint32_t>(in[i]);
|
|
210594
|
+
out[2 * i + 1] = in[i] >> 32;
|
|
210595
|
+
}
|
|
210596
|
+
}
|
|
210597
|
+
} // namespace internal
|
|
210598
|
+
} // namespace duckdb_fastpforlib
|
|
210599
|
+
|
|
210600
|
+
|
|
210601
|
+
// LICENSE_CHANGE_END
|
|
210602
|
+
|
|
210603
|
+
|
|
207504
210604
|
// LICENSE_CHANGE_BEGIN
|
|
207505
210605
|
// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #2
|
|
207506
210606
|
// See the end of this file for a list
|
|
@@ -257634,4 +260734,199 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
257634
260734
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
257635
260735
|
POSSIBILITY OF SUCH DAMAGE.
|
|
257636
260736
|
|
|
260737
|
+
|
|
260738
|
+
### THIRD PARTY LICENSE #10 ###
|
|
260739
|
+
|
|
260740
|
+
Apache License
|
|
260741
|
+
Version 2.0, January 2004
|
|
260742
|
+
http://www.apache.org/licenses/
|
|
260743
|
+
|
|
260744
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
260745
|
+
|
|
260746
|
+
1. Definitions.
|
|
260747
|
+
|
|
260748
|
+
"License" shall mean the terms and conditions for use, reproduction, and
|
|
260749
|
+
distribution as defined by Sections 1 through 9 of this document.
|
|
260750
|
+
|
|
260751
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
|
260752
|
+
owner that is granting the License.
|
|
260753
|
+
|
|
260754
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities
|
|
260755
|
+
that control, are controlled by, or are under common control with that entity.
|
|
260756
|
+
For the purposes of this definition, "control" means (i) the power, direct or
|
|
260757
|
+
indirect, to cause the direction or management of such entity, whether by
|
|
260758
|
+
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
260759
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
260760
|
+
|
|
260761
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
260762
|
+
permissions granted by this License.
|
|
260763
|
+
|
|
260764
|
+
"Source" form shall mean the preferred form for making modifications, including
|
|
260765
|
+
but not limited to software source code, documentation source, and configuration
|
|
260766
|
+
files.
|
|
260767
|
+
|
|
260768
|
+
"Object" form shall mean any form resulting from mechanical transformation or
|
|
260769
|
+
translation of a Source form, including but not limited to compiled object code,
|
|
260770
|
+
generated documentation, and conversions to other media types.
|
|
260771
|
+
|
|
260772
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
|
260773
|
+
available under the License, as indicated by a copyright notice that is included
|
|
260774
|
+
in or attached to the work (an example is provided in the Appendix below).
|
|
260775
|
+
|
|
260776
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
|
260777
|
+
is based on (or derived from) the Work and for which the editorial revisions,
|
|
260778
|
+
annotations, elaborations, or other modifications represent, as a whole, an
|
|
260779
|
+
original work of authorship. For the purposes of this License, Derivative Works
|
|
260780
|
+
shall not include works that remain separable from, or merely link (or bind by
|
|
260781
|
+
name) to the interfaces of, the Work and Derivative Works thereof.
|
|
260782
|
+
|
|
260783
|
+
"Contribution" shall mean any work of authorship, including the original version
|
|
260784
|
+
of the Work and any modifications or additions to that Work or Derivative Works
|
|
260785
|
+
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
|
260786
|
+
by the copyright owner or by an individual or Legal Entity authorized to submit
|
|
260787
|
+
on behalf of the copyright owner. For the purposes of this definition,
|
|
260788
|
+
"submitted" means any form of electronic, verbal, or written communication sent
|
|
260789
|
+
to the Licensor or its representatives, including but not limited to
|
|
260790
|
+
communication on electronic mailing lists, source code control systems, and
|
|
260791
|
+
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
|
260792
|
+
the purpose of discussing and improving the Work, but excluding communication
|
|
260793
|
+
that is conspicuously marked or otherwise designated in writing by the copyright
|
|
260794
|
+
owner as "Not a Contribution."
|
|
260795
|
+
|
|
260796
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
|
260797
|
+
of whom a Contribution has been received by Licensor and subsequently
|
|
260798
|
+
incorporated within the Work.
|
|
260799
|
+
|
|
260800
|
+
2. Grant of Copyright License.
|
|
260801
|
+
|
|
260802
|
+
Subject to the terms and conditions of this License, each Contributor hereby
|
|
260803
|
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
|
260804
|
+
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
|
260805
|
+
publicly display, publicly perform, sublicense, and distribute the Work and such
|
|
260806
|
+
Derivative Works in Source or Object form.
|
|
260807
|
+
|
|
260808
|
+
3. Grant of Patent License.
|
|
260809
|
+
|
|
260810
|
+
Subject to the terms and conditions of this License, each Contributor hereby
|
|
260811
|
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
|
260812
|
+
irrevocable (except as stated in this section) patent license to make, have
|
|
260813
|
+
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
|
260814
|
+
such license applies only to those patent claims licensable by such Contributor
|
|
260815
|
+
that are necessarily infringed by their Contribution(s) alone or by combination
|
|
260816
|
+
of their Contribution(s) with the Work to which such Contribution(s) was
|
|
260817
|
+
submitted. If You institute patent litigation against any entity (including a
|
|
260818
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
|
260819
|
+
Contribution incorporated within the Work constitutes direct or contributory
|
|
260820
|
+
patent infringement, then any patent licenses granted to You under this License
|
|
260821
|
+
for that Work shall terminate as of the date such litigation is filed.
|
|
260822
|
+
|
|
260823
|
+
4. Redistribution.
|
|
260824
|
+
|
|
260825
|
+
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
|
260826
|
+
in any medium, with or without modifications, and in Source or Object form,
|
|
260827
|
+
provided that You meet the following conditions:
|
|
260828
|
+
|
|
260829
|
+
You must give any other recipients of the Work or Derivative Works a copy of
|
|
260830
|
+
this License; and
|
|
260831
|
+
You must cause any modified files to carry prominent notices stating that You
|
|
260832
|
+
changed the files; and
|
|
260833
|
+
You must retain, in the Source form of any Derivative Works that You distribute,
|
|
260834
|
+
all copyright, patent, trademark, and attribution notices from the Source form
|
|
260835
|
+
of the Work, excluding those notices that do not pertain to any part of the
|
|
260836
|
+
Derivative Works; and
|
|
260837
|
+
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
|
260838
|
+
Derivative Works that You distribute must include a readable copy of the
|
|
260839
|
+
attribution notices contained within such NOTICE file, excluding those notices
|
|
260840
|
+
that do not pertain to any part of the Derivative Works, in at least one of the
|
|
260841
|
+
following places: within a NOTICE text file distributed as part of the
|
|
260842
|
+
Derivative Works; within the Source form or documentation, if provided along
|
|
260843
|
+
with the Derivative Works; or, within a display generated by the Derivative
|
|
260844
|
+
Works, if and wherever such third-party notices normally appear. The contents of
|
|
260845
|
+
the NOTICE file are for informational purposes only and do not modify the
|
|
260846
|
+
License. You may add Your own attribution notices within Derivative Works that
|
|
260847
|
+
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
|
260848
|
+
provided that such additional attribution notices cannot be construed as
|
|
260849
|
+
modifying the License.
|
|
260850
|
+
You may add Your own copyright statement to Your modifications and may provide
|
|
260851
|
+
additional or different license terms and conditions for use, reproduction, or
|
|
260852
|
+
distribution of Your modifications, or for any such Derivative Works as a whole,
|
|
260853
|
+
provided Your use, reproduction, and distribution of the Work otherwise complies
|
|
260854
|
+
with the conditions stated in this License.
|
|
260855
|
+
|
|
260856
|
+
5. Submission of Contributions.
|
|
260857
|
+
|
|
260858
|
+
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
|
260859
|
+
for inclusion in the Work by You to the Licensor shall be under the terms and
|
|
260860
|
+
conditions of this License, without any additional terms or conditions.
|
|
260861
|
+
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
|
260862
|
+
any separate license agreement you may have executed with Licensor regarding
|
|
260863
|
+
such Contributions.
|
|
260864
|
+
|
|
260865
|
+
6. Trademarks.
|
|
260866
|
+
|
|
260867
|
+
This License does not grant permission to use the trade names, trademarks,
|
|
260868
|
+
service marks, or product names of the Licensor, except as required for
|
|
260869
|
+
reasonable and customary use in describing the origin of the Work and
|
|
260870
|
+
reproducing the content of the NOTICE file.
|
|
260871
|
+
|
|
260872
|
+
7. Disclaimer of Warranty.
|
|
260873
|
+
|
|
260874
|
+
Unless required by applicable law or agreed to in writing, Licensor provides the
|
|
260875
|
+
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
260876
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
|
260877
|
+
including, without limitation, any warranties or conditions of TITLE,
|
|
260878
|
+
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
|
260879
|
+
solely responsible for determining the appropriateness of using or
|
|
260880
|
+
redistributing the Work and assume any risks associated with Your exercise of
|
|
260881
|
+
permissions under this License.
|
|
260882
|
+
|
|
260883
|
+
8. Limitation of Liability.
|
|
260884
|
+
|
|
260885
|
+
In no event and under no legal theory, whether in tort (including negligence),
|
|
260886
|
+
contract, or otherwise, unless required by applicable law (such as deliberate
|
|
260887
|
+
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
|
260888
|
+
liable to You for damages, including any direct, indirect, special, incidental,
|
|
260889
|
+
or consequential damages of any character arising as a result of this License or
|
|
260890
|
+
out of the use or inability to use the Work (including but not limited to
|
|
260891
|
+
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
|
260892
|
+
any and all other commercial damages or losses), even if such Contributor has
|
|
260893
|
+
been advised of the possibility of such damages.
|
|
260894
|
+
|
|
260895
|
+
9. Accepting Warranty or Additional Liability.
|
|
260896
|
+
|
|
260897
|
+
While redistributing the Work or Derivative Works thereof, You may choose to
|
|
260898
|
+
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
|
260899
|
+
other liability obligations and/or rights consistent with this License. However,
|
|
260900
|
+
in accepting such obligations, You may act only on Your own behalf and on Your
|
|
260901
|
+
sole responsibility, not on behalf of any other Contributor, and only if You
|
|
260902
|
+
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
|
260903
|
+
incurred by, or claims asserted against, such Contributor by reason of your
|
|
260904
|
+
accepting any such warranty or additional liability.
|
|
260905
|
+
|
|
260906
|
+
END OF TERMS AND CONDITIONS
|
|
260907
|
+
|
|
260908
|
+
APPENDIX: How to apply the Apache License to your work
|
|
260909
|
+
|
|
260910
|
+
To apply the Apache License to your work, attach the following boilerplate
|
|
260911
|
+
notice, with the fields enclosed by brackets "[]" replaced with your own
|
|
260912
|
+
identifying information. (Don't include the brackets!) The text should be
|
|
260913
|
+
enclosed in the appropriate comment syntax for the file format. We also
|
|
260914
|
+
recommend that a file or class name and description of purpose be included on
|
|
260915
|
+
the same "printed page" as the copyright notice for easier identification within
|
|
260916
|
+
third-party archives.
|
|
260917
|
+
|
|
260918
|
+
Copyright [yyyy] [name of copyright owner]
|
|
260919
|
+
|
|
260920
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
260921
|
+
you may not use this file except in compliance with the License.
|
|
260922
|
+
You may obtain a copy of the License at
|
|
260923
|
+
|
|
260924
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
260925
|
+
|
|
260926
|
+
Unless required by applicable law or agreed to in writing, software
|
|
260927
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
260928
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
260929
|
+
See the License for the specific language governing permissions and
|
|
260930
|
+
limitations under the License.
|
|
260931
|
+
|
|
257637
260932
|
*/
|