OmniSciDB  085a039ca4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
foreign_storage::CachingForeignStorageMgr Class Reference

#include <CachingForeignStorageMgr.h>

+ Inheritance diagram for foreign_storage::CachingForeignStorageMgr:
+ Collaboration diagram for foreign_storage::CachingForeignStorageMgr:

Public Member Functions

 CachingForeignStorageMgr (ForeignStorageCache *cache)
 
void fetchBuffer (const ChunkKey &chunk_key, AbstractBuffer *destination_buffer, const size_t num_bytes) override
 
void getChunkMetadataVecForKeyPrefix (ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix) override
 
void getChunkMetadataVecFromDataWrapper (ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix)
 
void removeTableRelatedDS (const int db_id, const int table_id) override
 
void refreshTable (const ChunkKey &table_key, const bool evict_cached_entries) override
 
bool createDataWrapperIfNotExists (const ChunkKey &chunk_key) override
 
- Public Member Functions inherited from foreign_storage::ForeignStorageMgr
 ForeignStorageMgr ()
 
 ~ForeignStorageMgr () override
 
AbstractBuffercreateBuffer (const ChunkKey &chunk_key, const size_t page_size, const size_t initial_size) override
 
void deleteBuffer (const ChunkKey &chunk_key, const bool purge) override
 
void deleteBuffersWithPrefix (const ChunkKey &chunk_key_prefix, const bool purge) override
 
AbstractBuffergetBuffer (const ChunkKey &chunk_key, const size_t num_bytes) override
 
void fetchBuffer (const ChunkKey &chunk_key, AbstractBuffer *destination_buffer, const size_t num_bytes) override
 
AbstractBufferputBuffer (const ChunkKey &chunk_key, AbstractBuffer *source_buffer, const size_t num_bytes) override
 
void getChunkMetadataVecForKeyPrefix (ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix) override
 
bool isBufferOnDevice (const ChunkKey &chunk_key) override
 
std::string printSlabs () override
 
size_t getMaxSize () override
 
size_t getInUseSize () override
 
size_t getAllocated () override
 
bool isAllocationCapped () override
 
void checkpoint () override
 
void checkpoint (const int db_id, const int tb_id) override
 
AbstractBufferalloc (const size_t num_bytes) override
 
void free (AbstractBuffer *buffer) override
 
MgrType getMgrType () override
 
std::string getStringMgrType () override
 
size_t getNumChunks () override
 
void removeTableRelatedDS (const int db_id, const int table_id) override
 
bool hasDataWrapperForChunk (const ChunkKey &chunk_key) const
 
bool isDatawrapperRestored (const ChunkKey &chunk_key)
 
void setDataWrapper (const ChunkKey &table_key, std::shared_ptr< MockForeignDataWrapper > data_wrapper)
 
std::shared_ptr
< ForeignDataWrapper
getDataWrapper (const ChunkKey &chunk_key) const
 
void setParallelismHints (const std::map< ChunkKey, std::set< ParallelismHint >> &hints_per_table)
 

Private Member Functions

void refreshTableInCache (const ChunkKey &table_key)
 
int getHighestCachedFragId (const ChunkKey &table_key)
 
void refreshAppendTableInCache (const ChunkKey &table_key, const std::vector< ChunkKey > &old_chunk_keys)
 
void refreshNonAppendTableInCache (const ChunkKey &table_key, const std::vector< ChunkKey > &old_chunk_keys)
 
void refreshChunksInCacheByFragment (const std::vector< ChunkKey > &old_chunk_keys, int last_frag_id)
 
void populateChunkBuffersSafely (ForeignDataWrapper &data_wrapper, ChunkToBufferMap &required_buffers, ChunkToBufferMap &optional_buffers)
 
void eraseDataWrapper (const ChunkKey &key) override
 
void clearTable (const ChunkKey &table_key)
 
size_t maxFetchSize (int32_t db_id) const override
 
bool hasMaxFetchSize () const override
 
std::set< ChunkKeygetOptionalKeysWithinSizeLimit (const ChunkKey &chunk_key, const std::set< ChunkKey, decltype(set_comp)* > &same_fragment_keys, const std::set< ChunkKey, decltype(set_comp)* > &diff_fragment_keys) const override
 
size_t getBufferSize (const ChunkKey &key) const
 
size_t getRequiredBuffersSize (const ChunkKey &chunk_key) const
 

Private Attributes

ForeignStorageCachedisk_cache_
 

Additional Inherited Members

- Public Types inherited from foreign_storage::ForeignStorageMgr
using ParallelismHint = std::pair< int, int >
 
- Protected Member Functions inherited from foreign_storage::ForeignStorageMgr
void updateFragmenterMetadata (const ChunkToBufferMap &) const
 
void createDataWrapperUnlocked (int32_t db, int32_t tb)
 
bool fetchBufferIfTempBufferMapEntryExists (const ChunkKey &chunk_key, AbstractBuffer *destination_buffer, const size_t num_bytes)
 
ChunkToBufferMap allocateTempBuffersForChunks (const std::set< ChunkKey > &chunk_keys)
 
void clearTempChunkBufferMapEntriesForTable (const ChunkKey &table_key)
 
void clearTempChunkBufferMapEntriesForTableUnlocked (const ChunkKey &table_key)
 
std::set< ChunkKeygetOptionalChunkKeySet (const ChunkKey &chunk_key, const std::set< ChunkKey > &required_chunk_keys, const ForeignDataWrapper::ParallelismLevel parallelism_level) const
 
