by_server[dm->hostname][dm->key] = dm;
all[dm->key] = dm;
+
+ for (auto& devid : dm->devids) {
+ auto d = _get_or_create_device(devid);
+ d->daemons.insert(dm->key);
+ d->server = dm->hostname;
+ }
}
void DaemonStateIndex::_erase(const DaemonKey& dmk)
const auto to_erase = all.find(dmk);
assert(to_erase != all.end());
const auto dm = to_erase->second;
+
+ for (auto& devid : dm->devids) {
+ auto d = _get_or_create_device(devid);
+ assert(d->daemons.count(dmk));
+ d->daemons.erase(dmk);
+ if (d->daemons.empty()) {
+ _erase_device(d);
+ }
+ }
+
auto &server_collection = by_server[dm->hostname];
server_collection.erase(dm->key);
if (server_collection.empty()) {
typedef std::map<DaemonKey, DaemonStatePtr> DaemonStateCollection;
+struct DeviceState : public RefCountedObject
+{
+ std::string devid;
+ std::string server;
+ std::set<DaemonKey> daemons;
+
+ DeviceState(const std::string& n) : devid(n) {}
+};
+typedef boost::intrusive_ptr<DeviceState> DeviceStateRef;
/**
* Fuse the collection of per-daemon metadata from Ceph into
*/
class DaemonStateIndex
{
- private:
+private:
mutable RWLock lock = {"DaemonStateIndex", true, true, true};
std::map<std::string, DaemonStateCollection> by_server;
DaemonStateCollection all;
std::set<DaemonKey> updating;
+ std::map<std::string,DeviceStateRef> devices;
+
void _erase(const DaemonKey& dmk);
- public:
+ DeviceStateRef _get_or_create_device(const std::string& dev) {
+ auto p = devices.find(dev);
+ if (p != devices.end()) {
+ return p->second;
+ }
+ devices[dev] = new DeviceState(dev);
+ return devices[dev];
+ }
+ void _erase_device(DeviceStateRef d) {
+ devices.erase(d->devid);
+ }
+
+public:
DaemonStateIndex() {}
// FIXME: shouldn't really be public, maybe construct DaemonState