Loading src/http.cpp +29 −39 Changes for src/http.cpp: 29 added lines, 39 removed lines. Original line number Diff line number Diff line Loading @@ -3191,57 +3191,36 @@ libhttppp::HttpHeader::HeaderData * libhttppp::HttpHeader::HeaderData::nextHeade } libhttppp::HttpHeader::HeaderData *libhttppp::HttpHeader::getHeaderData(const std ::string &key) const{ HeaderData *curdat =_firstHeaderData.get(); while(curdat){ if(curdat->_Key==key){ return curdat; } curdat=curdat->_nextHeaderData.get(); } return nullptr; auto it = _index.find(key); return (it != _index.end()) ? it->second : nullptr; } libhttppp::HttpHeader::HeaderData * libhttppp::HttpHeader::setHeaderData(const std ::string &key){ HeaderData *curdat =_firstHeaderData.get(); if(!curdat){ _firstHeaderData=std::make_unique<HeaderData>(key); _lastHeaderData=_firstHeaderData.get(); curdat=_lastHeaderData; }else{ while(curdat){ if(curdat->_Key==key){ auto it = _index.find(key); if (it != _index.end()) { HeaderData *curdat = it->second; curdat->clear(); curdat->_Key = key; break; } curdat=curdat->_nextHeaderData.get(); } if(!curdat){ _lastHeaderData->_nextHeaderData=std::make_unique<HeaderData>(key); _lastHeaderData=_lastHeaderData->_nextHeaderData.get(); curdat=_lastHeaderData; } } return curdat; } void libhttppp::HttpHeader::deldata(const std::string& key){ std::unique_ptr<HeaderData>* link = &_firstHeaderData; while (link && link->get()) { HeaderData* node = link->get(); if (node->_Key == key) { // unlink *link = std::move(node->_nextHeaderData); std::unique_ptr<HeaderData> node = std::make_unique<HeaderData>(key); HeaderData *curdat = node.get(); if (!_firstHeaderData) { _firstHeaderData = std::move(node); _lastHeaderData = _firstHeaderData.get(); while (_lastHeaderData && _lastHeaderData->_nextHeaderData) } else { _lastHeaderData->_nextHeaderData = std::move(node); _lastHeaderData = _lastHeaderData->_nextHeaderData.get(); continue; } link = &node->_nextHeaderData; _index[key] = curdat; return curdat; } if (!_firstHeaderData) _lastHeaderData = nullptr; void libhttppp::HttpHeader::deldata(const std::string& key){ auto it = _index.find(key); if (it != _index.end()) deldata(it->second); } Loading @@ -3259,6 +3238,16 @@ void libhttppp::HttpHeader::deldata(libhttppp::HttpHeader::HeaderData* pos){ while (_lastHeaderData && _lastHeaderData->_nextHeaderData) _lastHeaderData = _lastHeaderData->_nextHeaderData.get(); if (!_firstHeaderData) _lastHeaderData = nullptr; // Remove whichever index entry (if any) points at this node. Erase by // value rather than by pos->_Key: setHeaderData()'s found-existing path // can reassign _Key without touching the index, so they aren't guaranteed // to match in the (already-quirky, pre-existing) case of a caller reusing // the same key string with different casing across calls. for (auto idxIt = _index.begin(); idxIt != _index.end(); ) { if (idxIt->second == pos) idxIt = _index.erase(idxIt); else ++idxIt; } } Loading @@ -3285,6 +3274,7 @@ size_t libhttppp::HttpHeader::getHeaderSize(){ void libhttppp::HttpHeader::clear(){ _firstHeaderData.reset(); _lastHeaderData=nullptr; _index.clear(); } void libhttppp::HttpHeader::HeaderData::erase(int /*pos*/){ Loading src/http.h +12 −0 Changes for src/http.h: 12 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory> #include <deque> #include <map> #include <unordered_map> #include <chrono> #include <netplus/socket.h> Loading Loading @@ -325,6 +326,17 @@ namespace libhttppp { virtual ~HttpHeader()=default; std::unique_ptr<HeaderData> _firstHeaderData; HeaderData *_lastHeaderData; private: // O(1)-average lookup by key, keyed exactly like the old linear scan // compared (raw key string, case-sensitive -- callers already always // pass pre-lowercased keys; HeaderData's own ctor separately lowercases // _Key for storage). The linked list above remains the source of truth // for iteration order and node lifetime/address stability (HeaderData* // handed out to callers, e.g. HttpResponse's cached _ContentLength etc., // must stay valid -- nodes are never moved, only the index pointing at // them changes), this is purely a lookup accelerator kept in sync by // setHeaderData()/deldata()/clear(). std::unordered_map<std::string, HeaderData*> _index; }; class HttpResponse : public HttpHeader,public netplus::con { Loading Loading
src/http.cpp +29 −39 Changes for src/http.cpp: 29 added lines, 39 removed lines. Original line number Diff line number Diff line Loading @@ -3191,57 +3191,36 @@ libhttppp::HttpHeader::HeaderData * libhttppp::HttpHeader::HeaderData::nextHeade } libhttppp::HttpHeader::HeaderData *libhttppp::HttpHeader::getHeaderData(const std ::string &key) const{ HeaderData *curdat =_firstHeaderData.get(); while(curdat){ if(curdat->_Key==key){ return curdat; } curdat=curdat->_nextHeaderData.get(); } return nullptr; auto it = _index.find(key); return (it != _index.end()) ? it->second : nullptr; } libhttppp::HttpHeader::HeaderData * libhttppp::HttpHeader::setHeaderData(const std ::string &key){ HeaderData *curdat =_firstHeaderData.get(); if(!curdat){ _firstHeaderData=std::make_unique<HeaderData>(key); _lastHeaderData=_firstHeaderData.get(); curdat=_lastHeaderData; }else{ while(curdat){ if(curdat->_Key==key){ auto it = _index.find(key); if (it != _index.end()) { HeaderData *curdat = it->second; curdat->clear(); curdat->_Key = key; break; } curdat=curdat->_nextHeaderData.get(); } if(!curdat){ _lastHeaderData->_nextHeaderData=std::make_unique<HeaderData>(key); _lastHeaderData=_lastHeaderData->_nextHeaderData.get(); curdat=_lastHeaderData; } } return curdat; } void libhttppp::HttpHeader::deldata(const std::string& key){ std::unique_ptr<HeaderData>* link = &_firstHeaderData; while (link && link->get()) { HeaderData* node = link->get(); if (node->_Key == key) { // unlink *link = std::move(node->_nextHeaderData); std::unique_ptr<HeaderData> node = std::make_unique<HeaderData>(key); HeaderData *curdat = node.get(); if (!_firstHeaderData) { _firstHeaderData = std::move(node); _lastHeaderData = _firstHeaderData.get(); while (_lastHeaderData && _lastHeaderData->_nextHeaderData) } else { _lastHeaderData->_nextHeaderData = std::move(node); _lastHeaderData = _lastHeaderData->_nextHeaderData.get(); continue; } link = &node->_nextHeaderData; _index[key] = curdat; return curdat; } if (!_firstHeaderData) _lastHeaderData = nullptr; void libhttppp::HttpHeader::deldata(const std::string& key){ auto it = _index.find(key); if (it != _index.end()) deldata(it->second); } Loading @@ -3259,6 +3238,16 @@ void libhttppp::HttpHeader::deldata(libhttppp::HttpHeader::HeaderData* pos){ while (_lastHeaderData && _lastHeaderData->_nextHeaderData) _lastHeaderData = _lastHeaderData->_nextHeaderData.get(); if (!_firstHeaderData) _lastHeaderData = nullptr; // Remove whichever index entry (if any) points at this node. Erase by // value rather than by pos->_Key: setHeaderData()'s found-existing path // can reassign _Key without touching the index, so they aren't guaranteed // to match in the (already-quirky, pre-existing) case of a caller reusing // the same key string with different casing across calls. for (auto idxIt = _index.begin(); idxIt != _index.end(); ) { if (idxIt->second == pos) idxIt = _index.erase(idxIt); else ++idxIt; } } Loading @@ -3285,6 +3274,7 @@ size_t libhttppp::HttpHeader::getHeaderSize(){ void libhttppp::HttpHeader::clear(){ _firstHeaderData.reset(); _lastHeaderData=nullptr; _index.clear(); } void libhttppp::HttpHeader::HeaderData::erase(int /*pos*/){ Loading
src/http.h +12 −0 Changes for src/http.h: 12 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory> #include <deque> #include <map> #include <unordered_map> #include <chrono> #include <netplus/socket.h> Loading Loading @@ -325,6 +326,17 @@ namespace libhttppp { virtual ~HttpHeader()=default; std::unique_ptr<HeaderData> _firstHeaderData; HeaderData *_lastHeaderData; private: // O(1)-average lookup by key, keyed exactly like the old linear scan // compared (raw key string, case-sensitive -- callers already always // pass pre-lowercased keys; HeaderData's own ctor separately lowercases // _Key for storage). The linked list above remains the source of truth // for iteration order and node lifetime/address stability (HeaderData* // handed out to callers, e.g. HttpResponse's cached _ContentLength etc., // must stay valid -- nodes are never moved, only the index pointing at // them changes), this is purely a lookup accelerator kept in sync by // setHeaderData()/deldata()/clear(). std::unordered_map<std::string, HeaderData*> _index; }; class HttpResponse : public HttpHeader,public netplus::con { Loading