std::pair< std::set< ChunkKey,
decltype(set_comp)* >
, std::set< ChunkKey, decltype(set_comp)* > > 
getPrefetchSets (const ChunkKey &chunk_key, const std::set< ChunkKey > &required_chunk_keys, const ForeignDataWrapper::ParallelismLevel parallelism_level) const
 
- Static Protected Member Functions inherited from foreign_storage::ForeignStorageMgr
static void checkIfS3NeedsToBeEnabled (const ChunkKey &chunk_key)
 
- Protected Attributes inherited from foreign_storage::ForeignStorageMgr
std::shared_mutex data_wrapper_mutex_
 
std::map< ChunkKey,
std::shared_ptr
< ForeignDataWrapper > > 
data_wrapper_map_
 
std::map< ChunkKey,
std::unique_ptr
< AbstractBuffer > > 
temp_chunk_buffer_map_
 
std::shared_mutex temp_chunk_buffer_map_mutex_
 
std::shared_mutex parallelism_hints_mutex_
 
std::map< ChunkKey, std::set
< ParallelismHint > > 
parallelism_hints_per_table_
 

Detailed Description

Definition at line 28 of file CachingForeignStorageMgr.h.

Constructor & Destructor Documentation

foreign_storage::CachingForeignStorageMgr::CachingForeignStorageMgr ( ForeignStorageCache cache)

Definition at line 37 of file CachingForeignStorageMgr.cpp.

References CHECK, and disk_cache_.

38  : ForeignStorageMgr(), disk_cache_(cache) {
40 }
#define CHECK(condition)
Definition: Logger.h:223

Member Function Documentation

void foreign_storage::CachingForeignStorageMgr::clearTable ( const ChunkKey table_key)
private

Definition at line 235 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageCache::clearForTablePrefix(), disk_cache_, and foreign_storage::ForeignStorageMgr::eraseDataWrapper().

Referenced by getChunkMetadataVecFromDataWrapper(), refreshNonAppendTableInCache(), and refreshTable().

235  {
236  disk_cache_->clearForTablePrefix(table_key);
238 }
virtual void eraseDataWrapper(const ChunkKey &table_key)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool foreign_storage::CachingForeignStorageMgr::createDataWrapperIfNotExists ( const ChunkKey chunk_key)
overridevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 356 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageMgr::createDataWrapperUnlocked(), foreign_storage::ForeignStorageMgr::data_wrapper_map_, foreign_storage::ForeignStorageMgr::data_wrapper_mutex_, disk_cache_, get_table_key(), get_table_prefix(), foreign_storage::ForeignStorageCache::getCachedMetadataVecForKeyPrefix(), and foreign_storage::ForeignStorageCache::getSerializedWrapperPath().

Referenced by getChunkMetadataVecForKeyPrefix().

356  {
357  std::lock_guard data_wrapper_lock(data_wrapper_mutex_);
358  ChunkKey table_key = get_table_key(chunk_key);
359  auto data_wrapper_it = data_wrapper_map_.find(table_key);
360  if (data_wrapper_it != data_wrapper_map_.end()) {
361  return false;
362  }
363  auto [db, tb] = get_table_prefix(chunk_key);
365  auto wrapper_file = disk_cache_->getSerializedWrapperPath(db, tb);
366  if (boost::filesystem::exists(wrapper_file)) {
367  ChunkMetadataVector chunk_metadata;
368  disk_cache_->getCachedMetadataVecForKeyPrefix(chunk_metadata, table_key);
369  data_wrapper_map_.at(table_key)->restoreDataWrapperInternals(
370  disk_cache_->getSerializedWrapperPath(db, tb), chunk_metadata);
371  }
372  return true;
373 }
std::vector< int > ChunkKey
Definition: types.h:37
ChunkKey get_table_key(const ChunkKey &key)
Definition: types.h:58
void getCachedMetadataVecForKeyPrefix(ChunkMetadataVector &, const ChunkKey &) const
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
std::string getSerializedWrapperPath(int32_t db_id, int32_t tb_id) const
std::map< ChunkKey, std::shared_ptr< ForeignDataWrapper > > data_wrapper_map_
std::pair< int, int > get_table_prefix(const ChunkKey &key)
Definition: types.h:63
void createDataWrapperUnlocked(int32_t db, int32_t tb)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::eraseDataWrapper ( const ChunkKey key)
overrideprivatevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 222 of file CachingForeignStorageMgr.cpp.

References CHECK, foreign_storage::ForeignStorageMgr::data_wrapper_map_, foreign_storage::ForeignStorageMgr::data_wrapper_mutex_, disk_cache_, get_table_prefix(), foreign_storage::ForeignStorageCache::getSerializedWrapperPath(), and is_table_key().

Referenced by getChunkMetadataVecForKeyPrefix().

