1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-12-13 23:02:14 +03:00

Finished initial cut of the Cache class

This commit is contained in:
Patrick LeBlanc
2019-03-07 16:14:21 -06:00
parent df6675db01
commit 0626b30c88
9 changed files with 67 additions and 27 deletions

View File

@@ -103,22 +103,26 @@ void Cache::read(const vector<string> &keys)
else else
// not in the cache, put it in the list to download // not in the cache, put it in the list to download
keysToFetch.push_back(&key); keysToFetch.push_back(&key);
} }
// TODO: get the sizes of the objects to download and make space
// For now using an estimate
makeSpace(keys.size() * objectSize);
s.unlock(); s.unlock();
// start downloading the keys to fetch // start downloading the keys to fetch
int dl_err; int dl_err;
vector<int> dl_errnos; vector<int> dl_errnos;
vector<size_t> sizes;
if (!keysToFetch.empty()) if (!keysToFetch.empty())
dl_err = downloader.download(keysToFetch, &dl_errnos); dl_err = downloader.download(keysToFetch, &dl_errnos, &sizes);
size_t sum_sizes = 0;
for (size_t &size : sizes)
sum_sizes += size;
s.lock(); s.lock();
// do makespace() before downloading. Problem is, until the download is finished, this fcn can't tell which
// downloads it was responsible for. Need Downloader to make the call...?
makeSpace(sum_sizes);
currentCacheSize += sum_sizes;
// move all keys to the back of the LRU // move all keys to the back of the LRU
for (i = 0; i < keys.size(); i++) for (i = 0; i < keys.size(); i++)
{ {
@@ -131,7 +135,8 @@ void Cache::read(const vector<string> &keys)
else if (dl_errnos[i] == 0) // successful download else if (dl_errnos[i] == 0) // successful download
{ {
lru.push_back(keys[i]); lru.push_back(keys[i]);
m_lru.insert(M_LRU_element_t(&(lru.back()), lru.end()--)); LRU_t::iterator it = lru.end();
m_lru.insert(M_LRU_element_t(--it));
} }
else else
{ {
@@ -189,14 +194,31 @@ void Cache::exists(const vector<string> &keys, vector<bool> *out)
void Cache::newObject(const string &key, size_t size) void Cache::newObject(const string &key, size_t size)
{ {
boost::unique_lock<boost::mutex> s(lru_mutex);
assert(m_lru.find(key) == m_lru.end());
makeSpace(size);
lru.push_back(key);
LRU_t::iterator back = lru.end();
m_lru.insert(--back);
currentCacheSize += size;
} }
void Cache::deletedObject(const string &key, size_t size) void Cache::deletedObject(const string &key, size_t size)
{ {
boost::unique_lock<boost::mutex> s(lru_mutex);
M_LRU_t::iterator mit = m_lru.find(key);
assert(mit != m_lru.end());
assert(doNotEvict.find(mit->lit) == doNotEvict.end());
lru.erase(mit->lit);
m_lru.erase(mit);
currentCacheSize -= size;
} }
void Cache::setMaxCacheSize(size_t size) void Cache::setMaxCacheSize(size_t size)
{ {
if (size < maxCacheSize)
makeSpace(maxCacheSize - size);
maxCacheSize = size;
} }
// call this holding lru_mutex // call this holding lru_mutex
@@ -251,7 +273,7 @@ Cache::M_LRU_element_t::M_LRU_element_t(const string *k) : key(k)
Cache::M_LRU_element_t::M_LRU_element_t(const string &k) : key(&k) Cache::M_LRU_element_t::M_LRU_element_t(const string &k) : key(&k)
{} {}
Cache::M_LRU_element_t::M_LRU_element_t(const string *k, const LRU_t::iterator &i) : key(k), lit(i) Cache::M_LRU_element_t::M_LRU_element_t(const LRU_t::iterator &i) : key(&(*i)), lit(i)
{} {}
inline size_t Cache::KeyHasher::operator()(const M_LRU_element_t &l) const inline size_t Cache::KeyHasher::operator()(const M_LRU_element_t &l) const

View File

@@ -52,7 +52,7 @@ class Cache : public boost::noncopyable
{ {
M_LRU_element_t(const std::string &); M_LRU_element_t(const std::string &);
M_LRU_element_t(const std::string *); M_LRU_element_t(const std::string *);
M_LRU_element_t(const std::string *, const LRU_t::iterator &); M_LRU_element_t(const LRU_t::iterator &);
const std::string *key; const std::string *key;
LRU_t::iterator lit; LRU_t::iterator lit;
}; };

View File

@@ -11,7 +11,7 @@ class CloudStorage
{ {
public: public:
/* These behave like syscalls. return code -1 means an error, and errno is set */ /* These behave like syscalls. return code -1 means an error, and errno is set */
virtual int getObject(const std::string &sourceKey, const std::string &destFile) = 0; virtual int getObject(const std::string &sourceKey, const std::string &destFile, size_t *size = NULL) = 0;
virtual int putObject(const std::string &sourceFile, const std::string &destKey) = 0; virtual int putObject(const std::string &sourceFile, const std::string &destKey) = 0;
virtual void deleteObject(const std::string &key) = 0; virtual void deleteObject(const std::string &key) = 0;
virtual int copyObject(const std::string &sourceKey, const std::string &destKey) = 0; virtual int copyObject(const std::string &sourceKey, const std::string &destKey) = 0;

View File

@@ -36,9 +36,10 @@ inline boost::mutex & Downloader::getDownloadMutex()
return download_mutex; return download_mutex;
} }
int Downloader::download(const vector<const string *> &keys, vector<int> *errnos) int Downloader::download(const vector<const string *> &keys, vector<int> *errnos, vector<size_t> *sizes)
{ {
volatile uint counter = keys.size(); //volatile uint counter = keys.size();
uint counter = keys.size();
boost::condition condvar; boost::condition condvar;
boost::mutex m; boost::mutex m;
DownloadListener listener(&counter, &condvar, &m); DownloadListener listener(&counter, &condvar, &m);
@@ -71,19 +72,27 @@ int Downloader::download(const vector<const string *> &keys, vector<int> *errnos
(*iterators[i])->listeners.push_back(&listener); (*iterators[i])->listeners.push_back(&listener);
} }
} }
s.unlock();
// wait for the downloads to finish // wait for the downloads to finish
boost::unique_lock<boost::mutex> dl_lock(m); boost::unique_lock<boost::mutex> dl_lock(m);
s.unlock();
while (counter > 0) while (counter > 0)
condvar.wait(dl_lock); condvar.wait(dl_lock);
dl_lock.unlock(); dl_lock.unlock();
// remove the entries inserted by this call // remove the entries inserted by this call
sizes->resize(keys.size());
s.lock(); s.lock();
for (i = 0; i < keys.size(); i++) for (i = 0; i < keys.size(); i++)
{
if (inserted[i]) if (inserted[i])
{
(*sizes)[i] = (*iterators[i])->size;
downloads.erase(iterators[i]); downloads.erase(iterators[i]);
}
else
(*sizes)[i] = 0;
}
s.unlock(); s.unlock();
// check for errors & propagate // check for errors & propagate
@@ -113,14 +122,14 @@ inline const string & Downloader::getDownloadPath() const
} }
/* The helper fcns */ /* The helper fcns */
Downloader::Download::Download(const string *source, Downloader *dl) : key(source), dler(dl), dl_errno(0) Downloader::Download::Download(const string *source, Downloader *dl) : key(source), dler(dl), dl_errno(0), size(0)
{ {
} }
void Downloader::Download::operator()() void Downloader::Download::operator()()
{ {
CloudStorage *storage = CloudStorage::get(); CloudStorage *storage = CloudStorage::get();
int err = storage->getObject(*key, dler->getDownloadPath() + "/" + *key); int err = storage->getObject(*key, dler->getDownloadPath() + "/" + *key, &size);
if (err != 0) if (err != 0)
dl_errno = errno; dl_errno = errno;
@@ -129,7 +138,8 @@ void Downloader::Download::operator()()
listener->downloadFinished(); listener->downloadFinished();
} }
Downloader::DownloadListener::DownloadListener(volatile uint *counter, boost::condition *condvar, boost::mutex *m) : count(counter), cond(condvar), mutex(m) //Downloader::DownloadListener::DownloadListener(volatile uint *counter, boost::condition *condvar, boost::mutex *m) : count(counter), cond(condvar), mutex(m)
Downloader::DownloadListener::DownloadListener(uint *counter, boost::condition *condvar, boost::mutex *m) : count(counter), cond(condvar), mutex(m)
{ {
} }

View File

@@ -24,7 +24,7 @@ class Downloader
// returns 0 on success. If != 0, errnos will contains the errno associated with the failure // returns 0 on success. If != 0, errnos will contains the errno associated with the failure
// caller owns the memory for the strings. // caller owns the memory for the strings.
int download(const std::vector<const std::string *> &keys, std::vector<int> *errnos); int download(const std::vector<const std::string *> &keys, std::vector<int> *errnos, std::vector<size_t> *sizes);
void setDownloadPath(const std::string &path); void setDownloadPath(const std::string &path);
const std::string & getDownloadPath() const; const std::string & getDownloadPath() const;
@@ -35,10 +35,12 @@ class Downloader
class DownloadListener class DownloadListener
{ {
public: public:
DownloadListener(volatile uint *counter, boost::condition *condvar, boost::mutex *m); DownloadListener(uint *counter, boost::condition *condvar, boost::mutex *m);
//DownloadListener(volatile uint *counter, boost::condition *condvar, boost::mutex *m);
void downloadFinished(); void downloadFinished();
private: private:
volatile uint *count; uint *count;
//volatile uint *count;
boost::condition *cond; boost::condition *cond;
boost::mutex *mutex; boost::mutex *mutex;
}; };
@@ -50,6 +52,7 @@ class Downloader
Downloader *dler; Downloader *dler;
const std::string *key; const std::string *key;
int dl_errno; // to propagate errors from the download job to the caller int dl_errno; // to propagate errors from the download job to the caller
size_t size;
std::vector<DownloadListener *> listeners; std::vector<DownloadListener *> listeners;
}; };

