duckdb 0.5.2-dev271.0 → 0.5.2-dev289.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.5.2-dev271.0",
4
+ "version": "0.5.2-dev289.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -28634,7 +28634,7 @@ struct PartitionFunctor {
28634
28634
  RowDataCollection &string_heap, RowDataBlock &data_block,
28635
28635
  const data_ptr_t data_ptr, RowDataBlock &heap_block, BufferHandle &heap_handle) {
28636
28636
  D_ASSERT(!layout.AllConstant());
28637
- D_ASSERT(heap_block.block->BlockId() == heap_handle.GetBlockId());
28637
+ D_ASSERT(heap_block.block == heap_handle.GetBlockHandle());
28638
28638
  D_ASSERT(data_block.count >= heap_block.count);
28639
28639
  const auto count = data_block.count - heap_block.count;
28640
28640
  if (count == 0) {
@@ -37411,7 +37411,7 @@ void SBScanState::PinRadix(idx_t block_idx_to) {
37411
37411
  auto &radix_sorting_data = sb->radix_sorting_data;
37412
37412
  D_ASSERT(block_idx_to < radix_sorting_data.size());
37413
37413
  auto &block = radix_sorting_data[block_idx_to];
37414
- if (!radix_handle.IsValid() || radix_handle.GetBlockId() != block->block->BlockId()) {
37414
+ if (!radix_handle.IsValid() || radix_handle.GetBlockHandle() != block->block) {
37415
37415
  radix_handle = buffer_manager.Pin(block->block);
37416
37416
  }
37417
37417
  }
@@ -37422,14 +37422,14 @@ void SBScanState::PinData(SortedData &sd) {
37422
37422
  auto &heap_handle = sd.type == SortedDataType::BLOB ? blob_sorting_heap_handle : payload_heap_handle;
37423
37423
 
37424
37424
  auto &data_block = sd.data_blocks[block_idx];
37425
- if (!data_handle.IsValid() || data_handle.GetBlockId() != data_block->block->BlockId()) {
37425
+ if (!data_handle.IsValid() || data_handle.GetBlockHandle() != data_block->block) {
37426
37426
  data_handle = buffer_manager.Pin(data_block->block);
37427
37427
  }
37428
37428
  if (sd.layout.AllConstant() || !state.external) {
37429
37429
  return;
37430
37430
  }
37431
37431
  auto &heap_block = sd.heap_blocks[block_idx];
37432
- if (!heap_handle.IsValid() || heap_handle.GetBlockId() != heap_block->block->BlockId()) {
37432
+ if (!heap_handle.IsValid() || heap_handle.GetBlockHandle() != heap_block->block) {
37433
37433
  heap_handle = buffer_manager.Pin(heap_block->block);
37434
37434
  }
37435
37435
  }
@@ -37441,7 +37441,7 @@ data_ptr_t SBScanState::RadixPtr() const {
37441
37441
  data_ptr_t SBScanState::DataPtr(SortedData &sd) const {
37442
37442
  auto &data_handle = sd.type == SortedDataType::BLOB ? blob_sorting_data_handle : payload_data_handle;
37443
37443
  D_ASSERT(sd.data_blocks[block_idx]->block->Readers() != 0 &&
37444
- data_handle.GetBlockId() == sd.data_blocks[block_idx]->block->BlockId());
37444
+ data_handle.GetBlockHandle() == sd.data_blocks[block_idx]->block);
37445
37445
  return data_handle.Ptr() + entry_idx * sd.layout.GetRowWidth();
37446
37446
  }
37447
37447
 
@@ -37453,7 +37453,7 @@ data_ptr_t SBScanState::BaseHeapPtr(SortedData &sd) const {
37453
37453
  auto &heap_handle = sd.type == SortedDataType::BLOB ? blob_sorting_heap_handle : payload_heap_handle;
37454
37454
  D_ASSERT(!sd.layout.AllConstant() && state.external);
37455
37455
  D_ASSERT(sd.heap_blocks[block_idx]->block->Readers() != 0 &&
37456
- heap_handle.GetBlockId() == sd.heap_blocks[block_idx]->block->BlockId());
37456
+ heap_handle.GetBlockHandle() == sd.heap_blocks[block_idx]->block);
37457
37457
  return heap_handle.Ptr();
37458
37458
  }
37459
37459
 
@@ -45233,7 +45233,7 @@ void RowDataCollectionScanner::ScanState::PinData() {
45233
45233
  auto &rows = scanner.rows;
45234
45234
  D_ASSERT(block_idx < rows.blocks.size());
45235
45235
  auto &data_block = rows.blocks[block_idx];
45236
- if (!data_handle.IsValid() || data_handle.GetBlockId() != data_block->block->BlockId()) {
45236
+ if (!data_handle.IsValid() || data_handle.GetBlockHandle() != data_block->block) {
45237
45237
  data_handle = rows.buffer_manager.Pin(data_block->block);
45238
45238
  }
45239
45239
  if (scanner.layout.AllConstant() || !scanner.external) {
@@ -45243,7 +45243,7 @@ void RowDataCollectionScanner::ScanState::PinData() {
45243
45243
  auto &heap = scanner.heap;
45244
45244
  D_ASSERT(block_idx < heap.blocks.size());
45245
45245
  auto &heap_block = heap.blocks[block_idx];
45246
- if (!heap_handle.IsValid() || heap_handle.GetBlockId() != heap_block->block->BlockId()) {
45246
+ if (!heap_handle.IsValid() || heap_handle.GetBlockHandle() != heap_block->block) {
45247
45247
  heap_handle = heap.buffer_manager.Pin(heap_block->block);
45248
45248
  }
45249
45249
  }
@@ -161237,8 +161237,8 @@ SubqueryExpression::SubqueryExpression()
161237
161237
  string SubqueryExpression::ToString() const {
161238
161238
  switch (subquery_type) {
161239
161239
  case SubqueryType::ANY:
161240
- return child->ToString() + " " + ExpressionTypeToOperator(comparison_type) + " ANY(" + subquery->ToString() +
161241
- ")";
161240
+ return "(" + child->ToString() + " " + ExpressionTypeToOperator(comparison_type) + " ANY(" +
161241
+ subquery->ToString() + "))";
161242
161242
  case SubqueryType::EXISTS:
161243
161243
  return "EXISTS(" + subquery->ToString() + ")";
161244
161244
  case SubqueryType::NOT_EXISTS:
@@ -191560,17 +191560,11 @@ data_ptr_t BufferHandle::Ptr() {
191560
191560
  return node->buffer;
191561
191561
  }
191562
191562
 
191563
- block_id_t BufferHandle::GetBlockId() const {
191564
- D_ASSERT(handle);
191565
- return handle->BlockId();
191566
- }
191567
-
191568
191563
  void BufferHandle::Destroy() {
191569
191564
  if (!handle || !IsValid()) {
191570
191565
  return;
191571
191566
  }
191572
- auto &buffer_manager = BufferManager::GetBufferManager(handle->db);
191573
- buffer_manager.Unpin(handle);
191567
+ handle->block_manager.buffer_manager.Unpin(handle);
191574
191568
  handle.reset();
191575
191569
  node = nullptr;
191576
191570
  }
@@ -191586,27 +191580,6 @@ FileBuffer &BufferHandle::GetFileBuffer() {
191586
191580
 
191587
191581
 
191588
191582
 
191589
-
191590
- namespace duckdb {
191591
-
191592
- ManagedBuffer::ManagedBuffer(DatabaseInstance &db, idx_t size, bool can_destroy, block_id_t id)
191593
- : FileBuffer(Allocator::Get(db), FileBufferType::MANAGED_BUFFER, size), db(db), can_destroy(can_destroy), id(id) {
191594
- D_ASSERT(id >= MAXIMUM_BLOCK);
191595
- D_ASSERT(size >= Storage::BLOCK_SIZE);
191596
- }
191597
-
191598
- ManagedBuffer::ManagedBuffer(DatabaseInstance &db, FileBuffer &source, bool can_destroy, block_id_t id)
191599
- : FileBuffer(source, FileBufferType::MANAGED_BUFFER), db(db), can_destroy(can_destroy), id(id) {
191600
- D_ASSERT(id >= MAXIMUM_BLOCK);
191601
- D_ASSERT(size >= Storage::BLOCK_SIZE);
191602
- }
191603
-
191604
- } // namespace duckdb
191605
-
191606
-
191607
-
191608
-
191609
-
191610
191583
  //===----------------------------------------------------------------------===//
191611
191584
  // DuckDB
191612
191585
  //
@@ -191682,6 +191655,68 @@ public:
191682
191655
  #endif
191683
191656
 
191684
191657
 
191658
+ //===----------------------------------------------------------------------===//
191659
+ // DuckDB
191660
+ //
191661
+ // duckdb/storage/in_memory_block_manager.hpp
191662
+ //
191663
+ //
191664
+ //===----------------------------------------------------------------------===//
191665
+
191666
+
191667
+
191668
+
191669
+
191670
+
191671
+
191672
+ namespace duckdb {
191673
+
191674
+ //! InMemoryBlockManager is an implementation for a BlockManager
191675
+ class InMemoryBlockManager : public BlockManager {
191676
+ public:
191677
+ using BlockManager::BlockManager;
191678
+
191679
+ // LCOV_EXCL_START
191680
+ void StartCheckpoint() override {
191681
+ throw InternalException("Cannot perform IO in in-memory database!");
191682
+ }
191683
+ unique_ptr<Block> CreateBlock(block_id_t block_id) override {
191684
+ throw InternalException("Cannot perform IO in in-memory database!");
191685
+ }
191686
+ block_id_t GetFreeBlockId() override {
191687
+ throw InternalException("Cannot perform IO in in-memory database!");
191688
+ }
191689
+ bool IsRootBlock(block_id_t root) override {
191690
+ throw InternalException("Cannot perform IO in in-memory database!");
191691
+ }
191692
+ void MarkBlockAsModified(block_id_t block_id) override {
191693
+ throw InternalException("Cannot perform IO in in-memory database!");
191694
+ }
191695
+ void IncreaseBlockReferenceCount(block_id_t block_id) override {
191696
+ throw InternalException("Cannot perform IO in in-memory database!");
191697
+ }
191698
+ block_id_t GetMetaBlock() override {
191699
+ throw InternalException("Cannot perform IO in in-memory database!");
191700
+ }
191701
+ void Read(Block &block) override {
191702
+ throw InternalException("Cannot perform IO in in-memory database!");
191703
+ }
191704
+ void Write(FileBuffer &block, block_id_t block_id) override {
191705
+ throw InternalException("Cannot perform IO in in-memory database!");
191706
+ }
191707
+ void WriteHeader(DatabaseHeader header) override {
191708
+ throw InternalException("Cannot perform IO in in-memory database!");
191709
+ }
191710
+ idx_t TotalBlocks() override {
191711
+ throw InternalException("Cannot perform IO in in-memory database!");
191712
+ }
191713
+ idx_t FreeBlocks() override {
191714
+ throw InternalException("Cannot perform IO in in-memory database!");
191715
+ }
191716
+ // LCOV_EXCL_STOP
191717
+ };
191718
+ } // namespace duckdb
191719
+
191685
191720
 
191686
191721
  namespace duckdb {
191687
191722
 
@@ -191692,17 +191727,18 @@ struct BufferAllocatorData : PrivateAllocatorData {
191692
191727
  BufferManager &manager;
191693
191728
  };
191694
191729
 
191695
- BlockHandle::BlockHandle(DatabaseInstance &db, block_id_t block_id_p)
191696
- : db(db), readers(0), block_id(block_id_p), buffer(nullptr), eviction_timestamp(0), can_destroy(false),
191697
- unswizzled(nullptr) {
191730
+ BlockHandle::BlockHandle(BlockManager &block_manager, block_id_t block_id_p)
191731
+ : block_manager(block_manager), readers(0), block_id(block_id_p), buffer(nullptr), eviction_timestamp(0),
191732
+ can_destroy(false), unswizzled(nullptr) {
191698
191733
  eviction_timestamp = 0;
191699
191734
  state = BlockState::BLOCK_UNLOADED;
191700
191735
  memory_usage = Storage::BLOCK_ALLOC_SIZE;
191701
191736
  }
191702
191737
 
191703
- BlockHandle::BlockHandle(DatabaseInstance &db, block_id_t block_id_p, unique_ptr<FileBuffer> buffer_p,
191738
+ BlockHandle::BlockHandle(BlockManager &block_manager, block_id_t block_id_p, unique_ptr<FileBuffer> buffer_p,
191704
191739
  bool can_destroy_p, idx_t block_size)
191705
- : db(db), readers(0), block_id(block_id_p), eviction_timestamp(0), can_destroy(can_destroy_p), unswizzled(nullptr) {
191740
+ : block_manager(block_manager), readers(0), block_id(block_id_p), eviction_timestamp(0), can_destroy(can_destroy_p),
191741
+ unswizzled(nullptr) {
191706
191742
  D_ASSERT(block_size >= Storage::BLOCK_SIZE);
191707
191743
  buffer = move(buffer_p);
191708
191744
  state = BlockState::BLOCK_LOADED;
@@ -191710,16 +191746,16 @@ BlockHandle::BlockHandle(DatabaseInstance &db, block_id_t block_id_p, unique_ptr
191710
191746
  }
191711
191747
 
191712
191748
  BlockHandle::~BlockHandle() {
191713
- auto &buffer_manager = BufferManager::GetBufferManager(db);
191714
191749
  // being destroyed, so any unswizzled pointers are just binary junk now.
191715
191750
  unswizzled = nullptr;
191751
+ auto &buffer_manager = block_manager.buffer_manager;
191716
191752
  // no references remain to this block: erase
191717
191753
  if (state == BlockState::BLOCK_LOADED) {
191718
191754
  // the block is still loaded in memory: erase it
191719
191755
  buffer.reset();
191720
191756
  buffer_manager.current_memory -= memory_usage;
191721
191757
  }
191722
- buffer_manager.UnregisterBlock(block_id, can_destroy);
191758
+ block_manager.UnregisterBlock(block_id, can_destroy);
191723
191759
  }
191724
191760
 
191725
191761
  unique_ptr<Block> AllocateBlock(Allocator &allocator, unique_ptr<FileBuffer> reusable_buffer, block_id_t block_id) {
@@ -191740,23 +191776,13 @@ unique_ptr<Block> AllocateBlock(Allocator &allocator, unique_ptr<FileBuffer> reu
191740
191776
  }
191741
191777
  }
191742
191778
 
191743
- unique_ptr<ManagedBuffer> AllocateManagedBuffer(DatabaseInstance &db, unique_ptr<FileBuffer> reusable_buffer,
191744
- idx_t size, bool can_destroy, block_id_t id) {
191779
+ unique_ptr<FileBuffer> AllocateManagedBuffer(DatabaseInstance &db, unique_ptr<FileBuffer> reusable_buffer, idx_t size) {
191745
191780
  if (reusable_buffer) {
191746
- // re-usable buffer: re-use it
191747
- if (reusable_buffer->type == FileBufferType::MANAGED_BUFFER) {
191748
- // we can reuse the buffer entirely
191749
- auto &managed = (ManagedBuffer &)*reusable_buffer;
191750
- managed.id = id;
191751
- managed.can_destroy = can_destroy;
191752
- return unique_ptr_cast<FileBuffer, ManagedBuffer>(move(reusable_buffer));
191753
- }
191754
- auto buffer = make_unique<ManagedBuffer>(db, *reusable_buffer, can_destroy, id);
191755
- reusable_buffer.reset();
191756
- return buffer;
191781
+ auto tmp = move(reusable_buffer);
191782
+ return make_unique<FileBuffer>(*tmp, FileBufferType::MANAGED_BUFFER);
191757
191783
  } else {
191758
191784
  // no re-usable buffer: allocate a new buffer
191759
- return make_unique<ManagedBuffer>(db, size, can_destroy, id);
191785
+ return make_unique<FileBuffer>(Allocator::Get(db), FileBufferType::MANAGED_BUFFER, size);
191760
191786
  }
191761
191787
  }
191762
191788
 
@@ -191767,17 +191793,17 @@ BufferHandle BlockHandle::Load(shared_ptr<BlockHandle> &handle, unique_ptr<FileB
191767
191793
  return BufferHandle(handle, handle->buffer.get());
191768
191794
  }
191769
191795
 
191770
- auto &buffer_manager = BufferManager::GetBufferManager(handle->db);
191771
- auto &block_manager = BlockManager::GetBlockManager(handle->db);
191796
+ auto &block_manager = handle->block_manager;
191772
191797
  if (handle->block_id < MAXIMUM_BLOCK) {
191773
- auto block = AllocateBlock(Allocator::Get(handle->db), move(reusable_buffer), handle->block_id);
191798
+ auto block = AllocateBlock(Allocator::Get(block_manager.buffer_manager.GetDatabase()), move(reusable_buffer),
191799
+ handle->block_id);
191774
191800
  block_manager.Read(*block);
191775
191801
  handle->buffer = move(block);
191776
191802
  } else {
191777
191803
  if (handle->can_destroy) {
191778
191804
  return BufferHandle();
191779
191805
  } else {
191780
- handle->buffer = buffer_manager.ReadTemporaryBuffer(handle->block_id, move(reusable_buffer));
191806
+ handle->buffer = block_manager.buffer_manager.ReadTemporaryBuffer(handle->block_id, move(reusable_buffer));
191781
191807
  }
191782
191808
  }
191783
191809
  handle->state = BlockState::BLOCK_LOADED;
@@ -191785,7 +191811,6 @@ BufferHandle BlockHandle::Load(shared_ptr<BlockHandle> &handle, unique_ptr<FileB
191785
191811
  }
191786
191812
 
191787
191813
  unique_ptr<FileBuffer> BlockHandle::UnloadAndTakeBlock() {
191788
- auto &buffer_manager = BufferManager::GetBufferManager(db);
191789
191814
  if (state == BlockState::BLOCK_UNLOADED) {
191790
191815
  // already unloaded: nothing to do
191791
191816
  return nullptr;
@@ -191796,9 +191821,9 @@ unique_ptr<FileBuffer> BlockHandle::UnloadAndTakeBlock() {
191796
191821
 
191797
191822
  if (block_id >= MAXIMUM_BLOCK && !can_destroy) {
191798
191823
  // temporary block that cannot be destroyed: write to temporary file
191799
- buffer_manager.WriteTemporaryBuffer((ManagedBuffer &)*buffer);
191824
+ block_manager.buffer_manager.WriteTemporaryBuffer(block_id, *buffer);
191800
191825
  }
191801
- buffer_manager.current_memory -= memory_usage;
191826
+ block_manager.buffer_manager.current_memory -= memory_usage;
191802
191827
  state = BlockState::BLOCK_UNLOADED;
191803
191828
  return move(buffer);
191804
191829
  }
@@ -191817,8 +191842,7 @@ bool BlockHandle::CanUnload() {
191817
191842
  // there are active readers
191818
191843
  return false;
191819
191844
  }
191820
- auto &buffer_manager = BufferManager::GetBufferManager(db);
191821
- if (block_id >= MAXIMUM_BLOCK && !can_destroy && buffer_manager.temp_directory.empty()) {
191845
+ if (block_id >= MAXIMUM_BLOCK && !can_destroy && block_manager.buffer_manager.temp_directory.empty()) {
191822
191846
  // in order to unload this block we need to write it to a temporary buffer
191823
191847
  // however, no temporary directory is specified!
191824
191848
  // hence we cannot unload the block
@@ -191894,12 +191918,13 @@ BufferManager::BufferManager(DatabaseInstance &db, string tmp, idx_t maximum_mem
191894
191918
  queue(make_unique<EvictionQueue>()), temporary_id(MAXIMUM_BLOCK),
191895
191919
  buffer_allocator(BufferAllocatorAllocate, BufferAllocatorFree, BufferAllocatorRealloc,
191896
191920
  make_unique<BufferAllocatorData>(*this)) {
191921
+ temp_block_manager = make_unique<InMemoryBlockManager>(*this);
191897
191922
  }
191898
191923
 
191899
191924
  BufferManager::~BufferManager() {
191900
191925
  }
191901
191926
 
191902
- shared_ptr<BlockHandle> BufferManager::RegisterBlock(block_id_t block_id) {
191927
+ shared_ptr<BlockHandle> BlockManager::RegisterBlock(block_id_t block_id) {
191903
191928
  lock_guard<mutex> lock(blocks_lock);
191904
191929
  // check if the block already exists
191905
191930
  auto entry = blocks.find(block_id);
@@ -191912,17 +191937,16 @@ shared_ptr<BlockHandle> BufferManager::RegisterBlock(block_id_t block_id) {
191912
191937
  }
191913
191938
  }
191914
191939
  // create a new block pointer for this block
191915
- auto result = make_shared<BlockHandle>(db, block_id);
191940
+ auto result = make_shared<BlockHandle>(*this, block_id);
191916
191941
  // register the block pointer in the set of blocks as a weak pointer
191917
191942
  blocks[block_id] = weak_ptr<BlockHandle>(result);
191918
191943
  return result;
191919
191944
  }
191920
191945
 
191921
- shared_ptr<BlockHandle> BufferManager::ConvertToPersistent(BlockManager &block_manager, block_id_t block_id,
191922
- shared_ptr<BlockHandle> old_block) {
191946
+ shared_ptr<BlockHandle> BlockManager::ConvertToPersistent(block_id_t block_id, shared_ptr<BlockHandle> old_block) {
191923
191947
 
191924
191948
  // pin the old block to ensure we have it loaded in memory
191925
- auto old_handle = Pin(old_block);
191949
+ auto old_handle = buffer_manager.Pin(old_block);
191926
191950
  D_ASSERT(old_block->state == BlockState::BLOCK_LOADED);
191927
191951
  D_ASSERT(old_block->buffer);
191928
191952
 
@@ -191943,9 +191967,9 @@ shared_ptr<BlockHandle> BufferManager::ConvertToPersistent(BlockManager &block_m
191943
191967
  old_block.reset();
191944
191968
 
191945
191969
  // persist the new block to disk
191946
- block_manager.Write(*new_block->buffer, block_id);
191970
+ Write(*new_block->buffer, block_id);
191947
191971
 
191948
- AddToEvictionQueue(new_block);
191972
+ buffer_manager.AddToEvictionQueue(new_block);
191949
191973
 
191950
191974
  return new_block;
191951
191975
  }
@@ -191959,11 +191983,10 @@ shared_ptr<BlockHandle> BufferManager::RegisterMemory(idx_t block_size, bool can
191959
191983
  GetUsedMemory(), GetMaxMemory(), InMemoryWarning());
191960
191984
  }
191961
191985
 
191962
- auto temp_id = ++temporary_id;
191963
- auto buffer = AllocateManagedBuffer(db, move(reusable_buffer), block_size, can_destroy, temp_id);
191986
+ auto buffer = AllocateManagedBuffer(db, move(reusable_buffer), block_size);
191964
191987
 
191965
191988
  // create a new block pointer for this block
191966
- return make_shared<BlockHandle>(db, temp_id, move(buffer), can_destroy, block_size);
191989
+ return make_shared<BlockHandle>(*temp_block_manager, ++temporary_id, move(buffer), can_destroy, block_size);
191967
191990
  }
191968
191991
 
191969
191992
  BufferHandle BufferManager::Allocate(idx_t block_size) {
@@ -192095,12 +192118,12 @@ void BufferManager::PurgeQueue() {
192095
192118
  }
192096
192119
  }
192097
192120
 
192098
- void BufferManager::UnregisterBlock(block_id_t block_id, bool can_destroy) {
192121
+ void BlockManager::UnregisterBlock(block_id_t block_id, bool can_destroy) {
192099
192122
  if (block_id >= MAXIMUM_BLOCK) {
192100
192123
  // in-memory buffer: destroy the buffer
192101
192124
  if (!can_destroy) {
192102
192125
  // buffer could have been offloaded to disk: remove the file
192103
- DeleteTemporaryFile(block_id);
192126
+ buffer_manager.DeleteTemporaryFile(block_id);
192104
192127
  }
192105
192128
  } else {
192106
192129
  lock_guard<mutex> lock(blocks_lock);
@@ -192108,6 +192131,7 @@ void BufferManager::UnregisterBlock(block_id_t block_id, bool can_destroy) {
192108
192131
  blocks.erase(block_id);
192109
192132
  }
192110
192133
  }
192134
+
192111
192135
  void BufferManager::SetLimit(idx_t limit) {
192112
192136
  lock_guard<mutex> l_lock(limit_lock);
192113
192137
  // try to evict until the limit is reached
@@ -192132,10 +192156,9 @@ void BufferManager::SetLimit(idx_t limit) {
192132
192156
  //===--------------------------------------------------------------------===//
192133
192157
  // Temporary File Management
192134
192158
  //===--------------------------------------------------------------------===//
192135
- unique_ptr<ManagedBuffer> ReadTemporaryBufferInternal(DatabaseInstance &db, FileHandle &handle, idx_t position,
192136
- idx_t size, block_id_t id,
192137
- unique_ptr<FileBuffer> reusable_buffer) {
192138
- auto buffer = AllocateManagedBuffer(db, move(reusable_buffer), size, false, id);
192159
+ unique_ptr<FileBuffer> ReadTemporaryBufferInternal(DatabaseInstance &db, FileHandle &handle, idx_t position, idx_t size,
192160
+ unique_ptr<FileBuffer> reusable_buffer) {
192161
+ auto buffer = AllocateManagedBuffer(db, move(reusable_buffer), size);
192139
192162
  buffer->Read(handle, position);
192140
192163
  return buffer;
192141
192164
  }
@@ -192249,14 +192272,14 @@ public:
192249
192272
  return TemporaryFileIndex(file_index, block_index);
192250
192273
  }
192251
192274
 
192252
- void WriteTemporaryFile(ManagedBuffer &buffer, TemporaryFileIndex index) {
192275
+ void WriteTemporaryFile(FileBuffer &buffer, TemporaryFileIndex index) {
192253
192276
  D_ASSERT(buffer.size == Storage::BLOCK_SIZE);
192254
192277
  buffer.Write(*handle, GetPositionInFile(index.block_index));
192255
192278
  }
192256
192279
 
192257
192280
  unique_ptr<FileBuffer> ReadTemporaryBuffer(block_id_t id, idx_t block_index,
192258
192281
  unique_ptr<FileBuffer> reusable_buffer) {
192259
- auto buffer = ReadTemporaryBufferInternal(db, *handle, GetPositionInFile(block_index), Storage::BLOCK_SIZE, id,
192282
+ auto buffer = ReadTemporaryBufferInternal(db, *handle, GetPositionInFile(block_index), Storage::BLOCK_SIZE,
192260
192283
  move(reusable_buffer));
192261
192284
  {
192262
192285
  // remove the block (and potentially truncate the temp file)
@@ -192264,7 +192287,7 @@ public:
192264
192287
  D_ASSERT(handle);
192265
192288
  RemoveTempBlockIndex(lock, block_index);
192266
192289
  }
192267
- return move(buffer);
192290
+ return buffer;
192268
192291
  }
192269
192292
 
192270
192293
  bool DeleteIfEmpty() {
@@ -192328,7 +192351,7 @@ public:
192328
192351
  lock_guard<mutex> lock;
192329
192352
  };
192330
192353
 
192331
- void WriteTemporaryBuffer(ManagedBuffer &buffer) {
192354
+ void WriteTemporaryBuffer(block_id_t block_id, FileBuffer &buffer) {
192332
192355
  D_ASSERT(buffer.size == Storage::BLOCK_SIZE);
192333
192356
  TemporaryFileIndex index;
192334
192357
  TemporaryFileHandle *handle = nullptr;
@@ -192353,8 +192376,8 @@ public:
192353
192376
 
192354
192377
  index = handle->TryGetBlockIndex();
192355
192378
  }
192356
- D_ASSERT(used_blocks.find(buffer.id) == used_blocks.end());
192357
- used_blocks[buffer.id] = index;
192379
+ D_ASSERT(used_blocks.find(block_id) == used_blocks.end());
192380
+ used_blocks[block_id] = index;
192358
192381
  }
192359
192382
  D_ASSERT(handle);
192360
192383
  D_ASSERT(index.IsValid());
@@ -192464,16 +192487,16 @@ void BufferManager::RequireTemporaryDirectory() {
192464
192487
  }
192465
192488
  }
192466
192489
 
192467
- void BufferManager::WriteTemporaryBuffer(ManagedBuffer &buffer) {
192490
+ void BufferManager::WriteTemporaryBuffer(block_id_t block_id, FileBuffer &buffer) {
192468
192491
  RequireTemporaryDirectory();
192469
192492
  if (buffer.size == Storage::BLOCK_SIZE) {
192470
- temp_directory_handle->GetTempFile().WriteTemporaryBuffer(buffer);
192493
+ temp_directory_handle->GetTempFile().WriteTemporaryBuffer(block_id, buffer);
192471
192494
  return;
192472
192495
  }
192473
192496
 
192474
192497
  D_ASSERT(buffer.size > Storage::BLOCK_SIZE);
192475
192498
  // get the path to write to
192476
- auto path = GetTemporaryPath(buffer.id);
192499
+ auto path = GetTemporaryPath(block_id);
192477
192500
  // create the file and write the size followed by the buffer contents
192478
192501
  auto &fs = FileSystem::GetFileSystem(db);
192479
192502
  auto handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE);
@@ -192495,11 +192518,11 @@ unique_ptr<FileBuffer> BufferManager::ReadTemporaryBuffer(block_id_t id, unique_
192495
192518
  handle->Read(&block_size, sizeof(idx_t), 0);
192496
192519
 
192497
192520
  // now allocate a buffer of this size and read the data into that buffer
192498
- auto buffer = ReadTemporaryBufferInternal(db, *handle, sizeof(idx_t), block_size, id, move(reusable_buffer));
192521
+ auto buffer = ReadTemporaryBufferInternal(db, *handle, sizeof(idx_t), block_size, move(reusable_buffer));
192499
192522
 
192500
192523
  handle.reset();
192501
192524
  DeleteTemporaryFile(id);
192502
- return move(buffer);
192525
+ return buffer;
192503
192526
  }
192504
192527
 
192505
192528
  void BufferManager::DeleteTemporaryFile(block_id_t id) {
@@ -193527,12 +193550,11 @@ void CheckpointManager::FlushPartialSegments() {
193527
193550
  }
193528
193551
 
193529
193552
  void PartialBlock::FlushToDisk(DatabaseInstance &db) {
193530
- auto &buffer_manager = BufferManager::GetBufferManager(db);
193531
193553
  auto &block_manager = BlockManager::GetBlockManager(db);
193532
193554
 
193533
193555
  // the data for the block might already exists in-memory of our block
193534
193556
  // instead of copying the data we alter some metadata so the buffer points to an on-disk block
193535
- block = buffer_manager.ConvertToPersistent(block_manager, block_id, move(block));
193557
+ block = block_manager.ConvertToPersistent(block_id, move(block));
193536
193558
 
193537
193559
  // now set this block as the block for all segments
193538
193560
  for (auto &seg : segments) {
@@ -197750,12 +197772,13 @@ string_t UncompressedStringStorage::ReadOverflowString(ColumnSegment &segment, V
197750
197772
  D_ASSERT(block != INVALID_BLOCK);
197751
197773
  D_ASSERT(offset < Storage::BLOCK_SIZE);
197752
197774
 
197775
+ auto &block_manager = BlockManager::GetBlockManager(segment.db);
197753
197776
  auto &buffer_manager = BufferManager::GetBufferManager(segment.db);
197754
197777
  auto &state = (UncompressedStringSegmentState &)*segment.GetSegmentState();
197755
197778
  if (block < MAXIMUM_BLOCK) {
197756
197779
  // read the overflow string from disk
197757
197780
  // pin the initial handle and read the length
197758
- auto block_handle = buffer_manager.RegisterBlock(block);
197781
+ auto block_handle = block_manager.RegisterBlock(block);
197759
197782
  auto handle = buffer_manager.Pin(block_handle);
197760
197783
 
197761
197784
  // read header
@@ -197785,7 +197808,7 @@ string_t UncompressedStringStorage::ReadOverflowString(ColumnSegment &segment, V
197785
197808
  if (remaining > 0) {
197786
197809
  // read the next block
197787
197810
  block_id_t next_block = Load<block_id_t>(handle.Ptr() + offset);
197788
- block_handle = buffer_manager.RegisterBlock(next_block);
197811
+ block_handle = block_manager.RegisterBlock(next_block);
197789
197812
  handle = buffer_manager.Pin(block_handle);
197790
197813
  offset = 0;
197791
197814
  }
@@ -199911,7 +199934,7 @@ void MetaBlockReader::ReadNewBlock(block_id_t id) {
199911
199934
  auto &buffer_manager = BufferManager::GetBufferManager(db);
199912
199935
 
199913
199936
  block_manager.MarkBlockAsModified(id);
199914
- block = buffer_manager.RegisterBlock(id);
199937
+ block = block_manager.RegisterBlock(id);
199915
199938
  handle = buffer_manager.Pin(block);
199916
199939
 
199917
199940
  next_block = Load<block_id_t>(handle.Ptr());
@@ -200103,6 +200126,7 @@ private:
200103
200126
 
200104
200127
 
200105
200128
 
200129
+
200106
200130
  #include <algorithm>
200107
200131
  #include <cstring>
200108
200132
 
@@ -200178,7 +200202,7 @@ T DeserializeHeaderStructure(data_ptr_t ptr) {
200178
200202
 
200179
200203
  SingleFileBlockManager::SingleFileBlockManager(DatabaseInstance &db, string path_p, bool read_only, bool create_new,
200180
200204
  bool use_direct_io)
200181
- : db(db), path(move(path_p)),
200205
+ : BlockManager(BufferManager::GetBufferManager(db)), db(db), path(move(path_p)),
200182
200206
  header_buffer(Allocator::Get(db), FileBufferType::MANAGED_BUFFER, Storage::FILE_HEADER_SIZE), iteration_count(0),
200183
200207
  read_only(read_only), use_direct_io(use_direct_io) {
200184
200208
  uint8_t flags;
@@ -201613,65 +201637,6 @@ void StorageLock::ReleaseSharedLock() {
201613
201637
  } // namespace duckdb
201614
201638
 
201615
201639
 
201616
- //===----------------------------------------------------------------------===//
201617
- // DuckDB
201618
- //
201619
- // duckdb/storage/in_memory_block_manager.hpp
201620
- //
201621
- //
201622
- //===----------------------------------------------------------------------===//
201623
-
201624
-
201625
-
201626
-
201627
-
201628
-
201629
-
201630
- namespace duckdb {
201631
-
201632
- //! InMemoryBlockManager is an implementation for a BlockManager
201633
- class InMemoryBlockManager : public BlockManager {
201634
- public:
201635
- // LCOV_EXCL_START
201636
- void StartCheckpoint() override {
201637
- throw InternalException("Cannot perform IO in in-memory database!");
201638
- }
201639
- unique_ptr<Block> CreateBlock(block_id_t block_id) override {
201640
- throw InternalException("Cannot perform IO in in-memory database!");
201641
- }
201642
- block_id_t GetFreeBlockId() override {
201643
- throw InternalException("Cannot perform IO in in-memory database!");
201644
- }
201645
- bool IsRootBlock(block_id_t root) override {
201646
- throw InternalException("Cannot perform IO in in-memory database!");
201647
- }
201648
- void MarkBlockAsModified(block_id_t block_id) override {
201649
- throw InternalException("Cannot perform IO in in-memory database!");
201650
- }
201651
- void IncreaseBlockReferenceCount(block_id_t block_id) override {
201652
- throw InternalException("Cannot perform IO in in-memory database!");
201653
- }
201654
- block_id_t GetMetaBlock() override {
201655
- throw InternalException("Cannot perform IO in in-memory database!");
201656
- }
201657
- void Read(Block &block) override {
201658
- throw InternalException("Cannot perform IO in in-memory database!");
201659
- }
201660
- void Write(FileBuffer &block, block_id_t block_id) override {
201661
- throw InternalException("Cannot perform IO in in-memory database!");
201662
- }
201663
- void WriteHeader(DatabaseHeader header) override {
201664
- throw InternalException("Cannot perform IO in in-memory database!");
201665
- }
201666
- idx_t TotalBlocks() override {
201667
- throw InternalException("Cannot perform IO in in-memory database!");
201668
- }
201669
- idx_t FreeBlocks() override {
201670
- throw InternalException("Cannot perform IO in in-memory database!");
201671
- }
201672
- // LCOV_EXCL_STOP
201673
- };
201674
- } // namespace duckdb
201675
201640
 
201676
201641
 
201677
201642
 
@@ -201748,7 +201713,7 @@ void StorageManager::Initialize() {
201748
201713
  // create or load the database from disk, if not in-memory mode
201749
201714
  LoadDatabase();
201750
201715
  } else {
201751
- block_manager = make_unique<InMemoryBlockManager>();
201716
+ block_manager = make_unique<InMemoryBlockManager>(*buffer_manager);
201752
201717
  }
201753
201718
  }
201754
201719
 
@@ -203234,6 +203199,7 @@ ColumnSegment::ColumnSegment(DatabaseInstance &db, LogicalType type_p, ColumnSeg
203234
203199
  segment_type(segment_type), function(function_p), stats(type, move(statistics)), block_id(block_id_p),
203235
203200
  offset(offset_p) {
203236
203201
  D_ASSERT(function);
203202
+ auto &block_manager = BlockManager::GetBlockManager(db);
203237
203203
  auto &buffer_manager = BufferManager::GetBufferManager(db);
203238
203204
  if (block_id == INVALID_BLOCK) {
203239
203205
  // no block id specified
@@ -203245,7 +203211,7 @@ ColumnSegment::ColumnSegment(DatabaseInstance &db, LogicalType type_p, ColumnSeg
203245
203211
  }
203246
203212
  } else {
203247
203213
  D_ASSERT(segment_type == ColumnSegmentType::PERSISTENT);
203248
- this->block = buffer_manager.RegisterBlock(block_id);
203214
+ this->block = block_manager.RegisterBlock(block_id);
203249
203215
  }
203250
203216
  if (function->init_segment) {
203251
203217
  segment_state = function->init_segment(*this, block_id);
@@ -203339,12 +203305,11 @@ void ColumnSegment::ConvertToPersistent(block_id_t block_id_p) {
203339
203305
  block.reset();
203340
203306
  } else {
203341
203307
  // non-constant block: write the block to disk
203342
- auto &buffer_manager = BufferManager::GetBufferManager(db);
203343
203308
  auto &block_manager = BlockManager::GetBlockManager(db);
203344
203309
 
203345
203310
  // the data for the block already exists in-memory of our block
203346
203311
  // instead of copying the data we alter some metadata so the buffer points to an on-disk block
203347
- block = buffer_manager.ConvertToPersistent(block_manager, block_id, move(block));
203312
+ block = block_manager.ConvertToPersistent(block_id, move(block));
203348
203313
  }
203349
203314
 
203350
203315
  segment_state.reset();