222  {
223  CHECK(is_table_key(key));
224  std::lock_guard data_wrapper_lock(data_wrapper_mutex_);
225  // May not be created yet
226  if (data_wrapper_map_.find(key) != data_wrapper_map_.end()) {
227  auto [db, tb] = get_table_prefix(key);
228  // Need to erase serialized version on disk if it exists so we don't accidentally
229  // recover it after deleting.
230  boost::filesystem::remove_all(disk_cache_->getSerializedWrapperPath(db, tb));
231  data_wrapper_map_.erase(key);
232  }
233 }
bool is_table_key(const ChunkKey &key)
Definition: types.h:45
std::string getSerializedWrapperPath(int32_t db_id, int32_t tb_id) const
std::map< ChunkKey, std::shared_ptr< ForeignDataWrapper > > data_wrapper_map_
std::pair< int, int > get_table_prefix(const ChunkKey &key)
Definition: types.h:63
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::fetchBuffer ( const ChunkKey chunk_key,
AbstractBuffer destination_buffer,
const size_t  num_bytes 
)
override

Definition at line 76 of file CachingForeignStorageMgr.cpp.

References CHECK, CHUNK_KEY_DB_IDX, Data_Namespace::AbstractBuffer::copyTo(), disk_cache_, foreign_storage::ForeignStorageMgr::fetchBuffer(), foreign_storage::get_column_key_set(), foreign_storage::ForeignStorageCache::getCachedChunkIfExists(), foreign_storage::ForeignStorageCache::getChunkBuffersForCaching(), foreign_storage::ForeignStorageMgr::getDataWrapper(), foreign_storage::ForeignStorageMgr::getOptionalChunkKeySet(), getRequiredBuffersSize(), foreign_storage::is_system_table_chunk_key(), Data_Namespace::AbstractBuffer::isDirty(), maxFetchSize(), populateChunkBuffersSafely(), and foreign_storage::ChunkSizeValidator::validateChunkSize().

78  {
79  ChunkSizeValidator chunk_size_validator(chunk_key);
80  if (is_system_table_chunk_key(chunk_key)) {
81  ForeignStorageMgr::fetchBuffer(chunk_key, destination_buffer, num_bytes);
82  chunk_size_validator.validateChunkSize(destination_buffer);
83  return;
84  }
85  CHECK(destination_buffer);
86  CHECK(!destination_buffer->isDirty());
87 
89  if (buffer) {
90  chunk_size_validator.validateChunkSize(buffer);
91  buffer->copyTo(destination_buffer, num_bytes);
92  return;
93  } else {
94  auto required_size = getRequiredBuffersSize(chunk_key);
95  if (required_size > maxFetchSize(chunk_key[CHUNK_KEY_DB_IDX])) {
96  // If we don't have space in the cache then skip the caching.
97  ForeignStorageMgr::fetchBuffer(chunk_key, destination_buffer, num_bytes);
98  return;
99  }
100 
101  auto column_keys = get_column_key_set(chunk_key);
102 
103  // Use hints to prefetch other chunks in fragment into cache
104  auto& data_wrapper = *getDataWrapper(chunk_key);
105  auto optional_set = getOptionalChunkKeySet(
106  chunk_key, column_keys, data_wrapper.getCachedParallelismLevel());
107 
108  // Remove any chunks that are already cached.
109  // TODO(Misiu): Change to use std::erase_if when we get c++20
110  for (auto it = optional_set.begin(); it != optional_set.end();) {
111  if (disk_cache_->getCachedChunkIfExists(*it) != nullptr) {
112  it = optional_set.erase(it);
113  } else {
114  ++it;
115  }
116  }
117 
118  auto optional_buffers = disk_cache_->getChunkBuffersForCaching(optional_set);
119  auto required_buffers = disk_cache_->getChunkBuffersForCaching(column_keys);
120  CHECK(required_buffers.find(chunk_key) != required_buffers.end());
121  populateChunkBuffersSafely(data_wrapper, required_buffers, optional_buffers);
122 
123  AbstractBuffer* buffer = required_buffers.at(chunk_key);
124  CHECK(buffer);
125  buffer->copyTo(destination_buffer, num_bytes);
126  }
127 }
bool is_system_table_chunk_key(const ChunkKey &chunk_key)
std::shared_ptr< ForeignDataWrapper > getDataWrapper(const ChunkKey &chunk_key) const
#define CHUNK_KEY_DB_IDX
Definition: types.h:39
size_t maxFetchSize(int32_t db_id) const override
std::set< ChunkKey > get_column_key_set(const ChunkKey &destination_chunk_key)
std::set< ChunkKey > getOptionalChunkKeySet(const ChunkKey &chunk_key, const std::set< ChunkKey > &required_chunk_keys, const ForeignDataWrapper::ParallelismLevel parallelism_level) const
void fetchBuffer(const ChunkKey &chunk_key, AbstractBuffer *destination_buffer, const size_t num_bytes) override
An AbstractBuffer is a unit of data management for a data manager.
void populateChunkBuffersSafely(ForeignDataWrapper &data_wrapper, ChunkToBufferMap &required_buffers, ChunkToBufferMap &optional_buffers)
ChunkToBufferMap getChunkBuffersForCaching(const std::set< ChunkKey > &chunk_keys) const
void copyTo(AbstractBuffer *destination_buffer, const size_t num_bytes=0)
#define CHECK(condition)
Definition: Logger.h:223
File_Namespace::FileBuffer * getCachedChunkIfExists(const ChunkKey &)
size_t getRequiredBuffersSize(const ChunkKey &chunk_key) const

+ Here is the call graph for this function:

size_t foreign_storage::CachingForeignStorageMgr::getBufferSize ( const ChunkKey key) const
private

Definition at line 424 of file CachingForeignStorageMgr.cpp.

