]> granicus.if.org Git - icinga2/blob - base/objectmap.h
2411d542e391a1b0d9ffe14f5957078f77b497ca
[icinga2] / base / objectmap.h
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef OBJECTMAP_H
21 #define OBJECTMAP_H
22
23 namespace icinga
24 {
25
26 template<typename TKey = string, typename TValue = Object::Ptr>
27 class ObjectMap : public Object
28 {
29 public:
30         typedef shared_ptr<ObjectMap<TKey, TValue> > Ptr;
31         typedef weak_ptr<ObjectMap<TKey, TValue > > WeakPtr;
32
33         typedef typename multimap<TKey, TValue>::iterator Iterator;
34         typedef pair<Iterator, Iterator> Range;
35
36         ObjectMap(const typename ObjectSet<TValue>::Ptr& parent,
37             function<bool (const TValue&, TKey *key)> keygetter)
38                 : m_Parent(parent), m_KeyGetter(keygetter)
39         { 
40                 assert(m_Parent);
41                 assert(m_KeyGetter);
42         }
43
44         void Start(void)
45         {
46                 m_Parent->OnObjectAdded += bind_weak(&ObjectMap::ObjectAddedHandler, shared_from_this());
47                 m_Parent->OnObjectCommitted += bind_weak(&ObjectMap::ObjectCommittedHandler, shared_from_this());
48                 m_Parent->OnObjectRemoved += bind_weak(&ObjectMap::ObjectRemovedHandler, shared_from_this());
49
50                 for (typename ObjectSet<TValue>::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++)
51                         AddObject(*it);
52         }
53
54         Range GetRange(TKey key)
55         {
56                 return m_Objects.equal_range(key);
57         }
58
59         void ForeachObject(TKey key, function<int (const ObjectSetEventArgs<TValue>&)> callback)
60         {
61                 ObjectSetEventArgs<TValue> ea;
62                 ea.Source = shared_from_this();
63
64                 Range range = GetRange(key);
65
66                 for (Iterator it = range.first; it != range.second; it++) {
67                         ea.Target(*it);
68                         callback(ea);
69                 }
70         }
71
72 private:
73         multimap<TKey, TValue> m_Objects;
74         typename ObjectSet<TValue>::Ptr m_Parent;
75         function<bool (const TValue&, TKey *key)> m_KeyGetter;
76
77         void AddObject(const TValue& object)
78         {
79                 TKey key;
80                 if (!m_KeyGetter(object, &key))
81                         return;
82
83                 m_Objects.insert(make_pair(key, object));
84         }
85
86         void RemoveObject(const TValue& object)
87         {
88                 TKey key;
89                 if (!m_KeyGetter(object, &key))
90                         return;
91
92                 pair<Iterator, Iterator> range = GetRange(key);
93
94                 for (Iterator i = range.first; i != range.second; i++) {
95                         if (i->second == object) {
96                                 m_Objects.erase(i);
97                                 break;
98                         }
99                 }
100         }
101
102         void CheckObject(const TValue& object)
103         {
104                 RemoveObject(object);
105                 AddObject(object);
106         }
107
108         int ObjectAddedHandler(const ObjectSetEventArgs<TValue>& ea)
109         {
110                 AddObject(ea.Target);
111
112                 return 0;
113         }
114
115         int ObjectCommittedHandler(const ObjectSetEventArgs<TValue>& ea)
116         {
117                 CheckObject(ea.Target);
118
119                 return 0;
120         }
121
122         int ObjectRemovedHandler(const ObjectSetEventArgs<TValue>& ea)
123         {
124                 RemoveObject(ea.Target);
125
126                 return 0;
127         }
128 };
129
130 }
131
132 #endif /* OBJECTMAP_H */