changeset 11480:d14a23884d9c octave-forge

Cache map lookups of converters for composite type elements.
author i7tiol
date Mon, 25 Feb 2013 18:52:54 +0000
parents 174f5aaa9144
children 0946b7a3c764
files main/database/DESCRIPTION main/database/src/command.cc main/database/src/command.h main/database/src/converters.cc main/database/src/converters.h main/database/src/converters_arr_comp.cc main/database/src/pq_connection.cc
diffstat 7 files changed, 66 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/main/database/DESCRIPTION	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/DESCRIPTION	Mon Feb 25 18:52:54 2013 +0000
@@ -1,6 +1,6 @@
 Name: database
 Version: 2.0.1
-Date: 2013-02-22
+Date: 2013-02-25
 Author: Olaf Till <i7tiol@t-online.de>
 Maintainer: Olaf Till <i7tiol@t-online.de>
 Title: Database.
--- a/main/database/src/command.cc	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/command.cc	Mon Feb 25 18:52:54 2013 +0000
@@ -251,6 +251,24 @@
   return conv;
 }
 
+oct_pq_conv_t *command::pgtype_from_spec (Oid oid, oct_pq_conv_t *&c_conv,
+                                          oct_type_t &oct_type)
+{
+  if (c_conv)
+    {
+      if (c_conv->aoid == oid)
+        oct_type = array;
+      else if (c_conv->is_composite)
+        oct_type = composite;
+      else
+        oct_type = simple;
+    }
+  else
+    c_conv = pgtype_from_spec (oid, oct_type);
+
+  return c_conv;
+}
+
 octave_value command::process_single_result (const std::string &infile,
                                              const std::string &outfile)
 {
@@ -380,13 +398,6 @@
             }
         }
 