References CHECK_EQ, disk_cache_, get_fragment_key(), foreign_storage::get_max_chunk_size(), foreign_storage::ForeignStorageCache::getCachedMetadataVecForKeyPrefix(), is_varlen_data_key(), is_varlen_key(), and show_chunk().

Referenced by getOptionalKeysWithinSizeLimit(), and getRequiredBuffersSize().

424  {
425  size_t num_bytes = 0;
426  ChunkMetadataVector meta;
428  CHECK_EQ(meta.size(), 1U) << show_chunk(key);
429  auto metadata = meta.begin()->second;
430 
431  if (is_varlen_key(key)) {
432  if (is_varlen_data_key(key)) {
433  num_bytes = get_max_chunk_size(key);
434  } else {
435  num_bytes = (metadata->sqlType.is_string())
436  ? sizeof(StringOffsetT) * (metadata->numElements + 1)
437  : sizeof(ArrayOffsetT) * (metadata->numElements + 1);
438  }
439  } else {
440  num_bytes = metadata->numBytes;
441  }
442  return num_bytes;
443 }
#define CHECK_EQ(x, y)
Definition: Logger.h:231
bool is_varlen_data_key(const ChunkKey &key)
Definition: types.h:76
std::string show_chunk(const ChunkKey &key)
Definition: types.h:99
int32_t StringOffsetT
Definition: sqltypes.h:1113
void getCachedMetadataVecForKeyPrefix(ChunkMetadataVector &, const ChunkKey &) const
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
size_t get_max_chunk_size(const ChunkKey &key)
int32_t ArrayOffsetT
Definition: sqltypes.h:1114
ChunkKey get_fragment_key(const ChunkKey &key)
Definition: types.h:91
bool is_varlen_key(const ChunkKey &key)
Definition: types.h:72

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::getChunkMetadataVecForKeyPrefix ( ChunkMetadataVector chunk_metadata,
const ChunkKey chunk_key_prefix 
)
override

Definition at line 129 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageCache::cacheMetadataVec(), CHECK, createDataWrapperIfNotExists(), disk_cache_, eraseDataWrapper(), foreign_storage::fragment_maps_to_leaf(), get_table_key(), foreign_storage::ForeignStorageCache::getCachedMetadataVecForKeyPrefix(), foreign_storage::ForeignStorageMgr::getChunkMetadataVecForKeyPrefix(), getChunkMetadataVecFromDataWrapper(), has_table_prefix(), foreign_storage::ForeignStorageCache::hasCachedMetadataForKeyPrefix(), foreign_storage::is_shardable_key(), foreign_storage::is_system_table_chunk_key(), and show_chunk().

131  {
132  if (is_system_table_chunk_key(key_prefix)) {
133  ForeignStorageMgr::getChunkMetadataVecForKeyPrefix(chunk_metadata, key_prefix);
134  return;
135  }
136  CHECK(has_table_prefix(key_prefix));
137  // If the disk has any cached metadata for a prefix then it is guaranteed to have all
138  // metadata for that table, so we can return a complete set. If it has no metadata,
139  // then it may be that the table has no data, or that it's just not cached, so we need
140  // to go to storage to check.
141  if (disk_cache_->hasCachedMetadataForKeyPrefix(key_prefix)) {
142  disk_cache_->getCachedMetadataVecForKeyPrefix(chunk_metadata, key_prefix);
143 
144  // Assert all metadata in cache is mapped to this leaf node in distributed.
145  if (is_shardable_key(key_prefix)) {
146  for (auto& [key, meta] : chunk_metadata) {
147  CHECK(fragment_maps_to_leaf(key)) << show_chunk(key);
148  }
149  }
150 
151  // If the data in cache was restored from disk then it is possible that the wrapper
152  // does not exist yet. In this case the wrapper will be restored from disk if
153  // possible.
154  createDataWrapperIfNotExists(key_prefix);
155  return;
156  }
157 
158  // If we have no cached data then either the data was evicted, was never populated, or
159  // the data for the table is an empty set (no chunks). In case we are hitting the first
160  // two, we should repopulate the data wrapper so just do it in all cases.
161  auto table_key = get_table_key(key_prefix);
162  eraseDataWrapper(table_key);
163  createDataWrapperIfNotExists(table_key);
164 
165  getChunkMetadataVecFromDataWrapper(chunk_metadata, key_prefix);
166  disk_cache_->cacheMetadataVec(chunk_metadata);
167 }
bool is_system_table_chunk_key(const ChunkKey &chunk_key)
ChunkKey get_table_key(const ChunkKey &key)
Definition: types.h:58
std::string show_chunk(const ChunkKey &key)
Definition: types.h:99
void eraseDataWrapper(const ChunkKey &key) override
void getChunkMetadataVecFromDataWrapper(ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix)
void getCachedMetadataVecForKeyPrefix(ChunkMetadataVector &, const ChunkKey &) const
bool createDataWrapperIfNotExists(const ChunkKey &chunk_key) override
bool has_table_prefix(const ChunkKey &key)
Definition: types.h:49
bool fragment_maps_to_leaf(const ChunkKey &key)
bool is_shardable_key(const ChunkKey &key)
void cacheMetadataVec(const ChunkMetadataVector &)
void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix) override
#define CHECK(condition)
Definition: Logger.h:223
bool hasCachedMetadataForKeyPrefix(const ChunkKey &) const

+ Here is the call graph for this function:

