CUBRID Engine  latest
statistics_cl.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * statistics_cl.c - statistics manager (client)
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 
29 #include "object_representation.h"
30 #include "statistics.h"
31 #include "object_primitive.h"
32 #include "memory_alloc.h"
33 #include "work_space.h"
34 #include "schema_manager.h"
35 #include "network_interface_cl.h"
36 #include "tz_support.h"
37 #include "db_date.h"
38 
39 static CLASS_STATS *stats_client_unpack_statistics (char *buffer);
40 
41 /*
42  * stats_get_statistics () - Get class statistics
43  * return: error code
44  * classoid(in): OID of the class
45  * timestamp(in):
46  * stats_p(in/out):
47  *
48  * Note: This function provides an easier interface for the client for
49  * obtaining statistics to the client side by taking care of the
50  * communication details . (Note that the upper levels shouldn't have to
51  * worry about the communication buffer.)
52  */
53 int
54 stats_get_statistics (OID * class_oid_p, unsigned int time_stamp, CLASS_STATS ** stats_p)
55 {
56  char *buffer_p = NULL;
57  int length = -1;
58  int error;
59  *stats_p = NULL;
60 
61  error = stats_get_statistics_from_server (class_oid_p, time_stamp, &length, &buffer_p);
62  if (error == NO_ERROR && buffer_p != NULL)
63  {
64  assert (length > 0);
65 
66  *stats_p = stats_client_unpack_statistics (buffer_p);
67  free_and_init (buffer_p);
68  }
69 
70  return error;
71 }
72 
73 /*
74  * qst_client_unpack_statistics () - Unpack the buffer containing statistics
75  * return: CLASS_STATS or NULL in case of error
76  * bufp(in): buffer containing the class statistics
77  *
78  * Note: This function unpacks the statistics on the buffer received from the
79  * server side, and builds a CLASS_STATS structure on the work space
80  * area. This sturucture is returned to the caller.
81  */
82 static CLASS_STATS *
84 {
85  CLASS_STATS *class_stats_p;
86  ATTR_STATS *attr_stats_p;
87  BTREE_STATS *btree_stats_p;
88  int max_unique_keys;
89  int i, j, k;
90 
91  if (buf_p == NULL)
92  {
93  return NULL;
94  }
95 
96  class_stats_p = (CLASS_STATS *) db_ws_alloc (sizeof (CLASS_STATS));
97  if (class_stats_p == NULL)
98  {
99  return NULL;
100  }
101 
102  class_stats_p->time_stamp = (unsigned int) OR_GET_INT (buf_p);
103  buf_p += OR_INT_SIZE;
104 
105  class_stats_p->heap_num_objects = OR_GET_INT (buf_p);
106  buf_p += OR_INT_SIZE;
107  if (class_stats_p->heap_num_objects < 0)
108  {
109  assert (false);
110  class_stats_p->heap_num_objects = 0;
111  }
112 
113  class_stats_p->heap_num_pages = OR_GET_INT (buf_p);
114  buf_p += OR_INT_SIZE;
115  if (class_stats_p->heap_num_pages < 0)
116  {
117  assert (false);
118  class_stats_p->heap_num_pages = 0;
119  }
120 
121  /* to get the doubtful statistics to be updated, need to clear timestamp */
122  if (class_stats_p->heap_num_objects == 0 || class_stats_p->heap_num_pages == 0)
123  {
124  class_stats_p->time_stamp = 0;
125  }
126 
127  class_stats_p->n_attrs = OR_GET_INT (buf_p);
128  buf_p += OR_INT_SIZE;
129  if (class_stats_p->n_attrs == 0)
130  {
131  db_ws_free (class_stats_p);
132  return NULL;
133  }
134 
135  class_stats_p->attr_stats = (ATTR_STATS *) db_ws_alloc (class_stats_p->n_attrs * sizeof (ATTR_STATS));
136  if (class_stats_p->attr_stats == NULL)
137  {
138  db_ws_free (class_stats_p);
139  return NULL;
140  }
141 
142  for (i = 0, attr_stats_p = class_stats_p->attr_stats; i < class_stats_p->n_attrs; i++, attr_stats_p++)
143  {
144  attr_stats_p->id = OR_GET_INT (buf_p);
145  buf_p += OR_INT_SIZE;
146 
147  attr_stats_p->type = (DB_TYPE) OR_GET_INT (buf_p);
148  buf_p += OR_INT_SIZE;
149 
150  attr_stats_p->n_btstats = OR_GET_INT (buf_p);
151  buf_p += OR_INT_SIZE;
152 
153  if (attr_stats_p->n_btstats <= 0)
154  {
155  attr_stats_p->bt_stats = NULL;
156  continue;
157  }
158 
159  attr_stats_p->bt_stats = (BTREE_STATS *) db_ws_alloc (attr_stats_p->n_btstats * sizeof (BTREE_STATS));
160  if (attr_stats_p->bt_stats == NULL)
161  {
162  stats_free_statistics (class_stats_p);
163  return NULL;
164  }
165  memset (attr_stats_p->bt_stats, 0, attr_stats_p->n_btstats * sizeof (BTREE_STATS));
166 
167  for (j = 0, btree_stats_p = attr_stats_p->bt_stats; j < attr_stats_p->n_btstats; j++, btree_stats_p++)
168  {
169  OR_GET_BTID (buf_p, &btree_stats_p->btid);
170  buf_p += OR_BTID_ALIGNED_SIZE;
171 
172  btree_stats_p->leafs = OR_GET_INT (buf_p);
173  buf_p += OR_INT_SIZE;
174 
175  btree_stats_p->pages = OR_GET_INT (buf_p);
176  buf_p += OR_INT_SIZE;
177 
178  btree_stats_p->height = OR_GET_INT (buf_p);
179  buf_p += OR_INT_SIZE;
180 
181  btree_stats_p->has_function = OR_GET_INT (buf_p);
182  buf_p += OR_INT_SIZE;
183 
184  btree_stats_p->keys = OR_GET_INT (buf_p);
185  buf_p += OR_INT_SIZE;
186 
187  buf_p = or_unpack_domain (buf_p, &btree_stats_p->key_type, 0);
188 
189  if (TP_DOMAIN_TYPE (btree_stats_p->key_type) == DB_TYPE_MIDXKEY)
190  {
191  btree_stats_p->pkeys_size = tp_domain_size (btree_stats_p->key_type->setdomain);
192  }
193  else
194  {
195  btree_stats_p->pkeys_size = 1;
196  }
197 
198  /* cut-off to stats */
199  if (btree_stats_p->pkeys_size > BTREE_STATS_PKEYS_NUM)
200  {
201  btree_stats_p->pkeys_size = BTREE_STATS_PKEYS_NUM;
202  }
203 
204  btree_stats_p->pkeys = (int *) db_ws_alloc (btree_stats_p->pkeys_size * sizeof (int));
205  if (btree_stats_p->pkeys == NULL)
206  {
207  stats_free_statistics (class_stats_p);
208  return NULL;
209  }
210 
211  assert (btree_stats_p->pkeys_size <= BTREE_STATS_PKEYS_NUM);
212  for (k = 0; k < btree_stats_p->pkeys_size; k++)
213  {
214  btree_stats_p->pkeys[k] = OR_GET_INT (buf_p);
215  buf_p += OR_INT_SIZE;
216  }
217  }
218  }
219 
220  /* correct estimated num_objects with unique keys */
221  max_unique_keys = OR_GET_INT (buf_p);
222  buf_p += OR_INT_SIZE;
223  if (max_unique_keys > 0)
224  {
225  class_stats_p->heap_num_objects = max_unique_keys;
226  }
227 
228  /* validate key stats info */
229  assert (class_stats_p->heap_num_objects >= 0);
230  for (i = 0, attr_stats_p = class_stats_p->attr_stats; i < class_stats_p->n_attrs; i++, attr_stats_p++)
231  {
232  for (j = 0, btree_stats_p = attr_stats_p->bt_stats; j < attr_stats_p->n_btstats; j++, btree_stats_p++)
233  {
234  assert (btree_stats_p->keys >= 0);
235  btree_stats_p->keys = MIN (btree_stats_p->keys, class_stats_p->heap_num_objects);
236  for (k = 0; k < btree_stats_p->pkeys_size; k++)
237  {
238  assert (btree_stats_p->pkeys[k] >= 0);
239  btree_stats_p->pkeys[k] = MIN (btree_stats_p->pkeys[k], btree_stats_p->keys);
240  }
241  }
242  }
243 
244  return class_stats_p;
245 }
246 
247 /*
248  * stats_free_statistics () - Frees the given CLASS_STAT structure
249  * return: void
250  * class_statsp(in): class statistics to be freed
251  */
252 void
254 {
255  ATTR_STATS *attr_statsp;
256  int i, j;
257 
258  if (class_statsp)
259  {
260  if (class_statsp->attr_stats)
261  {
262  for (i = 0, attr_statsp = class_statsp->attr_stats; i < class_statsp->n_attrs; i++, attr_statsp++)
263  {
264  if (attr_statsp->bt_stats)
265  {
266  for (j = 0; j < attr_statsp->n_btstats; j++)
267  {
268  if (attr_statsp->bt_stats[j].pkeys)
269  {
270  db_ws_free (attr_statsp->bt_stats[j].pkeys);
271  attr_statsp->bt_stats[j].pkeys = NULL;
272  }
273  }
274 
275  db_ws_free (attr_statsp->bt_stats);
276  attr_statsp->bt_stats = NULL;
277  }
278  }
279  db_ws_free (class_statsp->attr_stats);
280  class_statsp->attr_stats = NULL;
281  }
282 
283  db_ws_free (class_statsp);
284  }
285 }
286 
287 /*
288  * stats_dump () - Dumps the given statistics about a class
289  * return:
290  * classname(in): The name of class to be printed
291  * fp(in):
292  */
293 void
294 stats_dump (const char *class_name_p, FILE * file_p)
295 {
296  MOP class_mop;
297  CLASS_STATS *class_stats_p;
298  ATTR_STATS *attr_stats_p;
299  BTREE_STATS *bt_stats_p;
300  SM_CLASS *smclass_p;
301  int i, j, k;
302  const char *name_p;
303  const char *prefix_p = "";
304  time_t tloc;
305 
306  class_mop = sm_find_class (class_name_p);
307  if (class_mop == NULL)
308  {
309  return;
310  }
311 
312  smclass_p = sm_get_class_with_statistics (class_mop);
313  if (smclass_p == NULL)
314  {
315  return;
316  }
317 
318  class_stats_p = smclass_p->stats;
319  if (class_stats_p == NULL)
320  {
321  return;
322  }
323 
324  tloc = (time_t) class_stats_p->time_stamp;
325 
326  fprintf (file_p, "\nCLASS STATISTICS\n");
327  fprintf (file_p, "****************\n");
328  fprintf (file_p, " Class name: %s Timestamp: %s", class_name_p, ctime (&tloc));
329  fprintf (file_p, " Total pages in class heap: %d\n", class_stats_p->heap_num_pages);
330  fprintf (file_p, " Total objects: %d\n", class_stats_p->heap_num_objects);
331  fprintf (file_p, " Number of attributes: %d\n", class_stats_p->n_attrs);
332 
333  for (i = 0; i < class_stats_p->n_attrs; i++)
334  {
335  attr_stats_p = &(class_stats_p->attr_stats[i]);
336 
337  name_p = sm_get_att_name (class_mop, attr_stats_p->id);
338  fprintf (file_p, " Attribute: %s\n", (name_p ? name_p : "not found"));
339  fprintf (file_p, " id: %d\n", attr_stats_p->id);
340  fprintf (file_p, " Type: ");
341 
342  switch (attr_stats_p->type)
343  {
344  case DB_TYPE_SHORT:
345  fprintf (file_p, "DB_TYPE_SHORT\n");
346  break;
347 
348  case DB_TYPE_INTEGER:
349  fprintf (file_p, "DB_TYPE_INTEGER\n");
350  break;
351 
352  case DB_TYPE_BIGINT:
353  fprintf (file_p, "DB_TYPE_BIGINT\n");
354  break;
355 
356  case DB_TYPE_FLOAT:
357  fprintf (file_p, "DB_TYPE_FLOAT\n");
358  break;
359 
360  case DB_TYPE_DOUBLE:
361  fprintf (file_p, "DB_TYPE_DOUBLE\n");
362  break;
363 
364  case DB_TYPE_STRING:
365  fprintf (file_p, "DB_TYPE_STRING\n");
366  break;
367 
368  case DB_TYPE_OBJECT:
369  fprintf (file_p, "DB_TYPE_OBJECT\n");
370  break;
371 
372  case DB_TYPE_SET:
373  fprintf (file_p, "DB_TYPE_SET\n");
374  break;
375 
376  case DB_TYPE_MULTISET:
377  fprintf (file_p, "DB_TYPE_MULTISET\n");
378  break;
379 
380  case DB_TYPE_SEQUENCE:
381  fprintf (file_p, "DB_TYPE_SEQUENCE\n");
382  break;
383 
384  case DB_TYPE_TIME:
385  fprintf (file_p, "DB_TYPE_TIME\n");
386  break;
387 
388  case DB_TYPE_TIMESTAMP:
389  fprintf (file_p, "DB_TYPE_TIMESTAMP\n");
390  break;
391 
393  fprintf (file_p, "DB_TYPE_TIMESTAMPLTZ\n");
394  break;
395 
396  case DB_TYPE_TIMESTAMPTZ:
397  fprintf (file_p, "DB_TYPE_TIMESTAMPTZ\n");
398  break;
399 
400  case DB_TYPE_DATETIME:
401  fprintf (file_p, "DB_TYPE_DATETIME\n");
402  break;
403 
404  case DB_TYPE_DATETIMELTZ:
405  fprintf (file_p, "DB_TYPE_DATETIMELTZ\n");
406  break;
407 
408  case DB_TYPE_DATETIMETZ:
409  fprintf (file_p, "DB_TYPE_DATETIMETZ\n");
410  break;
411 
412  case DB_TYPE_MONETARY:
413  fprintf (file_p, "DB_TYPE_MONETARY\n");
414  break;
415 
416  case DB_TYPE_DATE:
417  fprintf (file_p, "DB_TYPE_DATE\n");
418  break;
419 
420  case DB_TYPE_BLOB:
421  fprintf (file_p, "DB_TYPE_BLOB\n");
422  break;
423 
424  case DB_TYPE_CLOB:
425  fprintf (file_p, "DB_TYPE_CLOB\n");
426  break;
427 
428  case DB_TYPE_VARIABLE:
429  fprintf (file_p, "DB_TYPE_VARIABLE\n");
430  break;
431 
432  case DB_TYPE_SUB:
433  fprintf (file_p, "DB_TYPE_SUB\n");
434  break;
435 
436  case DB_TYPE_POINTER:
437  fprintf (file_p, "DB_TYPE_POINTER\n");
438  break;
439 
440  case DB_TYPE_NULL:
441  fprintf (file_p, "DB_TYPE_NULL\n");
442  break;
443 
444  case DB_TYPE_NUMERIC:
445  fprintf (file_p, "DB_TYPE_NUMERIC\n");
446  break;
447 
448  case DB_TYPE_BIT:
449  fprintf (file_p, "DB_TYPE_BIT\n");
450  break;
451 
452  case DB_TYPE_VARBIT:
453  fprintf (file_p, "DB_TYPE_VARBIT\n");
454  break;
455 
456  case DB_TYPE_CHAR:
457  fprintf (file_p, "DB_TYPE_CHAR\n");
458  break;
459 
460  case DB_TYPE_NCHAR:
461  fprintf (file_p, "DB_TYPE_NCHAR\n");
462  break;
463 
464  case DB_TYPE_VARNCHAR:
465  fprintf (file_p, "DB_TYPE_VARNCHAR\n");
466  break;
467 
468  case DB_TYPE_DB_VALUE:
469  fprintf (file_p, "DB_TYPE_DB_VALUE\n");
470  break;
471 
472  case DB_TYPE_ENUMERATION:
473  fprintf (file_p, "DB_TYPE_ENUMERATION\n");
474  break;
475 
476  default:
477  assert (false);
478  fprintf (file_p, "UNKNOWN_TYPE\n");
479  break;
480  }
481 
482  if (attr_stats_p->n_btstats > 0)
483  {
484  fprintf (file_p, " B+tree statistics:\n");
485 
486  for (j = 0; j < attr_stats_p->n_btstats; j++)
487  {
488  bt_stats_p = &(attr_stats_p->bt_stats[j]);
489 
490  fprintf (file_p, " BTID: { %d , %d }\n", bt_stats_p->btid.vfid.volid,
491  bt_stats_p->btid.vfid.fileid);
492  fprintf (file_p, " Cardinality: %d (", bt_stats_p->keys);
493 
494  prefix_p = "";
495  assert (bt_stats_p->pkeys_size <= BTREE_STATS_PKEYS_NUM);
496  for (k = 0; k < bt_stats_p->pkeys_size; k++)
497  {
498  fprintf (file_p, "%s%d", prefix_p, bt_stats_p->pkeys[k]);
499  prefix_p = ",";
500  }
501  fprintf (file_p, ") ,");
502  fprintf (file_p, " Total pages: %d , Leaf pages: %d , Height: %d\n", bt_stats_p->pages,
503  bt_stats_p->leafs, bt_stats_p->height);
504  }
505  }
506  fprintf (file_p, "\n");
507  }
508 
509  fprintf (file_p, "\n\n");
510 }
#define OR_BTID_ALIGNED_SIZE
#define NO_ERROR
Definition: error_code.h:46
DB_TYPE
Definition: dbtype_def.h:670
int n_btstats
Definition: statistics.h:80
struct tp_domain * setdomain
Definition: object_domain.h:82
CLASS_STATS * stats
Definition: class_object.h:747
int pkeys_size
Definition: statistics.h:66
void stats_dump(const char *class_name_p, FILE *file_p)
TP_DOMAIN * key_type
Definition: statistics.h:65
int stats_get_statistics(OID *class_oid_p, unsigned int time_stamp, CLASS_STATS **stats_p)
Definition: statistics_cl.c:54
const char * sm_get_att_name(MOP classop, int id)
void db_ws_free(void *ptr)
Definition: quick_fit.c:194
void stats_free_statistics(CLASS_STATS *class_statsp)
#define OR_GET_BTID(ptr, btid)
#define assert(x)
int * pkeys
Definition: statistics.h:67
int32_t fileid
Definition: dbtype_def.h:886
int tp_domain_size(const TP_DOMAIN *domain)
#define BTREE_STATS_PKEYS_NUM
Definition: statistics.h:41
#define TP_DOMAIN_TYPE(dom)
#define NULL
Definition: freelistheap.h:34
VFID vfid
int stats_get_statistics_from_server(OID *classoid, unsigned int timestamp, int *length_ptr, char **stats_buffer)
static void error(const char *msg)
Definition: gencat.c:331
static CLASS_STATS * stats_client_unpack_statistics(char *buffer)
Definition: statistics_cl.c:83
unsigned int time_stamp
Definition: statistics.h:88
BTREE_STATS * bt_stats
Definition: statistics.h:81
#define OR_GET_INT(ptr)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
void * db_ws_alloc(size_t size)
Definition: quick_fit.c:73
SM_CLASS * sm_get_class_with_statistics(MOP classop)
int i
Definition: dynamic_load.c:954
int has_function
Definition: statistics.h:64
int heap_num_pages
Definition: statistics.h:90
int heap_num_objects
Definition: statistics.h:89
short volid
Definition: dbtype_def.h:887
MOP sm_find_class(const char *name)
char * or_unpack_domain(char *ptr, struct tp_domain **domain_ptr, int *is_null)
ATTR_STATS * attr_stats
Definition: statistics.h:92
DB_TYPE type
Definition: statistics.h:79