blob: dac30c7a8f49e6327eb90c1b22a3444992223260 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_MACADDR_MAP_H_
#define GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_MACADDR_MAP_H_
#include <fbl/macros.h>
#include <wlan/common/logging.h>
#include <wlan/common/macaddr.h>
#include <zircon/types.h>
#include <unordered_map>
namespace wlan {
namespace macaddr_map_type {
enum MapType : uint8_t {
kBss = 1,
};
} // namespace macaddr_map_type
template <typename V, macaddr_map_type::MapType Type> class MacAddrMap {
public:
using size_type = typename std::unordered_map<uint64_t, V>::size_type;
MacAddrMap(size_type limit = kNoLimit) : limit_(limit) {}
~MacAddrMap() { Clear(); }
V Lookup(const common::MacAddr& addr) const {
auto iter = map_.find(addr.ToU64());
if (iter == map_.end()) { return V{}; }
return (iter->second);
}
void Clear() { map_.clear(); }
bool Remove(const common::MacAddr& addr) {
auto iter = map_.find(addr.ToU64());
if (iter == map_.end()) { return false; }
iter->second.reset();
map_.erase(iter);
return true;
}
// Predicate signature is bool(V v).
template <typename Predicate> size_type RemoveIf(Predicate p) {
size_type removed = 0;
for (auto iter = begin(map_); iter != end(map_);) {
if (p(iter->second)) {
iter->second.reset();
iter = map_.erase(iter);
removed++;
} else {
iter++;
}
}
return removed;
}
// Function signature is void(V v).
template <typename Function> void ForEach(Function f) {
for (auto iter = begin(map_); iter != end(map_); iter++) {
f(iter->second);
}
}
bool IsFull() const { return limit_ != kNoLimit && Count() >= limit_; }
zx_status_t Insert(const common::MacAddr& addr, V v) {
if (IsFull()) {
debugf("[MacAddrMap-%u] Already full\n", Type);
return ZX_ERR_BAD_STATE;
}
if (Lookup(addr)) {
debugf("[MacAddrMap-%u] Duplicate insert declined for Address: %s\n", Type,
MACSTR(addr));
return ZX_ERR_ALREADY_EXISTS;
}
map_.emplace(addr.ToU64(), v);
return ZX_OK;
}
inline size_type Count() const { return map_.size(); }
static constexpr size_type kNoLimit = 0;
private:
// TODO(porce): Consider using MacAddr as key.
std::unordered_map<uint64_t, V> map_;
size_type limit_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(MacAddrMap);
};
} // namespace wlan
#endif // GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_MACADDR_MAP_H_