void foreign_storage::CachingForeignStorageMgr::getChunkMetadataVecFromDataWrapper ( ChunkMetadataVector chunk_metadata,
const ChunkKey chunk_key_prefix 
)

Definition at line 169 of file CachingForeignStorageMgr.cpp.

References CHECK, foreign_storage::ForeignStorageCache::checkpoint(), clearTable(), disk_cache_, get_table_prefix(), foreign_storage::ForeignStorageMgr::getChunkMetadataVecForKeyPrefix(), foreign_storage::ForeignStorageMgr::getDataWrapper(), has_table_prefix(), foreign_storage::is_table_enabled_on_node(), and foreign_storage::ForeignStorageCache::storeDataWrapper().

Referenced by getChunkMetadataVecForKeyPrefix(), refreshAppendTableInCache(), and refreshNonAppendTableInCache().

171  {
172  CHECK(has_table_prefix(chunk_key_prefix));
173  auto [db_id, tb_id] = get_table_prefix(chunk_key_prefix);
174  try {
175  ForeignStorageMgr::getChunkMetadataVecForKeyPrefix(chunk_metadata, chunk_key_prefix);
176  } catch (...) {
177  clearTable({db_id, tb_id});
178  throw;
179  }
180  // If the table was disabled then we will have no wrapper to serialize.
181  if (is_table_enabled_on_node(chunk_key_prefix)) {
182  auto doc = getDataWrapper(chunk_key_prefix)->getSerializedDataWrapper();
183  disk_cache_->storeDataWrapper(doc, db_id, tb_id);
184 
185  // If the wrapper populated buffers we want that action to be checkpointed.
186  disk_cache_->checkpoint(db_id, tb_id);
187  }
188 }
std::shared_ptr< ForeignDataWrapper > getDataWrapper(const ChunkKey &chunk_key) const
void storeDataWrapper(const std::string &doc, int32_t db_id, int32_t tb_id)
bool is_table_enabled_on_node(const ChunkKey &key)
bool has_table_prefix(const ChunkKey &key)
Definition: types.h:49
void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix) override
std::pair< int, int > get_table_prefix(const ChunkKey &key)
Definition: types.h:63
void checkpoint(const int32_t db_id, const int32_t tb_id)
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int foreign_storage::CachingForeignStorageMgr::getHighestCachedFragId ( const ChunkKey table_key)
private

Definition at line 240 of file CachingForeignStorageMgr.cpp.

References CHUNK_KEY_FRAGMENT_IDX, disk_cache_, foreign_storage::ForeignStorageCache::getCachedMetadataVecForKeyPrefix(), and foreign_storage::ForeignStorageCache::hasCachedMetadataForKeyPrefix().

Referenced by refreshAppendTableInCache().

240  {
241  // Determine last fragment ID
242  int last_frag_id = 0;
243  if (disk_cache_->hasCachedMetadataForKeyPrefix(table_key)) {
244  ChunkMetadataVector cached_metadata;
245  disk_cache_->getCachedMetadataVecForKeyPrefix(cached_metadata, table_key);
246  for (const auto& [key, metadata] : cached_metadata) {
247  last_frag_id = std::max(last_frag_id, key[CHUNK_KEY_FRAGMENT_IDX]);
248  }
249  }
250  return last_frag_id;
251 }
#define CHUNK_KEY_FRAGMENT_IDX
Definition: types.h:42
void getCachedMetadataVecForKeyPrefix(ChunkMetadataVector &, const ChunkKey &) const
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
bool hasCachedMetadataForKeyPrefix(const ChunkKey &) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::set< ChunkKey > foreign_storage::CachingForeignStorageMgr::getOptionalKeysWithinSizeLimit ( const ChunkKey chunk_key,
const std::set< ChunkKey, decltype(set_comp)* > &  same_fragment_keys,
const std::set< ChunkKey, decltype(set_comp)* > &  diff_fragment_keys 
) const
overrideprivatevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 397 of file CachingForeignStorageMgr.cpp.

References CHUNK_KEY_DB_IDX, foreign_storage::get_column_key_set(), getBufferSize(), getRequiredBuffersSize(), and maxFetchSize().

400  {
401  std::set<ChunkKey> optional_keys;
402  auto total_chunk_size = getRequiredBuffersSize(chunk_key);
403  auto max_size = maxFetchSize(chunk_key[CHUNK_KEY_DB_IDX]);
404  // Add keys to the list of optional keys starting with the same fragment. If we run out
405  // of space, then exit early with what we have added so far.
406  for (const auto& keys : {same_fragment_keys, diff_fragment_keys}) {
407  for (const auto& key : keys) {
408  auto column_keys = get_column_key_set(key);
409  for (const auto& column_key : column_keys) {
410  total_chunk_size += getBufferSize(column_key);
411  }
412  // Early exist if we exceed the size limit.
413  if (total_chunk_size > max_size) {
414  return optional_keys;
415  }
416  for (const auto& column_key : column_keys) {
417  optional_keys.emplace(column_key);
418  }
419  }
420  }
421  return optional_keys;
422 }
size_t getBufferSize(const ChunkKey &key) const
#define CHUNK_KEY_DB_IDX
Definition: types.h:39
size_t maxFetchSize(int32_t db_id) const override
std::set< ChunkKey > get_column_key_set(const ChunkKey &destination_chunk_key)
size_t getRequiredBuffersSize(const ChunkKey &chunk_key) const

+ Here is the call graph for this function:

