Lumiera  0.pre.03
»edit your freedom«
defs-registry.hpp
Go to the documentation of this file.
1 /*
2  DEFS-REGISTRY.hpp - implementation of the default object store
3 
4  Copyright (C)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
38 #ifndef LUMIERA_QUERY_DEFS_REGISTRY_H
39 #define LUMIERA_QUERY_DEFS_REGISTRY_H
40 
41 
42 #include "lib/p.hpp"
43 #include "lib/util.hpp"
44 #include "lib/util-foreach.hpp"
45 #include "lib/sync-classlock.hpp"
46 #include "lib/format-string.hpp"
47 #include "lib/query-util.hpp"
48 #include "common/query.hpp"
49 #include "lib/nocopy.hpp"
50 
51 #include <set>
52 #include <vector>
53 #include <memory>
54 
55 
56 namespace lumiera{
57 namespace query {
58 
59  using lib::P;
60  using lib::ClassLock;
61  using std::weak_ptr;
62  using std::string;
63 
64  namespace impl {
65 
66  namespace {
67  using util::_Fmt;
68 
69  uint maxSlots (0);
70  _Fmt dumpRecord ("%2i| %64s --> %s\n");
71  }
72 
73 
74  struct TableEntry
75  {
76  virtual ~TableEntry() {};
77  };
78 
81  typedef std::vector< P<TableEntry> > Table;
82 
83 
87  template<class TAR>
88  struct Record
89  {
90  QueryKey queryKey;
91  weak_ptr<TAR> objRef;
92  uint degree;
93 
94  Record (Query<TAR> const& q, P<TAR> const& obj)
95  : queryKey (q)
96  , objRef (obj)
97  , degree(queryKey.degree())
98  { }
99 
100 
101  struct Search
102  {
103  Search (P<TAR> const& obj)
104  : obj_(obj) { }
105 
106  P<TAR> const& obj_;
107 
108  bool
109  operator() (Record const& rec)
110  {
111  P<TAR> storedObj (rec.objRef.lock());
112  return storedObj && (storedObj == obj_);
113  }
114  };
115 
116  friend bool
117  operator< (Record one, Record two)
118  {
119  return one.queryKey < two.queryKey;
120  }
121 
122  operator string () const { return dumpRecord % degree % queryKey.display() % dumpObj(); }
123  string dumpObj () const { P<TAR> o (objRef.lock()); return o? string(*o):"dead"; }
124  };
125 
131  template<class TAR>
132  struct Slot
133  : public TableEntry
134  {
135  typedef std::set<Record<TAR>> Registry;
136 
137  Registry registry;
138  static size_t index;
139 
140  static Registry&
141  access (Table& table)
142  {
143  if ( !index
144  || index > table.size()
145  ||!table[index-1])
146  createSlot (table);
147 
148  ASSERT (0 < index && index<=table.size() && table[index-1]);
149  Slot* item = static_cast<Slot*> (table[index-1].get());
150  return item->registry;
151  }
152 
153  private:
154  static void
155  createSlot (Table& table)
156  {
157  ClassLock<TableEntry> guard;
158  if (!index)
159  index = ++maxSlots;
160  if (index > table.size())
161  table.resize (index);
162  table[index-1].reset(new Slot);
163  }
164  };
165 
166 
167  // static vars to organise one Table Slot per type....
168  template<class TAR>
169  size_t Slot<TAR>::index (0);
170 
171 
172 
173 
188  {
189  Table table_;
190 
191  public:
193  template<class TAR>
194  class Iter
195  {
196  friend class DefsRegistry;
197  typedef typename Slot<TAR>::Registry::iterator II;
198 
199  II p,i,e;
200  P<TAR> next, ptr;
201 
202  Iter (II from, II to)
203  : p(from), i(from), e(to)
204  {
205  if (i!=e) ++i; // p is next to be tested, i always one ahead
206  operator++ ();
207  }
208 
209  Iter (II match, II from, II to)
210  : p(match), i(from), e(to)
211  {
212  operator++ (); // init to first element (or to null if empty)
213  }
214 
215  P<TAR>
216  findNext ()
217  {
218  while (!next)
219  {
220  if (p==e) break;
221  next = p->objRef.lock();
222  p = i++;
223  }
224  return next;
225  }
226 
227 
228  public:
229  P<TAR> operator* () { return ptr; }
230  bool hasNext () { return next || findNext(); }
231  Iter& operator++ ()
232  {
233  ptr=findNext();
234  next.reset();
235  return *this;
236  }
237  };
238 
248  template<class TAR>
249  Iter<TAR>
250  candidates (Query<TAR> const& query)
251  {
252  P<TAR> dummy;
253  Record<TAR> entry (query, dummy);
254  typedef typename Slot<TAR>::Registry Registry;
255  Registry& registry = Slot<TAR>::access(table_);
256 
257  // try to get a possible direct match (same query)
258  typename Registry::iterator pos = registry.find (entry);
259  typename Registry::iterator end = registry.end();
260 
261  if (pos==end)
262  return Iter<TAR> (registry.begin(), end); // just enumerate contents
263  else
264  return Iter<TAR> (pos, registry.begin(), end); // start with direct match
265  }
266 
267 
275  template<class TAR>
276  bool
277  put (P<TAR> const& obj, Query<TAR> const& query)
278  {
279  Record<TAR> entry (query, obj);
280  typedef typename Slot<TAR>::Registry Registry;
281  typedef typename Registry::iterator RIter;
282 
283  Registry& registry = Slot<TAR>::access(table_);
284  RIter pos = registry.lower_bound (entry);
285  if ( pos!=registry.end()
286  && pos->queryKey == query)
287  {
288  P<TAR> storedObj (pos->objRef.lock());
289  if (storedObj)
290  return (storedObj == obj);
291  else
292  // use the opportunity to purge the expired entry
293  registry.erase(pos++);
294  }
295  // no existing entry....
296  registry.insert(pos, entry);
297  ENSURE (registry.find (entry) != registry.end());
298  return true;
299  }
300 
301 
305  template<class TAR>
306  bool
307  forget (P<TAR> const& obj)
308  {
309  typedef typename Slot<TAR>::Registry Registry;
310  typedef typename Record<TAR>::Search SearchFunc;
311 
312  Registry& registry = Slot<TAR>::access(table_);
313  return util::remove_if(registry, SearchFunc (obj));
314  }
315 
316 
320  template<class TAR>
321  string
322  dump ()
323  {
324  string res;
325  util::for_each ( Slot<TAR>::access(table_)
326  , [&] (Record<TAR>& entry)
327  {
328  res += string(entry);
329  }
330  );
331  return res;
332  }
333  };
334 
335 
336 
337  } // (End) impl namespace
338 
339  using impl::DefsRegistry;
340 
341 
342 }} // namespace lumiera::query
343 #endif
used for enumerating solutions
static size_t index
where to find this Slot in every Table
Utilities to support working with predicate queries.
Basic and generic representation of an internal query.
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
< Functor searching for a specific object
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Front-end for printf-style string template interpolation.
Customised refcounting smart pointer.
A front-end for using printf-style formatting.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
holding a single "default object" entry
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
every new kind of object (Type) creates a new slot in the main Table holding all registered default o...
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Iter< TAR > candidates(Query< TAR > const &query)
find a sequence of "default" objects possibly matching the query.
Wrapper for indexing and ordering.
Definition: query.hpp:388
A synchronisation protection guard employing a lock scoped to the parameter type as a whole...
ExampleStrategy::Qualifier two(string additionalArg)
definition of another qualifier two(arg), accepting an additional argument
Lumiera public interface.
Definition: advice.cpp:104
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:71
uint maxSlots(0)
number of different registered Types
string dump()
helper for diagnostics.
bool forget(P< TAR > const &obj)
if this object is registered as "default" in some way, drop the registration.
ExampleStrategy::Qualifier one()
definition of a qualifier one()
std::vector< P< TableEntry > > Table
we maintain an independent defaults registry for every participating kind of object.
Perform operations "for each element" of a collection.
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:270
bool put(P< TAR > const &obj, Query< TAR > const &query)
register the object as being "default" when searching something similar as designated by the given qu...