Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions include/iocore/hostdb/HostDBProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,17 +497,6 @@ class HostDBRecord : public RefCountObj
/// The index of @a target in this record.
int index_of(HostDBInfo const *target) const;

/** Allocation and initialize an instance from a serialized buffer.
*
* @param buff Serialization data.
* @param size Size of @a buff.
* @return An instance initialized from @a buff.
*/
static self_type *unmarshall(char *buff, unsigned size);

/// Database version.
static constexpr ts::VersionNumber Version{3, 0};

protected:
/// Current active info.
/// @note This value may be out of range due to the difficulty of synchronization, therefore
Expand Down
22 changes: 3 additions & 19 deletions src/iocore/hostdb/HostDB.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ HostDBCache::start(int flags)
}

// Setup the ref-counted cache (this must be done regardless of syncing or not).
this->refcountcache = new RefCountCache<HostDBRecord>(hostdb_partitions, hostdb_max_size, hostdb_max_count, HostDBRecord::Version,
"proxy.process.hostdb.cache.");
this->pending_dns = new Queue<HostDBContinuation, Continuation::Link_link>[hostdb_partitions];
this->refcountcache =
new RefCountCache<HostDBRecord>(hostdb_partitions, hostdb_max_size, hostdb_max_count, "proxy.process.hostdb.cache.");
this->pending_dns = new Queue<HostDBContinuation, Continuation::Link_link>[hostdb_partitions];
this->remoteHostDBQueue = new Queue<HostDBContinuation, Continuation::Link_link>[hostdb_partitions];
return 0;
}
Expand Down Expand Up @@ -1573,22 +1573,6 @@ HostDBRecord::alloc(TextView query_name, unsigned int rr_count, size_t srv_name_
return self;
}

HostDBRecord::self_type *
HostDBRecord::unmarshall(char *buff, unsigned size)
{
if (size < sizeof(self_type)) {
return nullptr;
}
auto src = reinterpret_cast<self_type *>(buff);
ink_release_assert(size == src->_record_size);
auto ptr = ioBufAllocator[src->_iobuffer_index].alloc_void();
auto self = static_cast<self_type *>(ptr);
new (self) self_type();
auto delta = sizeof(RefCountObj); // skip the VFTP and ref count.
memcpy(static_cast<std::byte *>(ptr) + delta, buff + delta, size - delta);
return self;
}

bool
HostDBRecord::serve_stale_but_revalidate() const
{
Expand Down
88 changes: 3 additions & 85 deletions src/iocore/hostdb/P_RefCountCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,24 +360,10 @@ RefCountCachePartition<C>::get_map()
return this->item_map;
}

// The header for the cache, this is used to check if the serialized cache is compatible
class RefCountCacheHeader
{
public:
unsigned int magic = REFCOUNTCACHE_MAGIC_NUMBER;
ts::VersionNumber version{REFCOUNTCACHE_VERSION};
ts::VersionNumber object_version; // version passed in of whatever it is we are caching

RefCountCacheHeader(ts::VersionNumber object_version = ts::VersionNumber());
bool operator==(RefCountCacheHeader const &that) const;
bool compatible(RefCountCacheHeader *that) const;
};

// RefCountCache is a ref-counted key->value map to store classes that inherit from RefCountObj.
// Once an item is `put` into the cache, the cache will maintain a Ptr<> to that object until erase
// or clear is called-- which will remove the cache's Ptr<> to the object.
//
// This cache may be Persisted (RefCountCacheSync) as well as loaded from disk (LoadRefCountCacheFromPath).
// This class will optionally emit metrics at the given `metrics_prefix`.
//
// Note: although this cache does allow you to set expiry times this cache does not actively GC itself-- meaning
Expand All @@ -391,8 +377,7 @@ template <class C> class RefCountCache
{
public:
// Constructor
RefCountCache(unsigned int num_partitions, int size = -1, int items = -1, ts::VersionNumber object_version = ts::VersionNumber(),
const std::string &metrics_prefix = ".refcountcache");
RefCountCache(unsigned int num_partitions, int size = -1, int items = -1, const std::string &metrics_prefix = ".refcountcache");
// Destructor
~RefCountCache();

Expand All @@ -408,23 +393,18 @@ template <class C> class RefCountCache
size_t partition_count() const;
RefCountCachePartition<C> &get_partition(int pnum);
size_t count() const;
RefCountCacheHeader &get_header();
RefCountCacheBlock *get_rsb();

private:
int max_size; // Total size
int max_items; // Total number of items allowed
unsigned int num_partitions;
std::vector<std::unique_ptr<RefCountCachePartition<C>>> partitions;
// Header
RefCountCacheHeader header; // Our header
RefCountCacheBlock rsb;
RefCountCacheBlock rsb;
};