size_t foreign_storage::CachingForeignStorageMgr::getRequiredBuffersSize ( const ChunkKey chunk_key) const
private

Definition at line 388 of file CachingForeignStorageMgr.cpp.

References foreign_storage::get_column_key_set(), and getBufferSize().

Referenced by fetchBuffer(), and getOptionalKeysWithinSizeLimit().

388  {
389  auto key_set = get_column_key_set(chunk_key);
390  size_t total_size = 0U;
391  for (const auto& key : key_set) {
392  total_size += getBufferSize(key);
393  }
394  return total_size;
395 }
size_t getBufferSize(const ChunkKey &key) const
std::set< ChunkKey > get_column_key_set(const ChunkKey &destination_chunk_key)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool foreign_storage::CachingForeignStorageMgr::hasMaxFetchSize ( ) const
overrideprivatevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 384 of file CachingForeignStorageMgr.cpp.

384  {
385  return true;
386 }
size_t foreign_storage::CachingForeignStorageMgr::maxFetchSize ( int32_t  db_id) const
overrideprivatevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 380 of file CachingForeignStorageMgr.cpp.

References disk_cache_, and foreign_storage::ForeignStorageCache::getMaxChunkDataSize().

Referenced by fetchBuffer(), and getOptionalKeysWithinSizeLimit().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::populateChunkBuffersSafely ( ForeignDataWrapper data_wrapper,
ChunkToBufferMap required_buffers,
ChunkToBufferMap optional_buffers 
)
private

Definition at line 42 of file CachingForeignStorageMgr.cpp.

References CHECK_GT, foreign_storage::ForeignStorageCache::checkpoint(), disk_cache_, get_table_prefix(), foreign_storage::ForeignDataWrapper::populateChunkBuffers(), and foreign_storage::ForeignStorageMgr::updateFragmenterMetadata().

Referenced by fetchBuffer(), and refreshChunksInCacheByFragment().

45  {
46  CHECK_GT(required_buffers.size(), 0U) << "Must populate at least one buffer";
47  try {
48  ChunkSizeValidator chunk_size_validator(required_buffers.begin()->first);
49  data_wrapper.populateChunkBuffers(required_buffers, optional_buffers);
50  chunk_size_validator.validateChunkSizes(required_buffers);
51  chunk_size_validator.validateChunkSizes(optional_buffers);
52  updateFragmenterMetadata(required_buffers);
53  updateFragmenterMetadata(optional_buffers);
54  } catch (const std::runtime_error& error) {
55  // clear any partially loaded but failed chunks (there may be some
56  // fully-loaded chunks as well but they will be cleared conservatively
57  // anyways)
58  for (const auto& [chunk_key, buffer] : required_buffers) {
59  if (auto file_buffer = dynamic_cast<File_Namespace::FileBuffer*>(buffer)) {
60  file_buffer->freeChunkPages();
61  }
62  }
63  for (const auto& [chunk_key, buffer] : optional_buffers) {
64  if (auto file_buffer = dynamic_cast<File_Namespace::FileBuffer*>(buffer)) {
65  file_buffer->freeChunkPages();
66  }
67  }
68 
69  throw ForeignStorageException(error.what());
70  }
71  // All required buffers should be from the same table.
72  auto [db, tb] = get_table_prefix(required_buffers.begin()->first);
73  disk_cache_->checkpoint(db, tb);
74 }
#define CHECK_GT(x, y)
Definition: Logger.h:235
void updateFragmenterMetadata(const ChunkToBufferMap &) const
std::pair< int, int > get_table_prefix(const ChunkKey &key)
Definition: types.h:63
void checkpoint(const int32_t db_id, const int32_t tb_id)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::refreshAppendTableInCache ( const ChunkKey table_key,
const std::vector< ChunkKey > &  old_chunk_keys 
)
private

Definition at line 253 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageCache::cacheMetadataWithFragIdGreaterOrEqualTo(), CHECK, disk_cache_, getChunkMetadataVecFromDataWrapper(), getHighestCachedFragId(), is_table_key(), and refreshChunksInCacheByFragment().

Referenced by refreshTableInCache().

255  {
256  CHECK(is_table_key(table_key));
257  int last_frag_id = getHighestCachedFragId(table_key);
258 
259  ChunkMetadataVector storage_metadata;
260  getChunkMetadataVecFromDataWrapper(storage_metadata, table_key);
261  try {
262  disk_cache_->cacheMetadataWithFragIdGreaterOrEqualTo(storage_metadata, last_frag_id);
263  refreshChunksInCacheByFragment(old_chunk_keys, last_frag_id);
264  } catch (std::runtime_error& e) {
266  }
267 }
bool is_table_key(const ChunkKey &key)
Definition: types.h:45
void getChunkMetadataVecFromDataWrapper(ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix)
void refreshChunksInCacheByFragment(const std::vector< ChunkKey > &old_chunk_keys, int last_frag_id)
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
void cacheMetadataWithFragIdGreaterOrEqualTo(const ChunkMetadataVector &metadata_vec, const int frag_id)
#define CHECK(condition)
Definition: Logger.h:223
int getHighestCachedFragId(const ChunkKey &table_key)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::refreshChunksInCacheByFragment ( const std::vector< ChunkKey > &  old_chunk_keys,
int  last_frag_id 
)
private

Definition at line 285 of file CachingForeignStorageMgr.cpp.