-      // FIXME: To avoid map-lookups of converters for elements of
-      // composite types in arbitrarily deep recursions (over
-      // composite types and possibly arrays) to be repeated in each
-      // row, build up a tree of pointers to looked up converter
-      // structures in the first row and pass branches of it, getting
-      // smaller through the recursions of type conversions, in the
-      // next rows.
       for (int i = 0; i < nt; i++) // i is row
         {
           if (PQgetisnull (res, i, j))
@@ -410,7 +421,7 @@
                   break;
 
                 case composite:
-                  if ((this->*composite_to_octave) (v, ov, nb))
+                  if ((this->*composite_to_octave) (v, ov, nb, conv))
                     valid = 0;
                   break;
 
--- a/main/database/src/command.h	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/command.h	Mon Feb 25 18:52:54 2013 +0000
@@ -61,7 +61,7 @@
     (char *, octave_value &, int, oct_pq_conv_t *);
 
   typedef int (command::*to_octave_composite_fp_t)
-    (char *, octave_value &, int);
+    (char *, octave_value &, int, oct_pq_conv_t *);
 
   int all_results_fetched (void)
   {
@@ -119,6 +119,8 @@
 
   oct_pq_conv_t *pgtype_from_spec (Oid, oct_type_t &);
 
+  oct_pq_conv_t *pgtype_from_spec (Oid, oct_pq_conv_t *&, oct_type_t &);
+
   int from_octave_bin_array (const octave_value &oct_arr, oct_pq_dynvec_t &val,
                              oct_pq_conv_t *);
 
@@ -133,11 +135,11 @@
 
   int to_octave_bin_array (char *, octave_value &, int, oct_pq_conv_t *);
 
-  int to_octave_bin_composite (char *, octave_value &, int);
+  int to_octave_bin_composite (char *, octave_value &, int, oct_pq_conv_t *);
 
   int to_octave_str_array (char *, octave_value &, int, oct_pq_conv_t *);
 
-  int to_octave_str_composite (char *, octave_value &, int);
+  int to_octave_str_composite (char *, octave_value &, int, oct_pq_conv_t *);
 
   octave_idx_type count_row_major_order (dim_vector &, count_state &, bool);
 
--- a/main/database/src/converters.cc	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/converters.cc	Mon Feb 25 18:52:54 2013 +0000
@@ -95,6 +95,7 @@
 oct_pq_conv_t conv_bool = {0, // 16
                            0, // 1000
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -143,6 +144,7 @@
 oct_pq_conv_t conv_oid = {0, // 26
                           0,
                           oct_pq_el_oids_t (),
+                          oct_pq_conv_cache_t (),
                           false,
                           false,
                           false,
@@ -213,6 +215,7 @@
 oct_pq_conv_t conv_float8 = {0, // 701
                              0, // 1022
                              oct_pq_el_oids_t (),
+                             oct_pq_conv_cache_t (),
                              false,
                              false,
                              false,
@@ -283,6 +286,7 @@
 oct_pq_conv_t conv_float4 = {0,
                              0,
                              oct_pq_el_oids_t (),
+                             oct_pq_conv_cache_t (),
                              false,
                              false,
                              false,
@@ -347,6 +351,7 @@
 oct_pq_conv_t conv_bytea = {0,
                             0,
                             oct_pq_el_oids_t (),
+                            oct_pq_conv_cache_t (),
                             false,
                             false,
                             false,
@@ -400,6 +405,7 @@
 oct_pq_conv_t conv_text = {0,
                            0,
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -416,6 +422,7 @@
 oct_pq_conv_t conv_varchar = {0,
                               0,
                               oct_pq_el_oids_t (),
+                              oct_pq_conv_cache_t (),
                               false,
                               false,
                               false,
@@ -432,6 +439,7 @@
 oct_pq_conv_t conv_bpchar = {0,
                              0,
                              oct_pq_el_oids_t (),
+                             oct_pq_conv_cache_t (),
                              false,
                              false,
                              false,
@@ -494,6 +502,7 @@
 oct_pq_conv_t conv_name = {0,
                            0,
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -542,6 +551,7 @@
 oct_pq_conv_t conv_int2 = {0, // 26
                            0,
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -591,6 +601,7 @@
 oct_pq_conv_t conv_int4 = {0,
                            0,
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -640,6 +651,7 @@
 oct_pq_conv_t conv_int8 = {0,
                            0,
                            oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
                            false,
                            false,
                            false,
@@ -657,6 +669,7 @@
 oct_pq_conv_t conv_money = {0,
                             0,
                             oct_pq_el_oids_t (),
+                            oct_pq_conv_cache_t (),
                             false,
                             false,
                             false,
--- a/main/database/src/converters.h	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/converters.h	Mon Feb 25 18:52:54 2013 +0000
@@ -41,12 +41,18 @@
 
 typedef std::vector<Oid> oct_pq_el_oids_t;
 
+struct oct_pq_conv_t_;
+
+typedef std::vector<struct oct_pq_conv_t_ *> oct_pq_conv_cache_t;
+
 // some objects will be constants, some will be allocated
-typedef struct
+typedef struct oct_pq_conv_t_
 {
   Oid oid; // read from server
   Oid aoid; // array oid // read from server
   oct_pq_el_oids_t el_oids; // element oids, empty for non-composite types
+  oct_pq_conv_cache_t conv_cache; // element converter structures for
+                                  //composite types
   bool is_composite; // false for constant objects
   bool is_enum; // false for constant objects
   bool is_not_constant; // false for constant objects
--- a/main/database/src/converters_arr_comp.cc	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/converters_arr_comp.cc	Mon Feb 25 18:52:54 2013 +0000
@@ -233,7 +233,9 @@
           oct_pq_conv_t *el_conv;
           oct_type_t oct_type;
 
-          if (! (el_conv = pgtype_from_spec (conv->el_oids[i], oct_type)))
+          if (! (el_conv = pgtype_from_spec (conv->el_oids[i],
+                                             conv->conv_cache[i],
+                                             oct_type)))
             return 1;
 
           switch (oct_type)
@@ -343,7 +345,7 @@
 
           if (conv->is_composite)
             {
-              if (to_octave_bin_composite (p, ov_el, nb_el))
+              if (to_octave_bin_composite (p, ov_el, nb_el, conv))
                 return 1;
             }
           else
@@ -368,7 +370,8 @@
   return 0;
 }
 
-int command::to_octave_bin_composite (char *v, octave_value &ov, int nb)
+int command::to_octave_bin_composite (char *v, octave_value &ov, int nb,
+                                      oct_pq_conv_t *conv)
 {
   char *p = v;
 
@@ -394,7 +397,8 @@
           oct_pq_conv_t *el_conv;
           oct_type_t oct_type;
 
-          if (! (el_conv = pgtype_from_spec (oid, oct_type)))
+          if (! (el_conv = pgtype_from_spec (oid, conv->conv_cache[i],
+                                             oct_type)))
             return 1;
 
           octave_value el;
@@ -411,7 +415,7 @@
               break;
 
             case composite:
-              if (to_octave_bin_composite (p, el, nb_el))
+              if (to_octave_bin_composite (p, el, nb_el, el_conv))
                 return 1;
               break;
 
@@ -444,7 +448,8 @@
   return 0;
 }
 
-int command::to_octave_str_composite (char *v, octave_value &ov, int nb)
+int command::to_octave_str_composite (char *v, octave_value &ov, int nb,
+                                      oct_pq_conv_t *conv)
 {
   // not implemented
   error ("not implemented");
--- a/main/database/src/pq_connection.cc	Mon Feb 25 16:50:26 2013 +0000
+++ b/main/database/src/pq_connection.cc	Mon Feb 25 18:52:54 2013 +0000
@@ -311,6 +311,8 @@
         }
       oct_pq_el_oids_t el_oids;
       el_oids.resize (nel);
+      oct_pq_conv_cache_t conv_cache;
+      conv_cache.resize (nel);
       for (octave_idx_type i = 0; i < nel; i++)
         {
           // "column" number (attnum) is one-based, so subtract 1
@@ -325,6 +327,8 @@
                 }
 
               el_oids[pos] = r_el_oids(i).uint_value ();
+
+              conv_cache[pos] = NULL;
             }
         }
       if (error_state)
@@ -341,6 +345,7 @@
       t_conv->oid = oid;
       t_conv->aoid = aoid;
       t_conv->el_oids = el_oids;
+      t_conv->conv_cache = conv_cache;
       t_conv->is_composite = true;
       t_conv->is_enum = false;
       t_conv->is_not_constant = true;
@@ -372,6 +377,8 @@
 
           t_conv_v->el_oids = el_oids;
 
+          t_conv_v->conv_cache = conv_cache;
+
           t_conv_v->name = name;
 
           name_conv_map[t_conv_v->name.c_str ()] = t_conv_v;;
@@ -447,6 +454,7 @@
       t_conv->oid = oid;
       t_conv->aoid = aoid;
       t_conv->el_oids = oct_pq_el_oids_t ();
+      t_conv->conv_cache = oct_pq_conv_cache_t ();
       t_conv->is_composite = false;
       t_conv->is_enum = true;
       t_conv->is_not_constant = true;
@@ -477,6 +485,8 @@
 
           t_conv_v->el_oids = oct_pq_el_oids_t ();
 
+          t_conv_v->conv_cache = oct_pq_conv_cache_t ();
+
           t_conv_v->name = name;
 
           name_conv_map[t_conv_v->name.c_str ()] = t_conv_v;