template <class C>
RefCountCache<C>::RefCountCache(unsigned int num_partitions, int size, int items, ts::VersionNumber object_version,
const std::string &metrics_prefix)
: header(RefCountCacheHeader(object_version))
RefCountCache<C>::RefCountCache(unsigned int num_partitions, int size, int items, const std::string &metrics_prefix)
{
this->max_size = size;
this->max_items = items;
Expand Down Expand Up @@ -476,13 +456,6 @@ RefCountCache<C>::partition_for_key(uint64_t key)
return key % this->num_partitions;
}

template <class C>
RefCountCacheHeader &
RefCountCache<C>::get_header()
{
return this->header;
}

template <class C>
ts::shared_mutex &
RefCountCache<C>::lock_for_key(uint64_t key)
Expand Down Expand Up @@ -537,58 +510,3 @@ RefCountCache<C>::clear()
this->partitions[i]->clear();
}
}

// Fill `cache` with items in file `filepath` using `load_func` to unmarshall the record.
// Errors are -1
template <typename CacheEntryType>
int
LoadRefCountCacheFromPath(RefCountCache<CacheEntryType> &cache, const std::string &filepath,
CacheEntryType *(*load_func)(char *, unsigned int))
{
// If we have no load method, then we can't load anything so lets just stop right here
if (load_func == nullptr) {
return -1; // TODO: some specific error code
}

int fd = open(filepath.c_str(), O_RDONLY);
if (fd < 0) {
Warning("Unable to open file %s; [Error]: %s", filepath.c_str(), strerror(errno));
return -1;
}

// read in the header
RefCountCacheHeader tmpHeader = RefCountCacheHeader();
int read_ret = read(fd, reinterpret_cast<char *>(&tmpHeader), sizeof(RefCountCacheHeader));
if (read_ret != sizeof(RefCountCacheHeader)) {
UnixSocket{fd}.close();
Warning("Error reading cache header from disk (expected %ld): %d", sizeof(RefCountCacheHeader), read_ret);
return -1;
}
if (!cache.get_header().compatible(&tmpHeader)) {
UnixSocket{fd}.close();
Warning("Incompatible cache at %s, not loading.", filepath.c_str());
return -1; // TODO: specific code for incompatible
}

RefCountCacheItemMeta tmpValue = RefCountCacheItemMeta(0, 0);
while (true) { // TODO: better loop
read_ret = read(fd, reinterpret_cast<char *>(&tmpValue), sizeof(tmpValue));
if (read_ret != sizeof(tmpValue)) {
break;
}
char buf[tmpValue.size];
read_ret = read(fd, reinterpret_cast<char *>(&buf), tmpValue.size);
if (read_ret != static_cast<int>(tmpValue.size)) {
Warning("Encountered error reading item from cache: %d", read_ret);
break;
}

CacheEntryType *newItem = load_func(reinterpret_cast<char *>(&buf), tmpValue.size);
if (newItem != nullptr) {
cache.put(tmpValue.key, newItem, tmpValue.size - sizeof(CacheEntryType));
}
};

UnixSocket{fd}.close();
return 0;
}
14 changes: 0 additions & 14 deletions src/iocore/hostdb/RefCountCache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,3 @@ RefCountCacheHashEntry::dealloc(RefCountCacheHashEntry *e)
{
return refCountCacheHashingValueAllocator.free(e);
}

RefCountCacheHeader::RefCountCacheHeader(ts::VersionNumber object_version) : object_version(object_version){};

bool
RefCountCacheHeader::operator==(RefCountCacheHeader const &that) const
{
return this->magic == that.magic && this->version == that.version;
}

bool
RefCountCacheHeader::compatible(RefCountCacheHeader *that) const
{
return this->magic == that->magic && this->version == that->version && this->object_version == that->version;
};
16 changes: 0 additions & 16 deletions src/iocore/hostdb/test_RefCountCache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,6 @@ class ExampleStruct : public RefCountObj
items_freed.insert(this);
printf("freeing: %p items_freed.size(): %zu\n", this, items_freed.size());
}

static ExampleStruct *
unmarshall(char *buf, unsigned int size)
{
if (size < sizeof(ExampleStruct)) {
return nullptr;
}
ExampleStruct *ret = ExampleStruct::alloc(size - sizeof(ExampleStruct));
memcpy(static_cast<void *>(ret), buf, size);
// Reset the refcount back to 0, this is a bit ugly-- but I'm not sure we want to expose a method
// to mess with the refcount, since this is a fairly unique use case
ret = new (ret) ExampleStruct();
return ret;
}
};

std::set<ExampleStruct *> ExampleStruct::items_freed;
Expand Down Expand Up @@ -216,8 +202,6 @@ test()
auto cache = std::make_unique<RefCountCache<ExampleStruct>>(cachePartitions);
printf("Created...\n");

LoadRefCountCacheFromPath<ExampleStruct>(*cache, "/tmp/hostdb_cache", ExampleStruct::unmarshall);
printf("Cache started...\n");
int numTestEntries = 10000;

// See if anything persisted across the restart
Expand Down