From 8465a069104e40de35a4a56225b26ca5ba5c74f9 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Tue, 1 May 2007 12:16:36 +0000 Subject: [PATCH] added a ValueIterator to MultiHashTable to present a limited view in result of Lookup()s. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20946 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/util/MultiHashTable.h | 74 ++++++++++++++----- headers/private/kernel/util/OpenHashTable.h | 4 +- .../kernel/network/protocols/ipv4/ipv4.cpp | 6 +- .../kernel/network/protocols/ipv4/multicast.h | 2 +- .../network/protocols/tcp/EndpointManager.cpp | 4 +- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/headers/private/kernel/util/MultiHashTable.h b/headers/private/kernel/util/MultiHashTable.h index 79df88d250..bad16dadf1 100644 --- a/headers/private/kernel/util/MultiHashTable.h +++ b/headers/private/kernel/util/MultiHashTable.h @@ -40,24 +40,6 @@ public: status_t InitCheck() const { return HashTable::InitCheck(); } - Iterator Lookup(const KeyType &key) const - { - size_t index = HashTable::fDefinition.HashKey(key) - & (HashTable::fTableSize - 1); - ValueType *slot = HashTable::fTable[index]; - - while (slot) { - if (HashTable::fDefinition.Compare(key, slot)) - break; - slot = HashTable::_Link(slot)->fNext; - } - - if (slot == NULL) - return Iterator(this, HashTable::fTableSize, NULL); - - return Iterator(this, index, slot); - } - void Insert(ValueType *value) { if (AutoExpand @@ -87,7 +69,63 @@ public: Iterator GetIterator() const { return HashTable::GetIterator(); } + class ValueIterator : protected Iterator { + public: + ValueIterator(const HashTable *table, size_t index, ValueType *value) + : fOriginalIndex(index), fOriginalValue(value) + { + Iterator::fTable = table; + Iterator::fIndex = index; + Iterator::fNext = value; + } + + bool HasNext() const + { + if (Iterator::fNext == NULL) + return false; + if (Iterator::fNext == fOriginalValue) + return true; + return ((const MultiTable *)Iterator::fTable)->_Definition().CompareValues( + fOriginalValue, Iterator::fNext); + } + + void Rewind() + { + Iterator::fIndex = fOriginalIndex; + Iterator::fNext = fOriginalValue; + } + + ValueType *Next() { return Iterator::Next(); } + + private: + size_t fOriginalIndex; + ValueType *fOriginalValue; + }; + + ValueIterator Lookup(const KeyType &key) const + { + size_t index = HashTable::fDefinition.HashKey(key) + & (HashTable::fTableSize - 1); + ValueType *slot = HashTable::fTable[index]; + + while (slot) { + if (HashTable::fDefinition.Compare(key, slot)) + break; + slot = HashTable::_Link(slot)->fNext; + } + + if (slot == NULL) + return ValueIterator(this, HashTable::fTableSize, NULL); + + return ValueIterator(this, index, slot); + } + private: + // for g++ 2.95 + friend class ValueIterator; + + const Definition &_Definition() const { return HashTable::fDefinition; } + void _Insert(ValueType **table, size_t tableSize, ValueType *value) { size_t index = HashTable::fDefinition.Hash(value) & (tableSize - 1); diff --git a/headers/private/kernel/util/OpenHashTable.h b/headers/private/kernel/util/OpenHashTable.h index b9d215ed65..3715e42a0f 100644 --- a/headers/private/kernel/util/OpenHashTable.h +++ b/headers/private/kernel/util/OpenHashTable.h @@ -207,7 +207,9 @@ public: _GetNext(); } - private: + protected: + Iterator() {} + void _GetNext() { if (fNext) diff --git a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp index 11f929cf8a..2cdbfe7a98 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp +++ b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp @@ -648,16 +648,12 @@ deliver_multicast(net_protocol_module_info *module, net_buffer *buffer, sockaddr_in *multicastAddr = (sockaddr_in *)&buffer->destination; - MulticastState::Iterator it = sMulticastState->Lookup(std::make_pair( + MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair( &multicastAddr->sin_addr, buffer->interface->index)); while (it.HasNext()) { IPv4GroupInterface *state = it.Next(); - if (state->Interface()->index != buffer->interface->index - || state->Address().s_addr != multicastAddr->sin_addr.s_addr) - break; - if (deliverToRaw && state->Parent()->Socket()->raw == NULL) continue; diff --git a/src/add-ons/kernel/network/protocols/ipv4/multicast.h b/src/add-ons/kernel/network/protocols/ipv4/multicast.h index 423381c189..2c252e46f8 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/multicast.h +++ b/src/add-ons/kernel/network/protocols/ipv4/multicast.h @@ -93,7 +93,7 @@ private: ContainedAddress *_Get(const AddressType &address) const { - AddressList::ConstIterator it = fAddresses.GetIterator(); + typename AddressList::ConstIterator it = fAddresses.GetIterator(); while (it.HasNext()) { ContainedAddress *container = it.Next(); if (container->address == address) diff --git a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp index 082e1494d1..0e63ff4095 100644 --- a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp @@ -278,12 +278,10 @@ EndpointManager::_BindToAddress(TCPEndpoint *endpoint, const sockaddr *_address) if (ntohs(port) <= kLastReservedPort && geteuid() != 0) return B_PERMISSION_DENIED; - EndpointTable::Iterator portUsers = fEndpointHash.Lookup(port); + EndpointTable::ValueIterator portUsers = fEndpointHash.Lookup(port); while (portUsers.HasNext()) { TCPEndpoint *user = portUsers.Next(); - if (user->LocalAddress().Port() != port) - break; if (user->LocalAddress().IsEmpty(false) || address.EqualTo(*user->LocalAddress(), false)) {