View File

@@ -43,7 +43,7 @@ int LocalStorage::copy(const path &source, const path &dest)
{ {
boost::system::error_code err; boost::system::error_code err;
copy_file(source, dest, copy_option::fail_if_exists, err); copy_file(source, dest, copy_option::fail_if_exists, err);
if (!err) if (err)
{ {
errno = err.value(); errno = err.value();
return -1; return -1;
@@ -58,9 +58,14 @@ path operator+(const path &p1, const path &p2)
return ret; return ret;
} }
int LocalStorage::getObject(const string &source, const string &dest) int LocalStorage::getObject(const string &source, const string &dest, size_t *size)
{ {
return copy(prefix + source, dest); int ret = copy(prefix + source, dest);
if (ret)
return ret;
if (size)
*size = boost::filesystem::file_size(dest);
return ret;
} }
int LocalStorage::putObject(const string &source, const string &dest) int LocalStorage::putObject(const string &source, const string &dest)

View File

@@ -14,7 +14,7 @@ class LocalStorage : public CloudStorage
LocalStorage(); LocalStorage();
virtual ~LocalStorage(); virtual ~LocalStorage();
int getObject(const std::string &sourceKey, const std::string &destFile); int getObject(const std::string &sourceKey, const std::string &destFile, size_t *size = NULL);
int putObject(const std::string &sourceFile, const std::string &destKey); int putObject(const std::string &sourceFile, const std::string &destKey);
void deleteObject(const std::string &key); void deleteObject(const std::string &key);
int copyObject(const std::string &sourceKey, const std::string &destKey); int copyObject(const std::string &sourceKey, const std::string &destKey);

View File

@@ -14,7 +14,7 @@ S3Storage::~S3Storage()
{ {
} }
int S3Storage::getObject(const string &sourceKey, const string &destFile) int S3Storage::getObject(const string &sourceKey, const string &destFile, size_t *size)
{ {
return 0; return 0;
} }

View File

@@ -14,7 +14,7 @@ class S3Storage : public CloudStorage
S3Storage(); S3Storage();
virtual ~S3Storage(); virtual ~S3Storage();
int getObject(const std::string &sourceKey, const std::string &destFile); int getObject(const std::string &sourceKey, const std::string &destFile, size_t *size = NULL);
int putObject(const std::string &sourceFile, const std::string &destKey); int putObject(const std::string &sourceFile, const std::string &destKey);
void deleteObject(const std::string &key); void deleteObject(const std::string &key);
int copyObject(const std::string &sourceKey, const std::string &destKey); int copyObject(const std::string &sourceKey, const std::string &destKey);