References CHECK, CHUNK_KEY_COLUMN_IDX, CHUNK_KEY_DB_IDX, CHUNK_KEY_FRAGMENT_IDX, CHUNK_KEY_TABLE_IDX, disk_cache_, get_table_key(), foreign_storage::ForeignStorageCache::getCachedChunkIfExists(), foreign_storage::ForeignStorageCache::getChunkBuffersForCaching(), foreign_storage::ForeignStorageMgr::getDataWrapper(), is_varlen_data_key(), is_varlen_key(), foreign_storage::ForeignStorageCache::isMetadataCached(), LOG, foreign_storage::anonymous_namespace{CachingForeignStorageMgr.cpp}::MAX_REFRESH_TIME_IN_SECONDS, populateChunkBuffersSafely(), and logger::WARNING.

Referenced by refreshAppendTableInCache(), and refreshNonAppendTableInCache().

287  {
288  int64_t total_time{0};
289  auto fragment_refresh_start_time = std::chrono::high_resolution_clock::now();
290 
291  if (old_chunk_keys.empty()) {
292  return;
293  }
294  // Iterate through previously cached chunks and re-cache them. Caching is
295  // done one fragment at a time, for all applicable chunks in the fragment.
296  ChunkToBufferMap optional_buffers;
297  std::set<ChunkKey> chunk_keys_to_be_cached;
298  auto fragment_id = old_chunk_keys[0][CHUNK_KEY_FRAGMENT_IDX];
299  const ChunkKey table_key{get_table_key(old_chunk_keys[0])};
300  std::set<ChunkKey> chunk_keys_in_fragment;
301  for (const auto& chunk_key : old_chunk_keys) {
302  CHECK(chunk_key[CHUNK_KEY_TABLE_IDX] == table_key[CHUNK_KEY_TABLE_IDX]);
303  if (chunk_key[CHUNK_KEY_FRAGMENT_IDX] < start_frag_id) {
304  continue;
305  }
306  if (disk_cache_->isMetadataCached(chunk_key)) {
307  if (chunk_key[CHUNK_KEY_FRAGMENT_IDX] != fragment_id) {
308  if (chunk_keys_in_fragment.size() > 0) {
309  auto required_buffers =
310  disk_cache_->getChunkBuffersForCaching(chunk_keys_in_fragment);
312  *getDataWrapper(table_key), required_buffers, optional_buffers);
313  chunk_keys_in_fragment.clear();
314  }
315  // At this point, cache buffers for refreshable chunks in the last fragment
316  // have been populated. Exit if the max refresh time has been exceeded.
317  // Otherwise, move to the next fragment.
318  auto current_time = std::chrono::high_resolution_clock::now();
319  total_time += std::chrono::duration_cast<std::chrono::seconds>(
320  current_time - fragment_refresh_start_time)
321  .count();
322  if (total_time >= MAX_REFRESH_TIME_IN_SECONDS) {
323  LOG(WARNING) << "Refresh time exceeded for table key: { " << table_key[0]
324  << ", " << table_key[1] << " } after fragment id: " << fragment_id;
325  break;
326  } else {
327  fragment_refresh_start_time = std::chrono::high_resolution_clock::now();
328  }
329  fragment_id = chunk_key[CHUNK_KEY_FRAGMENT_IDX];
330  }
331  // Key may have been cached during scan
332  if (disk_cache_->getCachedChunkIfExists(chunk_key) == nullptr) {
333  if (is_varlen_key(chunk_key)) {
334  CHECK(is_varlen_data_key(chunk_key));
335  ChunkKey index_chunk_key{chunk_key[CHUNK_KEY_DB_IDX],
336  chunk_key[CHUNK_KEY_TABLE_IDX],
337  chunk_key[CHUNK_KEY_COLUMN_IDX],
338  chunk_key[CHUNK_KEY_FRAGMENT_IDX],
339  2};
340  chunk_keys_in_fragment.emplace(index_chunk_key);
341  chunk_keys_to_be_cached.emplace(index_chunk_key);
342  }
343  chunk_keys_in_fragment.emplace(chunk_key);
344  chunk_keys_to_be_cached.emplace(chunk_key);
345  }
346  }
347  }
348  if (chunk_keys_in_fragment.size() > 0) {
349  auto required_buffers =
350  disk_cache_->getChunkBuffersForCaching(chunk_keys_in_fragment);
352  *getDataWrapper(table_key), required_buffers, optional_buffers);
353  }
354 }
std::vector< int > ChunkKey
Definition: types.h:37
bool isMetadataCached(const ChunkKey &) const
bool is_varlen_data_key(const ChunkKey &key)
Definition: types.h:76
std::shared_ptr< ForeignDataWrapper > getDataWrapper(const ChunkKey &chunk_key) const
#define LOG(tag)
Definition: Logger.h:217
#define CHUNK_KEY_DB_IDX
Definition: types.h:39
#define CHUNK_KEY_FRAGMENT_IDX
Definition: types.h:42
std::map< ChunkKey, AbstractBuffer * > ChunkToBufferMap
ChunkKey get_table_key(const ChunkKey &key)
Definition: types.h:58
#define CHUNK_KEY_TABLE_IDX
Definition: types.h:40
void populateChunkBuffersSafely(ForeignDataWrapper &data_wrapper, ChunkToBufferMap &required_buffers, ChunkToBufferMap &optional_buffers)
ChunkToBufferMap getChunkBuffersForCaching(const std::set< ChunkKey > &chunk_keys) const
#define CHECK(condition)
Definition: Logger.h:223
File_Namespace::FileBuffer * getCachedChunkIfExists(const ChunkKey &)
#define CHUNK_KEY_COLUMN_IDX
Definition: types.h:41
bool is_varlen_key(const ChunkKey &key)
Definition: types.h:72

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::refreshNonAppendTableInCache ( const ChunkKey table_key,
const std::vector< ChunkKey > &  old_chunk_keys 
)
private

