This is an automated email from the ASF dual-hosted git repository. bcall pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new 9b7be40 TCL: Replace RawHashTable with STL 9b7be40 is described below commit 9b7be409e61b95b73e29eca0a57e87e52b4431e3 Author: Xavier Chi <chitianha...@gmail.com> AuthorDate: Mon Nov 12 10:31:35 2018 -0600 TCL: Replace RawHashTable with STL --- include/tscore/RawHashTable.h | 382 --------------------- proxy/hdrs/HttpCompat.h | 1 - proxy/http/HttpBodyFactory.cc | 223 +++++------- proxy/http/HttpBodyFactory.h | 21 +- proxy/http/unit_tests/test_error_page_selection.cc | 27 +- src/tscore/Makefile.am | 2 - src/tscore/RawHashTable.cc | 31 -- 7 files changed, 107 insertions(+), 580 deletions(-) diff --git a/include/tscore/RawHashTable.h b/include/tscore/RawHashTable.h deleted file mode 100644 index 4d0cb51..0000000 --- a/include/tscore/RawHashTable.h +++ /dev/null @@ -1,382 +0,0 @@ -/** @file - - C++ wrapper around libts hash tables - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - @section details Details - - These C++ RawHashTables are a C++ wrapper around libts hash tables. - They expose an interface very analogous to ink_hash_table, for better - or for worse. See HashTable for a more C++-oriented hash table. - -*/ - -#pragma once - -#include "tscore/ink_apidefs.h" -#include "tscore/ink_hash_table.h" - -////////////////////////////////////////////////////////////////////////////// -// -// Constants and Type Definitions -// -////////////////////////////////////////////////////////////////////////////// - -typedef enum { - RawHashTable_KeyType_String = InkHashTableKeyType_String, - RawHashTable_KeyType_Word = InkHashTableKeyType_Word -} RawHashTable_KeyType; - -typedef InkHashTableKey RawHashTable_Key; -typedef InkHashTableValue RawHashTable_Value; -typedef InkHashTableEntry RawHashTable_Binding; -typedef InkHashTableIteratorState RawHashTable_IteratorState; - -////////////////////////////////////////////////////////////////////////////// -// -// The RawHashTable Class -// -////////////////////////////////////////////////////////////////////////////// - -class RawHashTable -{ -private: - InkHashTable *ht; - RawHashTable_KeyType key_type; - bool deallocate_values_on_destruct; - -public: - inkcoreapi RawHashTable(RawHashTable_KeyType key_type, bool deallocate_values_on_destruct = false); - virtual ~RawHashTable(); - - // - // these are the simplest accessor functions - // - - bool getValue(RawHashTable_Key key, RawHashTable_Value *value_ptr); - void setValue(RawHashTable_Key key, RawHashTable_Value value_ptr); - bool isBound(RawHashTable_Key key); - bool unbindKey(RawHashTable_Key key); - void replaceString(char *key, char *string); - - // - // these functions allow you to manipulate the (key,value) bindings directly - // - - RawHashTable_Binding *getCurrentBinding(RawHashTable_Key key); - RawHashTable_Binding *getOrCreateBinding(RawHashTable_Key key, bool *was_new = nullptr); - - void setBindingValue(RawHashTable_Binding *binding, RawHashTable_Value value); - RawHashTable_Key getKeyFromBinding(RawHashTable_Binding *binding); - RawHashTable_Value getValueFromBinding(RawHashTable_Binding *binding); - - // - // these functions allow you to iterate through RawHashTable bindings - // - - RawHashTable_Binding *firstBinding(RawHashTable_IteratorState *state_ptr); - RawHashTable_Binding *nextBinding(RawHashTable_IteratorState *state_ptr); -}; - -////////////////////////////////////////////////////////////////////////////// -// -// Inline Methods -// -////////////////////////////////////////////////////////////////////////////// - -/** - This routine gets the value associated with key. If the key has a - binding, the value is stored through value_ptr and true is returned. If - the key DOES NOT have a binding, false is returned. - -*/ -inline bool -RawHashTable::getValue(RawHashTable_Key key, RawHashTable_Value *value_ptr) -{ - int is_bound; - - is_bound = ink_hash_table_lookup(ht, (InkHashTableKey)key, (InkHashTableValue *)value_ptr); - return (is_bound ? true : false); -} - -/** - This routine sets the value associated with key to the value. If - a value is previously bound to the key, the previous value is left - dangling. The caller is responsible to freeing any previous binding - values needing freeing before calling setValue. - - If the key has a binding, the value is stored through value_ptr and - true is returned. If the key DOES NOT have a binding, false is returned. - -*/ -inline void -RawHashTable::setValue(RawHashTable_Key key, RawHashTable_Value value) -{ - ink_hash_table_insert(ht, (InkHashTableKey)key, (InkHashTableValue)value); -} - -/** - This routine sets the value associated with key to the value pointed to - by value_ptr. If a value is previously bound to the key, the previous - value is left dangling. The caller is responsible to freeing any - previous value before setValue. - - If the key has a binding, the value is stored through value_ptr and - true is returned. If the key DOES NOT have a binding, false is returned. - -*/ -inline bool -RawHashTable::isBound(RawHashTable_Key key) -{ - int status = ink_hash_table_isbound(ht, (InkHashTableKey)key); - return (status ? true : false); -} - -/** - This routine removes any association for key from the hash table. If - data was bound to key, the binding will be deleted, but the value will - not be deallocated. The caller is responsible to freeing any previous - value before unbindKey. - - @return true if the key was previously bound, false otherwise. - -*/ -inline bool -RawHashTable::unbindKey(RawHashTable_Key key) -{ - int status; - - status = ink_hash_table_delete(ht, (InkHashTableKey)key); - return (status ? true : false); -} - -/** - This rather specialized routine binds a malloc-allocated string value - to the key, freeing any previous value. The key must be a string, - and the hash table must have been constructed as having key_type - RawHashTable_KeyType_String. - -*/ -inline void -RawHashTable::replaceString(char *key, char *string) -{ - // if (key_type != RawHashTable_KeyType_String) - // { - // throw BadKeyType(); - // } - - ink_hash_table_replace_string(ht, key, string); -} - -/** - This function looks up a binding for key in the hash table, and returns - a pointer to the binding data structure directly inside the hash table, - or NULL if there is no binding. - -*/ -inline RawHashTable_Binding * -RawHashTable::getCurrentBinding(RawHashTable_Key key) -{ - InkHashTableEntry *he_ptr; - - he_ptr = ink_hash_table_lookup_entry(ht, (InkHashTableKey)key); - return ((RawHashTable_Binding *)he_ptr); -} - -/** - This function looks up a binding for key in the hash table, creates - a binding if one doesn't exist, and returns a pointer to the binding - data structure directly inside the hash table. - - If was_new is not NULL, true is stored through was_new. If no binding - previously existed, false is stored through was_new if a binding - previously existed. - -*/ -inline RawHashTable_Binding * -RawHashTable::getOrCreateBinding(RawHashTable_Key key, bool *was_new) -{ - int _was_new; - InkHashTableEntry *he_ptr; - - he_ptr = ink_hash_table_get_entry(ht, (InkHashTableKey)key, &_was_new); - *was_new = (_was_new ? true : false); - return ((RawHashTable_Binding *)he_ptr); -} - -/** - This function looks up a binding for key in the hash table, creates - a binding if one doesn't exist, and returns a pointer to the binding - data structure directly inside the hash table. - - If was_new is not NULL, true is stored through was_new. If no binding - previously existed, false is stored through was_new if a binding - previously existed. - -*/ -inline void -RawHashTable::setBindingValue(RawHashTable_Binding *binding, RawHashTable_Value value) -{ - ink_hash_table_set_entry(ht, (InkHashTableEntry *)binding, (InkHashTableValue)value); -} - -/** - This function takes a binding and extracts the key. - -*/ -inline RawHashTable_Key -RawHashTable::getKeyFromBinding(RawHashTable_Binding *binding) -{ - InkHashTableKey ht_key; - - ht_key = ink_hash_table_entry_key(ht, (InkHashTableEntry *)binding); - return ((RawHashTable_Key)ht_key); -} - -/** - This function takes a binding and extracts the value. - -*/ -inline RawHashTable_Value -RawHashTable::getValueFromBinding(RawHashTable_Binding *binding) -{ - InkHashTableValue ht_value; - - ht_value = ink_hash_table_entry_value(ht, (InkHashTableEntry *)binding); - return ((RawHashTable_Value)ht_value); -} - -/** - This function takes a hash table, initializes an interator data - structure to point to the first binding in the hash table, and returns - the first binding, or NULL if there are none. - -*/ -inline RawHashTable_Binding * -RawHashTable::firstBinding(RawHashTable_IteratorState *state_ptr) -{ - InkHashTableEntry *he_ptr; - - he_ptr = ink_hash_table_iterator_first(ht, (InkHashTableIteratorState *)state_ptr); - return ((RawHashTable_Binding *)he_ptr); -} - -inline RawHashTable::RawHashTable(RawHashTable_KeyType akey_type, bool adeallocate_values_on_destruct) -{ - RawHashTable::key_type = akey_type; - RawHashTable::deallocate_values_on_destruct = adeallocate_values_on_destruct; - ht = ink_hash_table_create((InkHashTableKeyType)key_type); -} - -inline RawHashTable::~RawHashTable() -{ - if (deallocate_values_on_destruct) { - ink_hash_table_destroy_and_free_values(ht); - } else { - ink_hash_table_destroy(ht); - } -} - -/** - This function takes a hash table and a pointer to iterator state, - and advances to the next binding in the hash table, if any. If there - in a next binding, a pointer to the binding is returned, else NULL. - -*/ -inline RawHashTable_Binding * -RawHashTable::nextBinding(RawHashTable_IteratorState *state_ptr) -{ - InkHashTableEntry *he_ptr; - - he_ptr = ink_hash_table_iterator_next(ht, (InkHashTableIteratorState *)state_ptr); - return ((RawHashTable_Binding *)he_ptr); -} - -////////////////////////////////////////////////////////////////////////////// -// -// The RawHashTableIter Class -// -////////////////////////////////////////////////////////////////////////////// - -class RawHashTableIter -{ -public: - RawHashTableIter(RawHashTable &ht); - ~RawHashTableIter(); - - RawHashTable_Value &operator++(); // get next - RawHashTable_Value &operator()() const; // get current - operator const void *() const; // is valid - - RawHashTable_Value &value() const; // get current value - const char *key() const; // get current key - -private: - RawHashTable &m_ht; - RawHashTable_Binding *m_currentBinding; - RawHashTable_IteratorState m_hashIterState; -}; - -////////////////////////////////////////////////////////////////////////////// -// -// Inline Methods -// -////////////////////////////////////////////////////////////////////////////// - -inline RawHashTable_Value & -RawHashTableIter::operator()() const -{ - return (m_currentBinding->clientData); -} - -inline RawHashTable_Value & -RawHashTableIter::operator++() -{ - m_currentBinding = m_ht.nextBinding(&m_hashIterState); - return (m_currentBinding->clientData); -} - -inline RawHashTableIter::operator const void *() const -{ - return ((m_currentBinding != nullptr) ? this : nullptr); -} - -inline RawHashTable_Value & -RawHashTableIter::value() const -{ - return (m_currentBinding->clientData); -} - -inline const char * -RawHashTableIter::key() const -{ - return (m_currentBinding->key.string); -} - -inline RawHashTableIter::RawHashTableIter(RawHashTable &ht) : m_ht(ht), m_currentBinding(nullptr) -{ - m_currentBinding = m_ht.firstBinding(&m_hashIterState); - return; -} - -inline RawHashTableIter::~RawHashTableIter() -{ - return; -} diff --git a/proxy/hdrs/HttpCompat.h b/proxy/hdrs/HttpCompat.h index 3bf0dc3..8c23799 100644 --- a/proxy/hdrs/HttpCompat.h +++ b/proxy/hdrs/HttpCompat.h @@ -25,7 +25,6 @@ #include "tscore/ink_string++.h" #include "MIME.h" -#include "tscore/RawHashTable.h" #include "tscore/Diags.h" class HttpCompat diff --git a/proxy/http/HttpBodyFactory.cc b/proxy/http/HttpBodyFactory.cc index 53edaa6..9d5433b 100644 --- a/proxy/http/HttpBodyFactory.cc +++ b/proxy/http/HttpBodyFactory.cc @@ -190,50 +190,29 @@ HttpBodyFactory::fabricate_with_old_api(const char *type, HttpTransact::State *c } unlock(); - return (buffer); + return buffer; } void HttpBodyFactory::dump_template_tables(FILE *fp) { - RawHashTable *h1, *h2; - RawHashTable_Key k1, k2; - RawHashTable_Value v1, v2; - RawHashTable_Binding *b1, *b2; - RawHashTable_IteratorState i1, i2; - HttpBodySet *body_set; - lock(); - - h1 = table_of_sets; - - if (h1 != nullptr) { - /////////////////////////////////////////// - // loop over set->body-types hash table // - /////////////////////////////////////////// - - for (b1 = h1->firstBinding(&i1); b1 != nullptr; b1 = h1->nextBinding(&i1)) { - k1 = table_of_sets->getKeyFromBinding(b1); - v1 = table_of_sets->getValueFromBinding(b1); - body_set = (HttpBodySet *)v1; - - if (body_set != nullptr) { - fprintf(fp, "set %s: name '%s', lang '%s', charset '%s'\n", k1, body_set->set_name, body_set->content_language, - body_set->content_charset); + if (table_of_sets) { + for (const auto &it1 : *table_of_sets.get()) { + HttpBodySet *body_set = static_cast<HttpBodySet *>(it1.second); + if (body_set) { + fprintf(fp, "set %s: name '%s', lang '%s', charset '%s'\n", it1.first.c_str(), body_set->set_name, + body_set->content_language, body_set->content_charset); /////////////////////////////////////////// // loop over body-types->body hash table // /////////////////////////////////////////// ink_assert(body_set->is_sane()); - h2 = body_set->table_of_pages; - - for (b2 = h2->firstBinding(&i2); b2 != nullptr; b2 = h2->nextBinding(&i2)) { - k2 = table_of_sets->getKeyFromBinding(b2); - v2 = table_of_sets->getValueFromBinding(b2); - HttpBodyTemplate *t = (HttpBodyTemplate *)v2; - - fprintf(fp, " %-30s: %" PRId64 " bytes\n", k2, t->byte_count); + if (body_set->table_of_pages) { + for (const auto &it2 : *body_set->table_of_pages.get()) { + fprintf(fp, " %-30s: %" PRId64 " bytes\n", it2.first.c_str(), it2.second->byte_count); + } } } } @@ -254,7 +233,7 @@ config_callback(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UN { HttpBodyFactory *body_factory = (HttpBodyFactory *)cookie; body_factory->reconfigure(); - return (0); + return 0; } void @@ -372,7 +351,7 @@ HttpBodyFactory::HttpBodyFactory() HttpBodyFactory::~HttpBodyFactory() { // FIX: need to implement destructor - delete table_of_sets; + table_of_sets.reset(nullptr); } // LOCKING: must be called with lock taken @@ -457,13 +436,12 @@ const char * HttpBodyFactory::determine_set_by_host(HttpTransact::State *context) { const char *set; - RawHashTable_Value v; int host_len = context->hh_info.host_len; char host_buffer[host_len + 1]; strncpy(host_buffer, context->hh_info.request_host, host_len); host_buffer[host_len] = '\0'; - if (table_of_sets->getValue((RawHashTable_Key)host_buffer, &v)) { - set = table_of_sets->getKeyFromBinding(table_of_sets->getCurrentBinding((RawHashTable_Key)host_buffer)); + if (auto it = table_of_sets->find(host_buffer); it != table_of_sets->end()) { + set = it->first.c_str(); } else { set = "default"; } @@ -471,8 +449,9 @@ HttpBodyFactory::determine_set_by_host(HttpTransact::State *context) } const char * -HttpBodyFactory::determine_set_by_language(RawHashTable *table_of_sets, StrList *acpt_language_list, StrList *acpt_charset_list, - float *Q_best_ptr, int *La_best_ptr, int *Lc_best_ptr, int *I_best_ptr) +HttpBodyFactory::determine_set_by_language(std::unique_ptr<BodySetTable> &table_of_sets, StrList *acpt_language_list, + StrList *acpt_charset_list, float *Q_best_ptr, int *La_best_ptr, int *Lc_best_ptr, + int *I_best_ptr) { float Q, Ql, Qc, Q_best; int I, Idummy, I_best; @@ -480,13 +459,6 @@ HttpBodyFactory::determine_set_by_language(RawHashTable *table_of_sets, StrList int is_the_default_set; const char *set_best; - RawHashTable_Key k1; - RawHashTable_Value v1; - RawHashTable_Binding *b1; - RawHashTable_IteratorState i1; - RawHashTable *table_of_pages; - HttpBodySetRawData *body_set; - set_best = "default"; Q_best = 0.00001; La_best = 0; @@ -506,20 +478,15 @@ HttpBodyFactory::determine_set_by_language(RawHashTable *table_of_sets, StrList goto done; } - if (table_of_sets != nullptr) { + if (table_of_sets) { /////////////////////////////////////////// // loop over set->body-types hash table // /////////////////////////////////////////// + for (const auto &it : *table_of_sets.get()) { + const char *set_name = it.first.c_str(); + HttpBodySetRawData *body_set = it.second; - for (b1 = table_of_sets->firstBinding(&i1); b1 != nullptr; b1 = table_of_sets->nextBinding(&i1)) { - k1 = table_of_sets->getKeyFromBinding(b1); - v1 = table_of_sets->getValueFromBinding(b1); - const char *set_name = (const char *)k1; - - body_set = (HttpBodySetRawData *)v1; - table_of_pages = body_set->table_of_pages; - - if ((set_name == nullptr) || (table_of_pages == nullptr)) { + if ((it.first.empty()) || (body_set->table_of_pages == nullptr)) { continue; } @@ -635,7 +602,7 @@ done: *La_best_ptr = La_best; *Lc_best_ptr = Lc_best; *I_best_ptr = I_best; - return (set_best); + return set_best; } // LOCKING: must be called with lock taken @@ -648,46 +615,42 @@ HttpBodyFactory::determine_set_by_language(StrList *acpt_language_list, StrList set_best = determine_set_by_language(table_of_sets, acpt_language_list, acpt_charset_list, &Q_best, &La_best, &Lc_best, &I_best); - return (set_best); + return set_best; } // LOCKING: must be called with lock taken HttpBodyTemplate * HttpBodyFactory::find_template(const char *set, const char *type, HttpBodySet **body_set_return) { - RawHashTable_Value v; - Debug("body_factory", "calling find_template(%s,%s)", set, type); *body_set_return = nullptr; - if (table_of_sets == nullptr) { - return (nullptr); + if (table_of_sets == nullptr || !set || !type) { + return nullptr; } - if (table_of_sets->getValue((RawHashTable_Key)set, &v)) { - HttpBodySet *body_set = (HttpBodySet *)v; - RawHashTable *table_of_types = body_set->table_of_pages; - - if (table_of_types == nullptr) { - return (nullptr); + if (auto it = table_of_sets->find(set); it != table_of_sets->end()) { + HttpBodySet *body_set = static_cast<HttpBodySet *>(it->second); + if (body_set->table_of_pages == nullptr) { + return nullptr; } - if (table_of_types->getValue((RawHashTable_Key)type, &v)) { - HttpBodyTemplate *t = (HttpBodyTemplate *)v; + if (auto it_page = body_set->table_of_pages->find(type); it_page != body_set->table_of_pages->end()) { + HttpBodyTemplate *t = it_page->second; if ((t == nullptr) || (!t->is_sane())) { - return (nullptr); + return nullptr; } *body_set_return = body_set; Debug("body_factory", "find_template(%s,%s) -> (file %s, length %" PRId64 ", lang '%s', charset '%s')", set, type, t->template_pathname, t->byte_count, body_set->content_language, body_set->content_charset); - return (t); + return t; } } Debug("body_factory", "find_template(%s,%s) -> NULL", set, type); - return (nullptr); + return nullptr; } // LOCKING: must be called with lock taken @@ -705,17 +668,17 @@ HttpBodyFactory::is_response_suppressed(HttpTransact::State *context) } else */ if (response_suppression_mode == 0) { - return (false); + return false; } else if (response_suppression_mode == 1) { - return (true); + return true; } else if (response_suppression_mode == 2) { if (context->req_flavor == HttpTransact::REQ_FLAVOR_INTERCEPTED) { - return (true); + return true; } else { - return (false); + return false; } } else { - return (false); + return false; } } @@ -723,69 +686,43 @@ HttpBodyFactory::is_response_suppressed(HttpTransact::State *context) void HttpBodyFactory::nuke_template_tables() { - RawHashTable *h1, *h2; - RawHashTable_Value v1, v2; - RawHashTable_Binding *b1, *b2; - RawHashTable_IteratorState i1, i2; - HttpBodySet *body_set; - HttpBodyTemplate *hbt; - - h1 = table_of_sets; - - if (h1) { + if (table_of_sets) { Debug("body_factory", "deleting pre-existing template tables"); } else { Debug("body_factory", "no pre-existing template tables"); } - if (h1 != nullptr) { + if (table_of_sets) { /////////////////////////////////////////// // loop over set->body-types hash table // /////////////////////////////////////////// - - for (b1 = h1->firstBinding(&i1); b1 != nullptr; b1 = h1->nextBinding(&i1)) { - v1 = h1->getValueFromBinding(b1); - - body_set = (HttpBodySet *)v1; + for (const auto &it : *table_of_sets.get()) { + HttpBodySet *body_set = static_cast<HttpBodySet *>(it.second); ink_assert(body_set->is_sane()); - h2 = body_set->table_of_pages; - - if (h2 != nullptr) { - body_set->table_of_pages = nullptr; - + if (body_set->table_of_pages) { /////////////////////////////////////////// // loop over body-types->body hash table // /////////////////////////////////////////// - - for (b2 = h2->firstBinding(&i2); b2 != nullptr; b2 = h2->nextBinding(&i2)) { - v2 = h2->getValueFromBinding(b2); - if (v2) { - // need a cast here - hbt = (HttpBodyTemplate *)v2; - delete hbt; - } + for (const auto &it_page : *body_set->table_of_pages.get()) { + delete it_page.second; } - - delete h2; + body_set->table_of_pages.reset(nullptr); } - delete body_set; } - delete h1; + table_of_sets.reset(nullptr); } - - table_of_sets = nullptr; } // LOCKING: must be called with lock taken -RawHashTable * +std::unique_ptr<HttpBodyFactory::BodySetTable> HttpBodyFactory::load_sets_from_directory(char *set_dir) { DIR *dir; struct dirent *dirEntry; - RawHashTable *new_table_of_sets; + std::unique_ptr<HttpBodyFactory::BodySetTable> new_table_of_sets; if (set_dir == nullptr) { - return (nullptr); + return nullptr; } Debug("body_factory", "load_sets_from_directory(%s)", set_dir); @@ -798,10 +735,10 @@ HttpBodyFactory::load_sets_from_directory(char *set_dir) if (dir == nullptr) { Warning("can't open response template directory '%s' (%s)", set_dir, (strerror(errno) ? strerror(errno) : "unknown reason")); Warning("no response templates --- using default error pages"); - return (nullptr); + return nullptr; } - new_table_of_sets = new RawHashTable(RawHashTable_KeyType_String); + new_table_of_sets.reset(new HttpBodyFactory::BodySetTable); ////////////////////////////////////////// // loop over each language subdirectory // @@ -837,13 +774,13 @@ HttpBodyFactory::load_sets_from_directory(char *set_dir) HttpBodySet *body_set = load_body_set_from_directory(dirEntry->d_name, subdir); if (body_set != nullptr) { Debug("body_factory", " %s -> %p", dirEntry->d_name, body_set); - new_table_of_sets->setValue((RawHashTable_Key)(dirEntry->d_name), (RawHashTable_Value)body_set); + new_table_of_sets->emplace(dirEntry->d_name, body_set); } } closedir(dir); - return (new_table_of_sets); + return new_table_of_sets; } // LOCKING: must be called with lock taken @@ -931,7 +868,7 @@ HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir) } closedir(dir); - return (body_set); + return body_set; } //////////////////////////////////////////////////////////////////////// @@ -956,9 +893,7 @@ HttpBodySet::~HttpBodySet() ats_free(set_name); ats_free(content_language); ats_free(content_charset); - if (table_of_pages) { - delete table_of_pages; - } + table_of_pages.reset(nullptr); } int @@ -972,15 +907,11 @@ HttpBodySet::init(char *set, char *dir) ink_filepath_make(info_path, sizeof(info_path), dir, ".body_factory_info"); fd = open(info_path, O_RDONLY); if (fd < 0) { - return (-1); + return -1; } this->set_name = ats_strdup(set); - - if (this->table_of_pages) { - delete (this->table_of_pages); - } - this->table_of_pages = new RawHashTable(RawHashTable_KeyType_String); + this->table_of_pages.reset(new TemplateTable); lineno = 0; @@ -1079,37 +1010,37 @@ HttpBodySet::init(char *set, char *dir) } close(fd); - return (lines_added); + return lines_added; } HttpBodyTemplate * HttpBodySet::get_template_by_name(const char *name) { - RawHashTable_Value v; - Debug("body_factory", " calling get_template_by_name(%s)", name); if (table_of_pages == nullptr) { - return (nullptr); + return nullptr; } - if (table_of_pages->getValue((RawHashTable_Key)name, &v)) { - HttpBodyTemplate *t = (HttpBodyTemplate *)v; + if (auto it = table_of_pages->find(name); it != table_of_pages->end()) { + HttpBodyTemplate *t = it->second; if ((t == nullptr) || (!t->is_sane())) { - return (nullptr); + return nullptr; } Debug("body_factory", " get_template_by_name(%s) -> (file %s, length %" PRId64 ")", name, t->template_pathname, t->byte_count); - return (t); + return t; } Debug("body_factory", " get_template_by_name(%s) -> NULL", name); - return (nullptr); + return nullptr; } void HttpBodySet::set_template_by_name(const char *name, HttpBodyTemplate *t) { - table_of_pages->setValue((RawHashTable_Key)name, (RawHashTable_Value)t); + if (name) { + table_of_pages->emplace(name, t); + } } //////////////////////////////////////////////////////////////////////// @@ -1158,10 +1089,10 @@ HttpBodyTemplate::load_from_file(char *dir, char *file) // coverity[fs_check_call] status = stat(path, &stat_buf); if (status != 0) { - return (0); + return 0; } if (!S_ISREG(stat_buf.st_mode)) { - return (0); + return 0; } /////////////////// @@ -1171,7 +1102,7 @@ HttpBodyTemplate::load_from_file(char *dir, char *file) // coverity[toctou] fd = open(path, O_RDONLY); if (fd < 0) { - return (0); + return 0; } //////////////////////////////////////// @@ -1192,7 +1123,7 @@ HttpBodyTemplate::load_from_file(char *dir, char *file) Warning("reading template file '%s', got %" PRId64 " bytes instead of %" PRId64 " (%s)", path, bytes_read, new_byte_count, (strerror(errno) ? strerror(errno) : "unknown error")); ats_free(new_template_buffer); - return (0); + return 0; } Debug("body_factory", " read %" PRId64 " bytes from '%s'", new_byte_count, path); @@ -1206,7 +1137,7 @@ HttpBodyTemplate::load_from_file(char *dir, char *file) byte_count = new_byte_count; template_pathname = ats_strdup(path); - return (1); + return 1; } char * @@ -1224,5 +1155,5 @@ HttpBodyTemplate::build_instantiated_buffer(HttpTransact::State *context, int64_ Debug("body_factory_instantiation", " after instantiation: [%s]", buffer); Debug("body_factory", " returning %" PRId64 " byte instantiated buffer", *buflen_return); - return (buffer); + return buffer; } diff --git a/proxy/http/HttpBodyFactory.h b/proxy/http/HttpBodyFactory.h index 5d78fb4..165b240 100644 --- a/proxy/http/HttpBodyFactory.h +++ b/proxy/http/HttpBodyFactory.h @@ -61,9 +61,11 @@ #include "HttpConfig.h" #include "HttpCompat.h" #include "HttpTransact.h" -#include "tscore/RawHashTable.h" #include "tscore/ink_sprintf.h" +#include <memory> +#include <unordered_map> + #define HTTP_BODY_TEMPLATE_MAGIC 0xB0DFAC00 #define HTTP_BODY_SET_MAGIC 0xB0DFAC55 #define HTTP_BODY_FACTORY_MAGIC 0xB0DFACFF @@ -109,11 +111,12 @@ public: //////////////////////////////////////////////////////////////////////// struct HttpBodySetRawData { - unsigned int magic = 0; + using TemplateTable = std::unordered_map<std::string, HttpBodyTemplate *>; + unsigned int magic = 0; char *set_name; char *content_language; char *content_charset; - RawHashTable *table_of_pages; + std::unique_ptr<TemplateTable> table_of_pages; }; //////////////////////////////////////////////////////////////////////// @@ -162,6 +165,7 @@ public: class HttpBodyFactory { public: + using BodySetTable = std::unordered_map<std::string, HttpBodySetRawData *>; HttpBodyFactory(); ~HttpBodyFactory(); @@ -197,8 +201,9 @@ public: void dump_template_tables(FILE *fp = stderr); void reconfigure(); - static const char *determine_set_by_language(RawHashTable *table_of_sets, StrList *acpt_language_list, StrList *acpt_charset_list, - float *Q_best_ptr, int *La_best_ptr, int *Lc_best_ptr, int *I_best_ptr); + static const char *determine_set_by_language(std::unique_ptr<BodySetTable> &table_of_sets, StrList *acpt_language_list, + StrList *acpt_charset_list, float *Q_best_ptr, int *La_best_ptr, int *Lc_best_ptr, + int *I_best_ptr); private: char *fabricate(StrList *acpt_language_list, StrList *acpt_charset_list, const char *type, HttpTransact::State *context, @@ -225,7 +230,7 @@ private: // initialization methods // //////////////////////////// void nuke_template_tables(); - RawHashTable *load_sets_from_directory(char *set_dir); + std::unique_ptr<BodySetTable> load_sets_from_directory(char *set_dir); HttpBodySet *load_body_set_from_directory(char *set_name, char *tmpl_dir); ///////////////////////////////////////////////// @@ -254,6 +259,6 @@ private: //////////////////// unsigned int magic = HTTP_BODY_FACTORY_MAGIC; // magic for sanity checks/debugging ink_mutex mutex; // prevents reconfig/read races - bool callbacks_established = false; // all config variables present - RawHashTable *table_of_sets = nullptr; // sets of template hash tables + bool callbacks_established = false; // all config variables present + std::unique_ptr<BodySetTable> table_of_sets; // sets of template hash tables }; diff --git a/proxy/http/unit_tests/test_error_page_selection.cc b/proxy/http/unit_tests/test_error_page_selection.cc index 483c8e2..004aff5 100644 --- a/proxy/http/unit_tests/test_error_page_selection.cc +++ b/proxy/http/unit_tests/test_error_page_selection.cc @@ -74,16 +74,16 @@ TEST_CASE("error page selection test", "[http]") int nsets = sizeof(sets) / sizeof(sets[0]); int ntests = sizeof(tests) / sizeof(tests[0]); // (1) build fake hash table of sets - RawHashTable *table_of_sets = new RawHashTable(RawHashTable_KeyType_String); + std::unique_ptr<HttpBodyFactory::BodySetTable> table_of_sets; + table_of_sets.reset(new HttpBodyFactory::BodySetTable); for (i = 0; i < nsets; i++) { - HttpBodySetRawData *body_set; - body_set = (HttpBodySetRawData *)ats_malloc(sizeof(HttpBodySetRawData)); - body_set->magic = 0; - body_set->set_name = (char *)(sets[i].set_name); - body_set->content_language = (char *)(sets[i].content_language); - body_set->content_charset = (char *)(sets[i].content_charset); - body_set->table_of_pages = (RawHashTable *)1; // hack --- can't be NULL - table_of_sets->setValue((RawHashTable_Key)(body_set->set_name), (RawHashTable_Value)body_set); + HttpBodySetRawData *body_set = new HttpBodySetRawData; + body_set->magic = 0; + body_set->set_name = strdup(sets[i].set_name); + body_set->content_language = strdup(sets[i].content_language); + body_set->content_charset = strdup(sets[i].content_charset); + body_set->table_of_pages.reset(new HttpBodySetRawData::TemplateTable); + table_of_sets->emplace(body_set->set_name, body_set); } // (2) for each test, parse accept headers into lists, and test matching for (i = 0; i < ntests; i++) { @@ -104,5 +104,12 @@ TEST_CASE("error page selection test", "[http]") REQUIRE(La_best == tests[i].expected_La); REQUIRE(I_best == tests[i].expected_I); } - delete table_of_sets; + for (const auto &it : *table_of_sets.get()) { + ats_free(it.second->set_name); + ats_free(it.second->content_language); + ats_free(it.second->content_charset); + it.second->table_of_pages.reset(nullptr); + delete it.second; + } + table_of_sets.reset(nullptr); } diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am index 8c3c9f9..0ab5015 100644 --- a/src/tscore/Makefile.am +++ b/src/tscore/Makefile.am @@ -183,8 +183,6 @@ libtscore_la_SOURCES = \ ParseRules.h \ PriorityQueue.h \ Ptr.h \ - RawHashTable.cc \ - RawHashTable.h \ RbTree.cc \ RbTree.h \ Regex.cc \ diff --git a/src/tscore/RawHashTable.cc b/src/tscore/RawHashTable.cc deleted file mode 100644 index 7bfdaa1..0000000 --- a/src/tscore/RawHashTable.cc +++ /dev/null @@ -1,31 +0,0 @@ -/** @file - - C++ wrapper around libts hash tables - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - @section details Details - - These C++ RawHashTables are a C++ wrapper around libts hash tables. - They expose an interface very analogous to ink_hash_table, for better - or for worse. See HashTable for a more C++-oriented hash table. - -*/ - -#include "tscore/RawHashTable.h"