Github user jpeach commented on a diff in the pull request: https://github.com/apache/trafficserver/pull/653#discussion_r64931485 --- Diff: iocore/hostdb/RefCountCache.cc --- @@ -0,0 +1,145 @@ +// The goal here is to create a proof-of-concept cache struct which will cache an item +// for at least N seconds (configurable) and alloc a given amount of space for the given +// struct-- this way all of the dynamic pieces (strings, arrays, etc.) can be allocated +// within the same block. + +#include "ts/ink_platform.h" +#include "ts/I_Layout.h" +#include "P_HostDB.h" +#include "P_RefCountCache.h" +#include "P_EventSystem.h" // FIXME: need to have this in I_* header files. +#include "ts/ink_file.h" + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <unordered_map> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <cmath> + +// TODO: remove? Config? +// static const int MC_SYNC_MIN_PAUSE_TIME = HRTIME_MSECONDS(200); // Pause for at least 200ms + +void +RefCountCacheBase::sync_partitions(Continuation *cont) +{ + eventProcessor.schedule_imm(new RefCountCacheSync(cont, this), ET_CALL); +} + +int +RefCountCacheSync::copyPartition(int event, Event *e) +{ + (void)event; + if (partition >= cc->partition_count()) { + // TODO: check return + this->finalizeSync(); + cont->handleEvent(REFCOUNT_CACHE_EVENT_SYNC, 0); + Debug("multicache", "RefCountCacheSync done"); + delete this; + return EVENT_DONE; + } + Debug("hostdb", "sync partition=%d/%d", partition, cc->partition_count()); + // copy the partition into our buffer, then we'll let `pauseEvent` write it out + this->partitionItems.reserve(cc->partition_itemcount(partition)); + cc->copy_partition(partition, &this->partitionItems); + partition++; + SET_HANDLER((MCacheSyncHandler)&RefCountCacheSync::writePartition); + mutex = e->ethread->mutex; + e->schedule_imm(); + + return EVENT_CONT; +} + +int +RefCountCacheSync::writePartition(int event, Event *e) +{ + // write the partition to disk + // for item in this->partitionItems + // write to disk with headers per item + for (std::vector<Ptr<RefCountCacheItemBase>>::iterator it = this->partitionItems.begin(); it != this->partitionItems.end(); + ++it) { + // TODO: figure out a cleaner way, dereferencing and taking the ptr seems terrible! + this->outfile.write((char *)&*it->get(), sizeof(*it->get())); + // write the contents + this->outfile.write(it->get()->iobuf, it->get()->size); + } + + // Clear partition-- for the next user + this->partitionItems.clear(); + + SET_HANDLER((MCacheSyncHandler)&RefCountCacheSync::pauseEvent); + + // TODO: no sleep between partitions? + // TODO: keep track of how long it took and sleep if we were faster than expected + // TODO: figure out how to get access to hostdb_sync_frequency (probaby should be passed in instead of this global magic) + // e->schedule_in(MAX(MC_SYNC_MIN_PAUSE_TIME, HRTIME_SECONDS(hostdb_sync_frequency - 5) / MULTI_CACHE_PARTITIONS)); + // e->schedule_in(MC_SYNC_MIN_PAUSE_TIME); + e->schedule_imm(); + return EVENT_CONT; +} + +int +RefCountCacheSync::pauseEvent(int event, Event *e) +{ + (void)event; + (void)e; + + // Schedule up the next partition + if (partition < cc->partition_count()) + mutex = cc->lock_for_partition(partition); + else + mutex = cont->mutex; + SET_HANDLER((MCacheSyncHandler)&RefCountCacheSync::copyPartition); + e->schedule_imm(); + return EVENT_CONT; +} + +// Open the tmp file, etc. +int +RefCountCacheSync::initializeStorage(int event, Event *e) +{ + this->filename = this->cc->get_filepath(); + this->tmp_filename = this->filename + ".syncing"; + + this->outfile.open(this->tmp_filename.c_str(), std::ios::out | std::ios::binary); + + if (!this->outfile.is_open()) { + Warning("Unable to create temporyary file %s, unable to persist hostdb\n", this->tmp_filename.c_str()); --- End diff -- * temporary
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---