Definition at line 269 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageCache::cacheMetadataVec(), CHECK, clearTable(), disk_cache_, getChunkMetadataVecFromDataWrapper(), is_table_key(), and refreshChunksInCacheByFragment().

Referenced by refreshTableInCache().

271  {
272  CHECK(is_table_key(table_key));
273  ChunkMetadataVector storage_metadata;
274  clearTable(table_key);
275  getChunkMetadataVecFromDataWrapper(storage_metadata, table_key);
276 
277  try {
278  disk_cache_->cacheMetadataVec(storage_metadata);
279  refreshChunksInCacheByFragment(old_chunk_keys, 0);
280  } catch (std::runtime_error& e) {
282  }
283 }
bool is_table_key(const ChunkKey &key)
Definition: types.h:45
void getChunkMetadataVecFromDataWrapper(ChunkMetadataVector &chunk_metadata, const ChunkKey &chunk_key_prefix)
void refreshChunksInCacheByFragment(const std::vector< ChunkKey > &old_chunk_keys, int last_frag_id)
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata >>> ChunkMetadataVector
void cacheMetadataVec(const ChunkMetadataVector &)
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::refreshTable ( const ChunkKey table_key,
const bool  evict_cached_entries 
)
overridevirtual

Reimplemented from foreign_storage::ForeignStorageMgr.

Definition at line 190 of file CachingForeignStorageMgr.cpp.

References CHECK, foreign_storage::ForeignStorageMgr::checkIfS3NeedsToBeEnabled(), clearTable(), foreign_storage::ForeignStorageMgr::clearTempChunkBufferMapEntriesForTable(), is_table_key(), and refreshTableInCache().

191  {
192  CHECK(is_table_key(table_key));
195  if (evict_cached_entries) {
196  clearTable(table_key);
197  } else {
198  refreshTableInCache(table_key);
199  }
200 }
bool is_table_key(const ChunkKey &key)
Definition: types.h:45
static void checkIfS3NeedsToBeEnabled(const ChunkKey &chunk_key)
void refreshTableInCache(const ChunkKey &table_key)
#define CHECK(condition)
Definition: Logger.h:223
void clearTempChunkBufferMapEntriesForTable(const ChunkKey &table_key)

+ Here is the call graph for this function:

void foreign_storage::CachingForeignStorageMgr::refreshTableInCache ( const ChunkKey table_key)
private

Definition at line 202 of file CachingForeignStorageMgr.cpp.

References CHECK, disk_cache_, foreign_storage::fragment_maps_to_leaf(), foreign_storage::ForeignStorageCache::getCachedChunksForKeyPrefix(), foreign_storage::is_append_table_chunk_key(), foreign_storage::is_shardable_key(), is_table_key(), refreshAppendTableInCache(), refreshNonAppendTableInCache(), and show_chunk().

Referenced by refreshTable().

202  {
203  CHECK(is_table_key(table_key));
204 
205  // Preserve the list of which chunks were cached per table to refresh after clear.
206  std::vector<ChunkKey> old_chunk_keys =
208 
209  // Assert all data in cache is mapped to this leaf node in distributed.
210  if (is_shardable_key(table_key)) {
211  for (auto& key : old_chunk_keys) {
212  CHECK(fragment_maps_to_leaf(key)) << show_chunk(key);
213  }
214  }
215 
216  auto append_mode = is_append_table_chunk_key(table_key);
217 
218  append_mode ? refreshAppendTableInCache(table_key, old_chunk_keys)
219  : refreshNonAppendTableInCache(table_key, old_chunk_keys);
220 }
void refreshAppendTableInCache(const ChunkKey &table_key, const std::vector< ChunkKey > &old_chunk_keys)
bool is_table_key(const ChunkKey &key)
Definition: types.h:45
bool is_append_table_chunk_key(const ChunkKey &chunk_key)
std::string show_chunk(const ChunkKey &key)
Definition: types.h:99
void refreshNonAppendTableInCache(const ChunkKey &table_key, const std::vector< ChunkKey > &old_chunk_keys)
bool fragment_maps_to_leaf(const ChunkKey &key)
bool is_shardable_key(const ChunkKey &key)
std::vector< ChunkKey > getCachedChunksForKeyPrefix(const ChunkKey &) const
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void foreign_storage::CachingForeignStorageMgr::removeTableRelatedDS ( const int  db_id,
const int  table_id 
)
override

Definition at line 375 of file CachingForeignStorageMgr.cpp.

References foreign_storage::ForeignStorageCache::clearForTablePrefix(), disk_cache_, and foreign_storage::ForeignStorageMgr::removeTableRelatedDS().

375  {
376  disk_cache_->clearForTablePrefix({db_id, table_id});
378 }
void removeTableRelatedDS(const int db_id, const int table_id) override

+ Here is the call graph for this function:

Member Data Documentation


The documentation for this class was generated from the following files: