Merge lp:~posulliv/drizzle/replace-dynamic-array into lp:~drizzle-trunk/drizzle/development

Proposed by Padraig O'Sullivan
Status: Merged
Merged at revision: not available
Proposed branch: lp:~posulliv/drizzle/replace-dynamic-array
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: None lines
To merge this branch: bzr merge lp:~posulliv/drizzle/replace-dynamic-array
Reviewer Review Type Date Requested Status
Jay Pipes (community) Approve
Drizzle Developers Pending
Review via email: mp+4123@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Padraig O'Sullivan (posulliv) wrote :

In this branch, I've replaced an instance of DYNAMIC_ARRAY (all_status_vars) in drizzled/show.cc with the appropriate STL standard (in this case std::vector).

Revision history for this message
Jay Pipes (jaypipes) wrote :

Overall, great! Couple tiny things... :)

1) Const correctness in functor.

The args are const correct, good, but you should also add const to the function declaration, too, since the state of the functor doesn't change via the operator():

change from:

inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2)

to:

inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const

Same comment as above for the show_var_remove_if functor's operator().

2) Put assignments on a separate line from comparisons.

You do:

+ int val;
+ if ((val = strcmp(var1->name, var2->name)) < 0)

It would be better to do:

+ int val= strcmp(var1->name, var2->name);
+ if (val < 0)

Generally, a single line of source code should try to do a single operation. There is no performance benefit from putting it in a single line, and doing the assignment on a separate line leads to less error-prone code.

You could even change the body of the operator() to just this:

int val= strcmp(var1->name, var2->name);
return (val < 0);

3)

- all_status_vars.elements--; // but next insert_dynamic should overwite it
+ all_status_vars.insert(all_status_vars.begin(), list++);

You have 3 spaces instead of 2 at the start of this line. Yeah, I know...I'm nitpicky. :)

review: Needs Fixing
923. By Padraig <posulliv@linux-lap>

Small modifications based on Jay's merge review comments. Should be all good
now.

Revision history for this message
Padraig O'Sullivan (posulliv) wrote :

"Overall, great! Couple tiny things... :)

1) Const correctness in functor.

The args are const correct, good, but you should also add const to the function declaration, too, since the state of the functor doesn't change via the operator():

change from:

inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2)

to:

inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const

Same comment as above for the show_var_remove_if functor's operator().

2) Put assignments on a separate line from comparisons.

You do:

+ int val;
+ if ((val = strcmp(var1->name, var2->name)) < 0)

It would be better to do:

+ int val= strcmp(var1->name, var2->name);
+ if (val < 0)

Generally, a single line of source code should try to do a single operation. There is no performance benefit from putting it in a single line, and doing the assignment on a separate line leads to less error-prone code.

You could even change the body of the operator() to just this:

int val= strcmp(var1->name, var2->name);
return (val < 0);

3)

- all_status_vars.elements--; // but next insert_dynamic should overwite it
+ all_status_vars.insert(all_status_vars.begin(), list++);

You have 3 spaces instead of 2 at the start of this line. Yeah, I know...I'm nitpicky. :)

Thanks for the comments. I addressed the 3 things you mentioned in the branch.

Revision history for this message
Jay Pipes (jaypipes) wrote :

Looks great.

review: Approve
924. By Padraig <posulliv@linux-lap>

Merge from trunk.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'drizzled/show.cc'
2--- drizzled/show.cc 2009-02-28 17:48:22 +0000
3+++ drizzled/show.cc 2009-03-01 04:15:11 +0000
4@@ -45,6 +45,8 @@
5 #include <string>
6 #include <iostream>
7 #include <sstream>
8+#include <vector>
9+#include <algorithm>
10
11 using namespace std;
12
13@@ -1222,33 +1224,40 @@
14 Status functions
15 *****************************************************************************/
16
17-static DYNAMIC_ARRAY all_status_vars;
18+static vector<SHOW_VAR *> all_status_vars;
19 static bool status_vars_inited= 0;
20 int show_var_cmp(const void *var1, const void *var2)
21 {
22 return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
23 }
24
25-/*
26- deletes all the SHOW_UNDEF elements from the array and calls
27- delete_dynamic() if it's completely empty.
28-*/
29-static void shrink_var_array(DYNAMIC_ARRAY *array)
30+class show_var_cmp_functor
31 {
32- uint32_t a,b;
33- SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
34+ public:
35+ show_var_cmp_functor() { }
36+ inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2)
37+ {
38+ int val;
39+ if ((val = strcmp(var1->name, var2->name)) < 0)
40+ {
41+ return true;
42+ }
43+ else
44+ {
45+ return false;
46+ }
47+ }
48+};
49
50- for (a= b= 0; b < array->elements; b++)
51- if (all[b].type != SHOW_UNDEF)
52- all[a++]= all[b];
53- if (a)
54+class show_var_remove_if
55+{
56+ public:
57+ show_var_remove_if() { }
58+ inline bool operator()(const SHOW_VAR *curr)
59 {
60- memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
61- array->elements= a;
62+ return (curr->type == SHOW_UNDEF);
63 }
64- else // array is completely empty - delete it
65- delete_dynamic(array);
66-}
67+};
68
69 /*
70 Adds an array of SHOW_VAR entries to the output of SHOW STATUS
71@@ -1266,27 +1275,17 @@
72 As a special optimization, if add_status_vars() is called before
73 init_status_vars(), it assumes "startup mode" - neither concurrent access
74 to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
75-
76- The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
77 */
78 int add_status_vars(SHOW_VAR *list)
79 {
80 int res= 0;
81 if (status_vars_inited)
82 pthread_mutex_lock(&LOCK_status);
83- if (!all_status_vars.buffer && // array is not allocated yet - do it now
84- my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
85- {
86- res= 1;
87- goto err;
88- }
89 while (list->name)
90- res|= insert_dynamic(&all_status_vars, (unsigned char*)list++);
91- res|= insert_dynamic(&all_status_vars, (unsigned char*)list); // appending NULL-element
92- all_status_vars.elements--; // but next insert_dynamic should overwite it
93+ all_status_vars.insert(all_status_vars.begin(), list++);
94 if (status_vars_inited)
95- sort_dynamic(&all_status_vars, show_var_cmp);
96-err:
97+ sort(all_status_vars.begin(), all_status_vars.end(),
98+ show_var_cmp_functor());
99 if (status_vars_inited)
100 pthread_mutex_unlock(&LOCK_status);
101 return res;
102@@ -1302,19 +1301,20 @@
103 */
104 void init_status_vars()
105 {
106- status_vars_inited=1;
107- sort_dynamic(&all_status_vars, show_var_cmp);
108+ status_vars_inited= 1;
109+ sort(all_status_vars.begin(), all_status_vars.end(),
110+ show_var_cmp_functor());
111 }
112
113 void reset_status_vars()
114 {
115- SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
116- SHOW_VAR *last= ptr + all_status_vars.elements;
117- for (; ptr < last; ptr++)
118+ vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
119+ while (p != all_status_vars.end())
120 {
121 /* Note that SHOW_LONG_NOFLUSH variables are not reset */
122- if (ptr->type == SHOW_LONG)
123- *(ulong*) ptr->value= 0;
124+ if ((*p)->type == SHOW_LONG)
125+ (*p)->value= 0;
126+ ++p;
127 }
128 }
129
130@@ -1324,12 +1324,12 @@
131 DESCRIPTION
132 This function is not strictly required if all add_to_status/
133 remove_status_vars are properly paired, but it's a safety measure that
134- deletes everything from the all_status_vars[] even if some
135+ deletes everything from the all_status_vars vector even if some
136 remove_status_vars were forgotten
137 */
138 void free_status_vars()
139 {
140- delete_dynamic(&all_status_vars);
141+ all_status_vars.clear();
142 }
143
144 /*
145@@ -1351,13 +1351,13 @@
146 if (status_vars_inited)
147 {
148 pthread_mutex_lock(&LOCK_status);
149- SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
150- int a= 0, b= all_status_vars.elements, c= (a+b)/2;
151+ SHOW_VAR *all= all_status_vars.front();
152+ int a= 0, b= all_status_vars.size(), c= (a+b)/2;
153
154 for (; list->name; list++)
155 {
156 int res= 0;
157- for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
158+ for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
159 {
160 res= show_var_cmp(list, all+c);
161 if (res < 0)
162@@ -1370,16 +1370,19 @@
163 if (res == 0)
164 all[c].type= SHOW_UNDEF;
165 }
166- shrink_var_array(&all_status_vars);
167+ /* removes all the SHOW_UNDEF elements from the vector */
168+ all_status_vars.erase(std::remove_if(all_status_vars.begin(),
169+ all_status_vars.end(),show_var_remove_if()),
170+ all_status_vars.end());
171 pthread_mutex_unlock(&LOCK_status);
172 }
173 else
174 {
175- SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
176+ SHOW_VAR *all= all_status_vars.front();
177 uint32_t i;
178 for (; list->name; list++)
179 {
180- for (i= 0; i < all_status_vars.elements; i++)
181+ for (i= 0; i < all_status_vars.size(); i++)
182 {
183 if (show_var_cmp(list, all+i))
184 continue;
185@@ -1387,7 +1390,10 @@
186 break;
187 }
188 }
189- shrink_var_array(&all_status_vars);
190+ /* removes all the SHOW_UNDEF elements from the vector */
191+ all_status_vars.erase(std::remove_if(all_status_vars.begin(),
192+ all_status_vars.end(),show_var_remove_if()),
193+ all_status_vars.end());
194 }
195 }
196
197@@ -3569,7 +3575,7 @@
198 if (option_type == OPT_GLOBAL)
199 calc_sum_of_all_status(&tmp);
200 res= show_status_array(session, wild,
201- (SHOW_VAR *)all_status_vars.buffer,
202+ (SHOW_VAR *) all_status_vars.front(),
203 option_type, tmp1, "", tables->table,
204 upper_case_names);
205 pthread_mutex_unlock(&LOCK_status);