[beast: 6/8] SFI: sfi_pspec_seq_field_from_visitable: cache pspecs per template type



commit 6b1ea71e76b7d5de937156495a82cdd6a3141434
Author: Tim Janik <timj gnu org>
Date:   Sat Sep 19 00:20:52 2015 +0200

    SFI: sfi_pspec_seq_field_from_visitable: cache pspecs per template type

 sfi/sfivisitors.cc |   19 +++++++++++++++++++
 sfi/sfivisitors.hh |   18 ++++++++++++++++--
 2 files changed, 35 insertions(+), 2 deletions(-)
---
diff --git a/sfi/sfivisitors.cc b/sfi/sfivisitors.cc
index 0c02cd5..0e86171 100644
--- a/sfi/sfivisitors.cc
+++ b/sfi/sfivisitors.cc
@@ -24,6 +24,25 @@ sfi_pspecs_rec_fields_cache (const std::type_info &type_info, SfiRecFields *rf,
   return true;
 }
 
+typedef std::unordered_map<std::type_index, GParamSpec*> VisitableTypeSeqFieldMap;
+
+static VisitableTypeSeqFieldMap visitable_type_seq_field_map;
+
+bool
+sfi_pspecs_seq_field_cache (const std::type_info &type_info, GParamSpec  **pp, bool assign)
+{
+  if (assign)
+    {
+      visitable_type_seq_field_map[type_info] = *pp;
+      return true;
+    }
+  auto it = visitable_type_seq_field_map.find (type_info);
+  if (it == visitable_type_seq_field_map.end())
+    return false;
+  *pp = it->second;
+  return true;
+}
+
 typedef std::unordered_map<std::type_index, std::vector<GParamSpec*> > VisitableTypeAcsFieldMap;
 
 static VisitableTypeAcsFieldMap visitable_type_acs_fields;
diff --git a/sfi/sfivisitors.hh b/sfi/sfivisitors.hh
index ee91896..016687d 100644
--- a/sfi/sfivisitors.hh
+++ b/sfi/sfivisitors.hh
@@ -14,6 +14,7 @@ template<class Visitable> SfiRecFields                    sfi_pspecs_rec_fields_
 template<class Visitable> GParamSpec*                     sfi_pspec_seq_field_from_visitable        
(Visitable &visitable);
 template<class Visitable> const std::vector<GParamSpec*>& sfi_pspecs_fields_from_accessor_visitable 
(Visitable &visitable);
 bool sfi_pspecs_rec_fields_cache (const std::type_info &type_info, SfiRecFields *rf, bool assign = false); 
// internal
+bool sfi_pspecs_seq_field_cache  (const std::type_info &type_info, GParamSpec  **pp, bool assign = false); 
// internal
 bool sfi_pspecs_acs_fields_cache (const std::type_info &type_info, std::vector<GParamSpec*>**, bool assign = 
false); // internal
 
 class PspecVisitor : public VisitorDispatcher<PspecVisitor> {
@@ -313,14 +314,27 @@ sfi_pspecs_rec_fields_from_visitable (Visitable &visitable)
 template<class Visitable> GParamSpec*
 sfi_pspec_seq_field_from_visitable (Visitable &visitable)
 {
+  GParamSpec *pspec = NULL;
+  if (sfi_pspecs_seq_field_cache (typeid (Visitable), &pspec))
+    return pspec;
   std::vector<GParamSpec*> pspecs;
   PspecVisitor pspec_visitor (pspecs, visitable.__aida_aux_data__());
   typedef typename Visitable::value_type A;
   A example_element = A();
   pspec_visitor (example_element, "seqelement");
-  GParamSpec *pspec = NULL;
   if (pspecs.size() == 1)
-    pspec = pspecs[0];
+    {
+      pspec = pspecs[0];
+      g_param_spec_ref (pspec);
+      g_param_spec_sink (pspec);
+      sfi_pspecs_seq_field_cache (typeid (Visitable), &pspec, true);
+    }
+  for (size_t i = 0; i < pspecs.size(); i++)
+    {
+      g_param_spec_ref (pspecs[i]);
+      g_param_spec_sink (pspecs[i]);
+      g_param_spec_unref (pspecs[i]);
+    }
   return pspec;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]