Author: timbo
Date: Sat Jul  1 14:59:09 2006
New Revision: 6605

Modified:
   dbi/trunk/DBI.xs

Log:
further profile code refactoring


Modified: dbi/trunk/DBI.xs
==============================================================================
--- dbi/trunk/DBI.xs    (original)
+++ dbi/trunk/DBI.xs    Sat Jul  1 14:59:09 2006
@@ -2201,6 +2201,27 @@
 # endif
 }
 
+
+static SV *
+_profile_next_node(SV *node, const char *name)
+{
+    /* step one level down profile Data tree and auto-vivify if required */
+    dTHX;
+    SV *orig_node = node;
+    if (SvROK(node))
+        node = SvRV(node);
+    if (SvTYPE(node) != SVt_PVHV) {
+        HV *hv = newHV();
+        if (SvOK(node))
+            warn("Profile data element %s replaced with new hash ref", 
neatsvpv(orig_node,0));
+        sv_setsv(node, newRV_noinc((SV*)hv));
+        node = (SV*)hv;
+    }
+    node = *hv_fetch((HV*)node, name, strlen(name), 1);
+    return node;
+}
+
+
 static void
 dbi_profile(SV *h, imp_xxh_t *imp_xxh, const char *statement, SV *method, 
double t1, double t2)
 {
@@ -2215,13 +2236,12 @@
 #define DBIprof_max_index      6
     dTHX;
     double ti = t2 - t1;
-    const char *path[DBIprof_MAX_PATH_ELEM+1];
-    int src_idx;
-    int dst_idx;
+    int src_idx = 0;
     HV *dbh_outer_hv = NULL;
     HV *dbh_inner_hv = NULL;
     SV *profile;
     SV *tmp;
+    SV *dest_node;
     AV *av;
     HV *h_hv;
 
@@ -2255,9 +2275,8 @@
        PerlIO_printf(DBIc_LOGPIO(imp_xxh), "dbi_profile %s %f q{%s}\n",
                neatsvpv((SvTYPE(method)==SVt_PVCV) ? (SV*)CvGV(method) : 
method, 0),
                ti, statement);
-    src_idx = 0;
-    dst_idx = 0;
-    path[dst_idx++] = "Data";
+
+    dest_node = _profile_next_node(profile, "Data");
 
     tmp = *hv_fetch((HV*)SvRV(profile), "Path", 4, 1);
     if (SvROK(tmp) && SvTYPE(SvRV(tmp))==SVt_PVAV) {
@@ -2265,18 +2284,17 @@
        av = (AV*)SvRV(tmp);
        len = av_len(av); /* -1=empty, 0=one element */
 
-       while ( src_idx <= len && dst_idx < DBIprof_MAX_PATH_ELEM) {
+       while ( src_idx <= len ) {
            SV *pathsv = AvARRAY(av)[src_idx++];
-           const char *p = "?";
-            /* warn("s=%d, d=%d, p=%s", src_idx, dst_idx, neatsvpv(pathsv,0)); 
*/
 
            if (SvROK(tmp) && SvTYPE(SvRV(tmp))==SVt_PVCV) {
                /* call sub, use returned list of values as path */
                /* if no values returned then don't save data   */
                warn("code ref in Path");
-               p = Nullch;
+                dest_node = _profile_next_node(dest_node, "CODE");
            }
            else if (looks_like_number(pathsv)) {
+                const char *p = "?";
                /* numbers are special-cases */
                switch(SvIV(pathsv)) {  /* see lib/DBI/Profile.pm for magic 
numbers */
                case -2100000001:       /* DBIprofile_Statement */
@@ -2310,10 +2328,11 @@
                    p = SvPV_nolen(pathsv);
                    break;
                }
+                dest_node = _profile_next_node(dest_node, p);
            }
            else if (SvOK(pathsv)) {
                STRLEN len;
-               p = SvPV(pathsv,len);
+                const char *p = SvPV(pathsv,len);
                if (p[0] == '{' && p[len-1] == '}') { /* treat as name of dbh 
attribute to use */
                    SV **attr_svp;
                    if (!dbh_inner_hv) {        /* cache dbh handles the first 
time we need them */
@@ -2345,31 +2364,18 @@
                    else
                        p = SvPV_nolen(*attr_svp);
                }
+                dest_node = _profile_next_node(dest_node, p);
            }
-           path[dst_idx++] = p;
+            /* else ignore */
        }
     }
-    else { /* any bad Path value is treated as a Path of just Statement */
-       path[dst_idx++] = statement;
+    else { /* a bad Path value is treated as a Path of just Statement */
+        dest_node = _profile_next_node(dest_node, statement);
     }
-    path[dst_idx++] = Nullch;
+
 
     /* this walk-down-the-tree code should be merged into the loop above */
-    tmp = profile;
-    for (dst_idx=0; path[dst_idx]; ++dst_idx) {
-       SV *orig_tmp = tmp;
-       if (SvROK(tmp))
-           tmp = SvRV(tmp);
-       if (SvTYPE(tmp) != SVt_PVHV) {
-           HV *hv = newHV();
-           if (SvOK(tmp))
-               warn("Profile data element %s replaced with new hash ref", 
neatsvpv(orig_tmp,0));
-           sv_setsv(tmp, newRV_noinc((SV*)hv));
-           tmp = (SV*)hv;
-       }
-       tmp = *hv_fetch((HV*)tmp, path[dst_idx], strlen(path[dst_idx]), 1);
-       /* warn("%d hv_fetch %s = %s", dst_idx, path[dst_idx], 
neatsvpv(tmp,0)); */
-    }
+    tmp = dest_node;
     if (!SvOK(tmp)) {
        av = newAV();
        sv_setsv(tmp, newRV_noinc((SV*)av));
@@ -2385,8 +2391,8 @@
        if (SvROK(tmp))
            tmp = SvRV(tmp);
        if (SvTYPE(tmp) != SVt_PVAV)
-           croak("Invalid Profile data leaf element at depth %d: %s (type %d)",
-                   dst_idx, neatsvpv(tmp,0), SvTYPE(tmp));
+           croak("Invalid Profile data leaf element: %s (type %d)",
+                   neatsvpv(tmp,0), SvTYPE(tmp));
        av = (AV*)tmp;
        sv_inc( *av_fetch(av, DBIprof_COUNT, 1));
        tmp = *av_fetch(av, DBIprof_TOTAL_TIME, 1);

Reply via email to