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
This commit is contained in:
Hugo Santos
2007-05-01 12:16:36 +00:00
parent 8aa4c7e370
commit 8465a06910
5 changed files with 62 additions and 28 deletions
+56 -18
View File
@@ -40,24 +40,6 @@ public:
status_t InitCheck() const { return HashTable::InitCheck(); } 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) void Insert(ValueType *value)
{ {
if (AutoExpand if (AutoExpand
@@ -87,7 +69,63 @@ public:
Iterator GetIterator() const { return HashTable::GetIterator(); } 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: private:
// for g++ 2.95
friend class ValueIterator;
const Definition &_Definition() const { return HashTable::fDefinition; }
void _Insert(ValueType **table, size_t tableSize, ValueType *value) void _Insert(ValueType **table, size_t tableSize, ValueType *value)
{ {
size_t index = HashTable::fDefinition.Hash(value) & (tableSize - 1); size_t index = HashTable::fDefinition.Hash(value) & (tableSize - 1);
+3 -1
View File
@@ -207,7 +207,9 @@ public:
_GetNext(); _GetNext();
} }
private: protected:
Iterator() {}
void _GetNext() void _GetNext()
{ {
if (fNext) if (fNext)
@@ -648,16 +648,12 @@ deliver_multicast(net_protocol_module_info *module, net_buffer *buffer,
sockaddr_in *multicastAddr = (sockaddr_in *)&buffer->destination; 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)); &multicastAddr->sin_addr, buffer->interface->index));
while (it.HasNext()) { while (it.HasNext()) {
IPv4GroupInterface *state = it.Next(); 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) if (deliverToRaw && state->Parent()->Socket()->raw == NULL)
continue; continue;
@@ -93,7 +93,7 @@ private:
ContainedAddress *_Get(const AddressType &address) const ContainedAddress *_Get(const AddressType &address) const
{ {
AddressList::ConstIterator it = fAddresses.GetIterator(); typename AddressList::ConstIterator it = fAddresses.GetIterator();
while (it.HasNext()) { while (it.HasNext()) {
ContainedAddress *container = it.Next(); ContainedAddress *container = it.Next();
if (container->address == address) if (container->address == address)
@@ -278,12 +278,10 @@ EndpointManager::_BindToAddress(TCPEndpoint *endpoint, const sockaddr *_address)
if (ntohs(port) <= kLastReservedPort && geteuid() != 0) if (ntohs(port) <= kLastReservedPort && geteuid() != 0)
return B_PERMISSION_DENIED; return B_PERMISSION_DENIED;
EndpointTable::Iterator portUsers = fEndpointHash.Lookup(port); EndpointTable::ValueIterator portUsers = fEndpointHash.Lookup(port);
while (portUsers.HasNext()) { while (portUsers.HasNext()) {
TCPEndpoint *user = portUsers.Next(); TCPEndpoint *user = portUsers.Next();
if (user->LocalAddress().Port() != port)
break;
if (user->LocalAddress().IsEmpty(false) if (user->LocalAddress().IsEmpty(false)
|| address.EqualTo(*user->LocalAddress(), false)) { || address.EqualTo(*user->LocalAddress(), false)) {