1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #include "config.h"
22 #include <stdio.h>
23
24 #include "IndexMap2D.h"
25 #include "DbeSession.h"
26 #include "FilterExp.h"
27 #include "Table.h"
28 #include "util.h"
29 #include "i18n.h"
30
31 char *
get_prof_data_type_name(int t)32 get_prof_data_type_name (int t)
33 {
34 switch (t)
35 {
36 case DATA_SAMPLE: return NTXT("PROFDATA_TYPE_SAMPLE");
37 case DATA_GCEVENT: return NTXT("PROFDATA_TYPE_GCEVENT");
38 case DATA_HEAPSZ: return NTXT("PROFDATA_TYPE_HEAPSZ");
39 case DATA_CLOCK: return NTXT("PROFDATA_TYPE_CLOCK");
40 case DATA_HWC: return NTXT("PROFDATA_TYPE_HWC");
41 case DATA_SYNCH: return NTXT("PROFDATA_TYPE_SYNCH");
42 case DATA_HEAP: return NTXT("PROFDATA_TYPE_HEAP");
43 case DATA_OMP: return NTXT("PROFDATA_TYPE_OMP");
44 case DATA_OMP2: return NTXT("PROFDATA_TYPE_OMP2");
45 case DATA_OMP3: return NTXT("PROFDATA_TYPE_OMP3");
46 case DATA_OMP4: return NTXT("PROFDATA_TYPE_OMP4");
47 case DATA_OMP5: return NTXT("PROFDATA_TYPE_OMP5");
48 case DATA_IOTRACE: return NTXT("PROFDATA_TYPE_IOTRACE");
49 default: abort ();
50 return NTXT ("PROFDATA_TYPE_ERROR");
51 }
52 }
53
54 char *
get_prof_data_type_uname(int t)55 get_prof_data_type_uname (int t)
56 {
57 switch (t)
58 {
59 case DATA_SAMPLE: return GTXT("Process-wide Resource Utilization");
60 case DATA_GCEVENT: return GTXT("Java Garbage Collection Events");
61 case DATA_HEAPSZ: return GTXT("Heap Size");
62 case DATA_CLOCK: return GTXT("Clock Profiling");
63 case DATA_HWC: return GTXT("HW Counter Profiling");
64 case DATA_SYNCH: return GTXT("Synchronization Tracing");
65 case DATA_HEAP: return GTXT("Heap Tracing");
66 case DATA_OMP: return GTXT("OpenMP Profiling");
67 case DATA_OMP2: return GTXT("OpenMP Profiling");
68 case DATA_OMP3: return GTXT("OpenMP Profiling");
69 case DATA_OMP4: return GTXT("OpenMP Profiling");
70 case DATA_OMP5: return GTXT("OpenMP Profiling");
71 case DATA_IOTRACE: return GTXT("IO Tracing");
72 default: abort ();
73 return NTXT ("PROFDATA_TYPE_ERROR");
74 }
75 }
76
77 int assert_level = 0; // set to 1 to bypass problematic asserts
78
79 #define ASSERT_SKIP (assert_level)
80
81 /*
82 * class PropDescr
83 */
84
PropDescr(int _propID,const char * _name)85 PropDescr::PropDescr (int _propID, const char *_name)
86 {
87 propID = _propID;
88 name = strdup (_name ? _name : NTXT (""));
89 uname = NULL;
90 vtype = TYPE_NONE;
91 flags = 0;
92 stateNames = NULL;
93 stateUNames = NULL;
94 }
95
~PropDescr()96 PropDescr::~PropDescr ()
97 {
98 free (name);
99 free (uname);
100 if (stateNames)
101 {
102 stateNames->destroy ();
103 delete stateNames;
104 }
105 if (stateUNames)
106 {
107 stateUNames->destroy ();
108 delete stateUNames;
109 }
110 }
111
112 void
addState(int value,const char * stname,const char * stuname)113 PropDescr::addState (int value, const char *stname, const char *stuname)
114 {
115 if (value < 0 || stname == NULL)
116 return;
117 if (stateNames == NULL)
118 stateNames = new Vector<char*>;
119 stateNames->store (value, strdup (stname));
120 if (stateUNames == NULL)
121 stateUNames = new Vector<char*>;
122 stateUNames->store (value, strdup (stuname));
123 }
124
125 char *
getStateName(int value)126 PropDescr::getStateName (int value)
127 {
128 if (stateNames && value >= 0 && value < stateNames->size ())
129 return stateNames->fetch (value);
130 return NULL;
131 }
132
133 char *
getStateUName(int value)134 PropDescr::getStateUName (int value)
135 {
136 if (stateUNames && value >= 0 && value < stateUNames->size ())
137 return stateUNames->fetch (value);
138 return NULL;
139 }
140
141 /*
142 * class FieldDescr
143 */
144
FieldDescr(int _propID,const char * _name)145 FieldDescr::FieldDescr (int _propID, const char *_name)
146 {
147 propID = _propID;
148 name = _name ? strdup (_name) : NULL;
149 offset = 0;
150 vtype = TYPE_NONE;
151 format = NULL;
152 }
153
~FieldDescr()154 FieldDescr::~FieldDescr ()
155 {
156 free (name);
157 free (format);
158 }
159
160 /*
161 * class PacketDescriptor
162 */
163
PacketDescriptor(DataDescriptor * _ddscr)164 PacketDescriptor::PacketDescriptor (DataDescriptor *_ddscr)
165 {
166 ddscr = _ddscr;
167 fields = new Vector<FieldDescr*>;
168 }
169
~PacketDescriptor()170 PacketDescriptor::~PacketDescriptor ()
171 {
172 fields->destroy ();
173 delete fields;
174 }
175
176 void
addField(FieldDescr * fldDscr)177 PacketDescriptor::addField (FieldDescr *fldDscr)
178 {
179 if (fldDscr == NULL)
180 return;
181 fields->append (fldDscr);
182 }
183
184 /*
185 * class Data
186 */
187
188 /* Check compatibility between Datum and Data */
189 static void
checkCompatibility(VType_type v1,VType_type v2)190 checkCompatibility (VType_type v1, VType_type v2)
191 {
192 switch (v1)
193 {
194 case TYPE_NONE:
195 case TYPE_STRING:
196 case TYPE_DOUBLE:
197 case TYPE_OBJ:
198 case TYPE_DATE:
199 assert (v1 == v2);
200 break;
201 case TYPE_INT32:
202 case TYPE_UINT32:
203 assert (v2 == TYPE_INT32 ||
204 v2 == TYPE_UINT32);
205 break;
206 case TYPE_INT64:
207 case TYPE_UINT64:
208 assert (v2 == TYPE_INT64 ||
209 v2 == TYPE_UINT64);
210 break;
211 default:
212 assert (0);
213 }
214 }
215
216 class DataINT32 : public Data
217 {
218 public:
219
DataINT32()220 DataINT32 ()
221 {
222 data = new Vector<int32_t>;
223 }
224
225 virtual
~DataINT32()226 ~DataINT32 ()
227 {
228 delete data;
229 }
230
231 virtual VType_type
type()232 type ()
233 {
234 return TYPE_INT32;
235 }
236
237 virtual void
reset()238 reset ()
239 {
240 data->reset ();
241 }
242
243 virtual long
getSize()244 getSize ()
245 {
246 return data->size ();
247 }
248
249 virtual int
fetchInt(long i)250 fetchInt (long i)
251 {
252 return (int) data->fetch (i);
253 }
254
255 virtual unsigned long long
fetchULong(long i)256 fetchULong (long i)
257 {
258 return (unsigned long long) data->fetch (i);
259 }
260
261 virtual long long
fetchLong(long i)262 fetchLong (long i)
263 {
264 return (long long) data->fetch (i);
265 }
266
267 virtual char *
fetchString(long i)268 fetchString (long i)
269 {
270 return dbe_sprintf (NTXT ("%d"), data->fetch (i));
271 }
272
273 virtual double
fetchDouble(long i)274 fetchDouble (long i)
275 {
276 return (double) data->fetch (i);
277 }
278
279 virtual void *
fetchObject(long)280 fetchObject (long)
281 {
282 assert (ASSERT_SKIP);
283 return NULL;
284 }
285
286 virtual void
setDatumValue(long idx,const Datum * val)287 setDatumValue (long idx, const Datum *val)
288 {
289 data->store (idx, val->i);
290 }
291
292 virtual void
setValue(long idx,uint64_t val)293 setValue (long idx, uint64_t val)
294 {
295 data->store (idx, (int32_t) val);
296 }
297
298 virtual void
setObjValue(long,void *)299 setObjValue (long, void*)
300 {
301 assert (ASSERT_SKIP);
302 return;
303 }
304
305 virtual int
cmpValues(long idx1,long idx2)306 cmpValues (long idx1, long idx2)
307 {
308 int32_t i1 = data->fetch (idx1);
309 int32_t i2 = data->fetch (idx2);
310 return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
311 }
312
313 virtual int
cmpDatumValue(long idx,const Datum * val)314 cmpDatumValue (long idx, const Datum *val)
315 {
316 int32_t i1 = data->fetch (idx);
317 int32_t i2 = val->i;
318 return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
319 }
320
321 private:
322 Vector<int32_t> *data;
323 };
324
325 class DataUINT32 : public Data
326 {
327 public:
328
DataUINT32()329 DataUINT32 ()
330 {
331 data = new Vector<uint32_t>;
332 }
333
334 virtual
~DataUINT32()335 ~DataUINT32 ()
336 {
337 delete data;
338 }
339
340 virtual VType_type
type()341 type ()
342 {
343 return TYPE_UINT32;
344 }
345
346 virtual void
reset()347 reset ()
348 {
349 data->reset ();
350 }
351
352 virtual long
getSize()353 getSize ()
354 {
355 return data->size ();
356 }
357
358 virtual int
fetchInt(long i)359 fetchInt (long i)
360 {
361 return (int) data->fetch (i);
362 }
363
364 virtual unsigned long long
fetchULong(long i)365 fetchULong (long i)
366 {
367 return (unsigned long long) data->fetch (i);
368 }
369
370 virtual long long
fetchLong(long i)371 fetchLong (long i)
372 {
373 return (long long) data->fetch (i);
374 }
375
376 virtual char *
fetchString(long i)377 fetchString (long i)
378 {
379 return dbe_sprintf (NTXT ("%u"), data->fetch (i));
380 }
381
382 virtual double
fetchDouble(long i)383 fetchDouble (long i)
384 {
385 return (double) data->fetch (i);
386 }
387
388 virtual void *
fetchObject(long)389 fetchObject (long)
390 {
391 assert (ASSERT_SKIP);
392 return NULL;
393 }
394
395 virtual void
setDatumValue(long idx,const Datum * val)396 setDatumValue (long idx, const Datum *val)
397 {
398 data->store (idx, val->i);
399 }
400
401 virtual void
setValue(long idx,uint64_t val)402 setValue (long idx, uint64_t val)
403 {
404 data->store (idx, (uint32_t) val);
405 }
406
407 virtual void
setObjValue(long,void *)408 setObjValue (long, void*)
409 {
410 assert (ASSERT_SKIP);
411 return;
412 }
413
414 virtual int
cmpValues(long idx1,long idx2)415 cmpValues (long idx1, long idx2)
416 {
417 uint32_t u1 = data->fetch (idx1);
418 uint32_t u2 = data->fetch (idx2);
419 return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
420 }
421
422 virtual int
cmpDatumValue(long idx,const Datum * val)423 cmpDatumValue (long idx, const Datum *val)
424 {
425 uint32_t u1 = data->fetch (idx);
426 uint32_t u2 = (uint32_t) val->i;
427 return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
428 }
429
430 private:
431 Vector<uint32_t> *data;
432 };
433
434 class DataINT64 : public Data
435 {
436 public:
437
DataINT64()438 DataINT64 ()
439 {
440 data = new Vector<int64_t>;
441 }
442
443 virtual
~DataINT64()444 ~DataINT64 ()
445 {
446 delete data;
447 }
448
449 virtual VType_type
type()450 type ()
451 {
452 return TYPE_INT64;
453 }
454
455 virtual void
reset()456 reset ()
457 {
458 data->reset ();
459 }
460
461 virtual long
getSize()462 getSize ()
463 {
464 return data->size ();
465 }
466
467 virtual int
fetchInt(long i)468 fetchInt (long i)
469 {
470 return (int) data->fetch (i);
471 }
472
473 virtual unsigned long long
fetchULong(long i)474 fetchULong (long i)
475 {
476 return (unsigned long long) data->fetch (i);
477 }
478
479 virtual long long
fetchLong(long i)480 fetchLong (long i)
481 {
482 return (long long) data->fetch (i);
483 }
484
485 virtual char *
fetchString(long i)486 fetchString (long i)
487 {
488 return dbe_sprintf (NTXT ("%lld"), (long long) data->fetch (i));
489 }
490
491 virtual double
fetchDouble(long i)492 fetchDouble (long i)
493 {
494 return (double) data->fetch (i);
495 }
496
497 virtual void *
fetchObject(long)498 fetchObject (long)
499 {
500 assert (ASSERT_SKIP);
501 return NULL;
502 }
503
504 virtual void
setDatumValue(long idx,const Datum * val)505 setDatumValue (long idx, const Datum *val)
506 {
507 data->store (idx, val->ll);
508 }
509
510 virtual void
setValue(long idx,uint64_t val)511 setValue (long idx, uint64_t val)
512 {
513 data->store (idx, (int64_t) val);
514 }
515
516 virtual void
setObjValue(long,void *)517 setObjValue (long, void*)
518 {
519 assert (ASSERT_SKIP);
520 return;
521 }
522
523 virtual int
cmpValues(long idx1,long idx2)524 cmpValues (long idx1, long idx2)
525 {
526 int64_t i1 = data->fetch (idx1);
527 int64_t i2 = data->fetch (idx2);
528 return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
529 }
530
531 virtual int
cmpDatumValue(long idx,const Datum * val)532 cmpDatumValue (long idx, const Datum *val)
533 {
534 int64_t i1 = data->fetch (idx);
535 int64_t i2 = val->ll;
536 return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
537 }
538
539 private:
540 Vector<int64_t> *data;
541 };
542
543 class DataUINT64 : public Data
544 {
545 public:
546
DataUINT64()547 DataUINT64 ()
548 {
549 data = new Vector<uint64_t>;
550 }
551
552 virtual
~DataUINT64()553 ~DataUINT64 ()
554 {
555 delete data;
556 }
557
558 virtual VType_type
type()559 type ()
560 {
561 return TYPE_UINT64;
562 }
563
564 virtual void
reset()565 reset ()
566 {
567 data->reset ();
568 }
569
570 virtual long
getSize()571 getSize ()
572 {
573 return data->size ();
574 }
575
576 virtual int
fetchInt(long i)577 fetchInt (long i)
578 {
579 return (int) data->fetch (i);
580 }
581
582 virtual unsigned long long
fetchULong(long i)583 fetchULong (long i)
584 {
585 return (unsigned long long) data->fetch (i);
586 }
587
588 virtual long long
fetchLong(long i)589 fetchLong (long i)
590 {
591 return (long long) data->fetch (i);
592 }
593
594 virtual char *
fetchString(long i)595 fetchString (long i)
596 {
597 return dbe_sprintf (NTXT ("%llu"), (long long) data->fetch (i));
598 }
599
600 virtual double
fetchDouble(long i)601 fetchDouble (long i)
602 {
603 return (double) data->fetch (i);
604 }
605
606 virtual void *
fetchObject(long)607 fetchObject (long)
608 {
609 assert (ASSERT_SKIP);
610 return NULL;
611 }
612
613 virtual void
setDatumValue(long idx,const Datum * val)614 setDatumValue (long idx, const Datum *val)
615 {
616 data->store (idx, val->ll);
617 }
618
619 virtual void
setValue(long idx,uint64_t val)620 setValue (long idx, uint64_t val)
621 {
622 data->store (idx, val);
623 }
624
625 virtual void
setObjValue(long,void *)626 setObjValue (long, void*)
627 {
628 assert (ASSERT_SKIP);
629 return;
630 }
631
632 virtual int
cmpValues(long idx1,long idx2)633 cmpValues (long idx1, long idx2)
634 {
635 uint64_t u1 = data->fetch (idx1);
636 uint64_t u2 = data->fetch (idx2);
637 return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
638 }
639
640 virtual int
cmpDatumValue(long idx,const Datum * val)641 cmpDatumValue (long idx, const Datum *val)
642 {
643 uint64_t u1 = data->fetch (idx);
644 uint64_t u2 = (uint64_t) val->ll;
645 return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
646 }
647
648 private:
649 Vector<uint64_t> *data;
650 };
651
652 class DataOBJECT : public Data
653 {
654 public:
655
DataOBJECT()656 DataOBJECT ()
657 {
658 dtype = TYPE_OBJ;
659 data = new Vector<void*>;
660 }
661
DataOBJECT(VType_type _dtype)662 DataOBJECT (VType_type _dtype)
663 {
664 dtype = _dtype;
665 data = new Vector<void*>;
666 }
667
668 virtual
~DataOBJECT()669 ~DataOBJECT ()
670 {
671 delete data;
672 }
673
674 virtual VType_type
type()675 type ()
676 {
677 return dtype;
678 }
679
680 virtual void
reset()681 reset ()
682 {
683 data->reset ();
684 }
685
686 virtual long
getSize()687 getSize ()
688 {
689 return data->size ();
690 }
691
692 virtual int
fetchInt(long)693 fetchInt (long)
694 {
695 assert (ASSERT_SKIP);
696 return 0;
697 }
698
699 virtual unsigned long long
fetchULong(long)700 fetchULong (long)
701 {
702 assert (ASSERT_SKIP);
703 return 0LL;
704 }
705
706 virtual long long
fetchLong(long)707 fetchLong (long)
708 {
709 assert (ASSERT_SKIP);
710 return 0LL;
711 }
712
713 virtual char *
fetchString(long i)714 fetchString (long i)
715 {
716 return dbe_sprintf (NTXT ("%lu"), (unsigned long) data->fetch (i));
717 }
718
719 virtual double
fetchDouble(long)720 fetchDouble (long)
721 {
722 assert (ASSERT_SKIP);
723 return 0.0;
724 }
725
726 virtual void *
fetchObject(long i)727 fetchObject (long i)
728 {
729 return data->fetch (i);
730 }
731
732 virtual void
setDatumValue(long idx,const Datum * val)733 setDatumValue (long idx, const Datum *val)
734 {
735 data->store (idx, val->p);
736 }
737
738 virtual void
setValue(long,uint64_t)739 setValue (long, uint64_t)
740 {
741 assert (ASSERT_SKIP);
742 return;
743 }
744
745 virtual void
setObjValue(long idx,void * p)746 setObjValue (long idx, void *p)
747 {
748 data->store (idx, p);
749 }
750
751 virtual int
cmpValues(long,long)752 cmpValues (long, long)
753 {
754 return 0;
755 }
756
757 virtual int
cmpDatumValue(long,const Datum *)758 cmpDatumValue (long, const Datum *)
759 {
760 return 0;
761 }
762
763 private:
764 VType_type dtype;
765 Vector<void*> *data;
766 };
767
768 class DataSTRING : public Data
769 {
770 public:
771
DataSTRING()772 DataSTRING ()
773 {
774 data = new Vector<char*>;
775 }
776
777 virtual
~DataSTRING()778 ~DataSTRING ()
779 {
780 data->destroy ();
781 delete data;
782 }
783
784 virtual VType_type
type()785 type ()
786 {
787 return TYPE_STRING;
788 }
789
790 virtual void
reset()791 reset ()
792 {
793 data->reset ();
794 }
795
796 virtual long
getSize()797 getSize ()
798 {
799 return data->size ();
800 }
801
802 virtual int
fetchInt(long)803 fetchInt (long)
804 {
805 return 0;
806 }
807
808 virtual unsigned long long
fetchULong(long)809 fetchULong (long)
810 {
811 return 0LL;
812 }
813
814 virtual long long
fetchLong(long)815 fetchLong (long)
816 {
817 return 0LL;
818 }
819
820 virtual char *
fetchString(long i)821 fetchString (long i)
822 {
823 return strdup (data->fetch (i));
824 }
825
826 virtual double
fetchDouble(long)827 fetchDouble (long)
828 {
829 return 0.0;
830 }
831
832 virtual void *
fetchObject(long i)833 fetchObject (long i)
834 {
835 return data->fetch (i);
836 }
837
838 virtual void
setDatumValue(long idx,const Datum * val)839 setDatumValue (long idx, const Datum *val)
840 {
841 data->store (idx, val->l);
842 }
843
844 virtual void
setValue(long,uint64_t)845 setValue (long, uint64_t)
846 {
847 return;
848 }
849
850 virtual void
setObjValue(long idx,void * p)851 setObjValue (long idx, void *p)
852 {
853 data->store (idx, (char*) p);
854 }
855
856 virtual int
cmpValues(long,long)857 cmpValues (long, long)
858 {
859 return 0;
860 }
861
862 virtual int
cmpDatumValue(long,const Datum *)863 cmpDatumValue (long, const Datum *)
864 {
865 return 0;
866 }
867
868 private:
869 Vector<char*> *data;
870 };
871
872 class DataDOUBLE : public Data
873 {
874 public:
875
DataDOUBLE()876 DataDOUBLE ()
877 {
878 data = new Vector<double>;
879 }
880
881 virtual
~DataDOUBLE()882 ~DataDOUBLE ()
883 {
884 delete data;
885 }
886
887 virtual VType_type
type()888 type ()
889 {
890 return TYPE_DOUBLE;
891 }
892
893 virtual void
reset()894 reset ()
895 {
896 data->reset ();
897 }
898
899 virtual long
getSize()900 getSize ()
901 {
902 return data->size ();
903 }
904
905 virtual int
fetchInt(long i)906 fetchInt (long i)
907 {
908 return (int) data->fetch (i);
909 }
910
911 virtual unsigned long long
fetchULong(long i)912 fetchULong (long i)
913 {
914 return (unsigned long long) data->fetch (i);
915 }
916
917 virtual long long
fetchLong(long i)918 fetchLong (long i)
919 {
920 return (long long) data->fetch (i);
921 }
922
923 virtual char *
fetchString(long i)924 fetchString (long i)
925 {
926 return dbe_sprintf (NTXT ("%f"), data->fetch (i));
927 }
928
929 virtual double
fetchDouble(long i)930 fetchDouble (long i)
931 {
932 return data->fetch (i);
933 }
934
935 virtual void
setDatumValue(long idx,const Datum * val)936 setDatumValue (long idx, const Datum *val)
937 {
938 data->store (idx, val->d);
939 }
940
941 virtual void
setValue(long idx,uint64_t val)942 setValue (long idx, uint64_t val)
943 {
944 data->store (idx, (double) val);
945 }
946
947 virtual void
setObjValue(long,void *)948 setObjValue (long, void*)
949 {
950 return;
951 }
952
953 virtual void *
fetchObject(long)954 fetchObject (long)
955 {
956 return NULL;
957 }
958
959 virtual int
cmpValues(long idx1,long idx2)960 cmpValues (long idx1, long idx2)
961 {
962 double d1 = data->fetch (idx1);
963 double d2 = data->fetch (idx2);
964 return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
965 }
966
967 virtual int
cmpDatumValue(long idx,const Datum * val)968 cmpDatumValue (long idx, const Datum *val)
969 {
970 double d1 = data->fetch (idx);
971 double d2 = val->d;
972 return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
973 }
974
975 private:
976 Vector<double> *data;
977 };
978
979 Data *
newData(VType_type vtype)980 Data::newData (VType_type vtype)
981 {
982 switch (vtype)
983 {
984 case TYPE_INT32:
985 return new DataINT32;
986 case TYPE_UINT32:
987 return new DataUINT32;
988 case TYPE_INT64:
989 return new DataINT64;
990 case TYPE_UINT64:
991 return new DataUINT64;
992 case TYPE_OBJ:
993 return new DataOBJECT;
994 case TYPE_STRING:
995 return new DataSTRING;
996 case TYPE_DOUBLE:
997 return new DataDOUBLE;
998 default:
999 return NULL;
1000 }
1001 }
1002
1003 /*
1004 * class DataDescriptor
1005 */
DataDescriptor(int _id,const char * _name,const char * _uname,int _flags)1006 DataDescriptor::DataDescriptor (int _id, const char *_name, const char *_uname,
1007 int _flags)
1008 {
1009 isMaster = true;
1010 id = _id;
1011 name = _name ? strdup (_name) : strdup (NTXT (""));
1012 uname = _uname ? strdup (_uname) : strdup (NTXT (""));
1013 flags = _flags;
1014
1015 // master data, shared with reference copies:
1016 master_size = 0;
1017 master_resolveFrameInfoDone = false;
1018 props = new Vector<PropDescr*>;
1019 data = new Vector<Data*>;
1020 setsTBR = new Vector<Vector<long long>*>;
1021
1022 // master references point to self:
1023 ref_size = &master_size;
1024 ref_resolveFrameInfoDone = &master_resolveFrameInfoDone;
1025 }
1026
DataDescriptor(int _id,const char * _name,const char * _uname,DataDescriptor * dDscr)1027 DataDescriptor::DataDescriptor (int _id, const char *_name, const char *_uname,
1028 DataDescriptor* dDscr)
1029 {
1030 isMaster = false;
1031 id = _id;
1032 name = _name ? strdup (_name) : strdup (NTXT (""));
1033 uname = _uname ? strdup (_uname) : strdup (NTXT (""));
1034 flags = dDscr->flags;
1035
1036 // references point to master DataDescriptor
1037 ref_size = &dDscr->master_size;
1038 ref_resolveFrameInfoDone = &dDscr->master_resolveFrameInfoDone;
1039 props = dDscr->props;
1040 data = dDscr->data;
1041 setsTBR = dDscr->setsTBR;
1042
1043 // data that should never be accessed in reference copy
1044 master_size = -1;
1045 master_resolveFrameInfoDone = false;
1046 }
1047
~DataDescriptor()1048 DataDescriptor::~DataDescriptor ()
1049 {
1050 free (name);
1051 free (uname);
1052 if (!isMaster)
1053 return;
1054 props->destroy ();
1055 delete props;
1056 data->destroy ();
1057 delete data;
1058 setsTBR->destroy ();
1059 delete setsTBR;
1060 }
1061
1062 void
reset()1063 DataDescriptor::reset ()
1064 {
1065 if (!isMaster)
1066 return;
1067 for (int i = 0; i < data->size (); i++)
1068 {
1069 Data *d = data->fetch (i);
1070 if (d != NULL)
1071 d->reset ();
1072 Vector<long long> *set = setsTBR->fetch (i);
1073 if (set != NULL)
1074 set->reset ();
1075 }
1076 master_size = 0;
1077 }
1078
1079 PropDescr *
getProp(int prop_id)1080 DataDescriptor::getProp (int prop_id)
1081 {
1082 for (int i = 0; i < props->size (); i++)
1083 {
1084 PropDescr *propDscr = props->fetch (i);
1085 if (propDscr->propID == prop_id)
1086 return propDscr;
1087 }
1088 return NULL;
1089 }
1090
1091 Data *
getData(int prop_id)1092 DataDescriptor::getData (int prop_id)
1093 {
1094 if (prop_id < 0 || prop_id >= data->size ())
1095 return NULL;
1096 return data->fetch (prop_id);
1097 }
1098
1099 void
addProperty(PropDescr * propDscr)1100 DataDescriptor::addProperty (PropDescr *propDscr)
1101 {
1102 if (propDscr == NULL)
1103 return;
1104 if (propDscr->propID < 0)
1105 return;
1106 PropDescr *oldProp = getProp (propDscr->propID);
1107 if (oldProp != NULL)
1108 {
1109 checkCompatibility (propDscr->vtype, oldProp->vtype); //YXXX depends on experiment correctness
1110 delete propDscr;
1111 return;
1112 }
1113 props->append (propDscr);
1114 data->store (propDscr->propID, Data::newData (propDscr->vtype));
1115 setsTBR->store (propDscr->propID, NULL);
1116 }
1117
1118 long
addRecord()1119 DataDescriptor::addRecord ()
1120 {
1121 if (!isMaster)
1122 return -1;
1123 return master_size++;
1124 }
1125
1126 static void
checkEntity(Vector<long long> * set,long long val)1127 checkEntity (Vector<long long> *set, long long val)
1128 {
1129 // Binary search
1130 int lo = 0;
1131 int hi = set->size () - 1;
1132 while (lo <= hi)
1133 {
1134 int md = (lo + hi) / 2;
1135 long long ent = set->fetch (md);
1136 if (ent < val)
1137 lo = md + 1;
1138 else if (ent > val)
1139 hi = md - 1;
1140 else
1141 return;
1142 }
1143 set->insert (lo, val);
1144 }
1145
1146 void
setDatumValue(int prop_id,long idx,const Datum * val)1147 DataDescriptor::setDatumValue (int prop_id, long idx, const Datum *val)
1148 {
1149 if (idx >= *ref_size)
1150 return;
1151 Data *d = getData (prop_id);
1152 if (d != NULL)
1153 {
1154 VType_type datum_type = val->type;
1155 VType_type data_type = d->type ();
1156 checkCompatibility (datum_type, data_type);
1157 d->setDatumValue (idx, val);
1158 Vector<long long> *set = setsTBR->fetch (prop_id);
1159 if (set != NULL)// Sets are maintained
1160 checkEntity (set, d->fetchLong (idx));
1161 }
1162 }
1163
1164 void
setValue(int prop_id,long idx,uint64_t val)1165 DataDescriptor::setValue (int prop_id, long idx, uint64_t val)
1166 {
1167 if (idx >= *ref_size)
1168 return;
1169 Data *d = getData (prop_id);
1170 if (d != NULL)
1171 {
1172 d->setValue (idx, val);
1173 Vector<long long> *set = setsTBR->fetch (prop_id);
1174 if (set != NULL)// Sets are maintained
1175 checkEntity (set, d->fetchLong (idx));
1176 }
1177 }
1178
1179 void
setObjValue(int prop_id,long idx,void * val)1180 DataDescriptor::setObjValue (int prop_id, long idx, void *val)
1181 {
1182 if (idx >= *ref_size)
1183 return;
1184 Data *d = getData (prop_id);
1185 if (d != NULL)
1186 d->setObjValue (idx, val);
1187 }
1188
1189 DataView *
createView()1190 DataDescriptor::createView ()
1191 {
1192 return new DataView (this);
1193 }
1194
1195 DataView *
createImmutableView()1196 DataDescriptor::createImmutableView ()
1197 {
1198 return new DataView (this, DataView::DV_IMMUTABLE);
1199 }
1200
1201 DataView *
createExtManagedView()1202 DataDescriptor::createExtManagedView ()
1203 {
1204 return new DataView (this, DataView::DV_EXT_MANAGED);
1205 }
1206
1207 int
getIntValue(int prop_id,long idx)1208 DataDescriptor::getIntValue (int prop_id, long idx)
1209 {
1210 Data *d = getData (prop_id);
1211 if (d == NULL || idx >= d->getSize ())
1212 return 0;
1213 return d->fetchInt (idx);
1214 }
1215
1216 unsigned long long
getULongValue(int prop_id,long idx)1217 DataDescriptor::getULongValue (int prop_id, long idx)
1218 {
1219 Data *d = getData (prop_id);
1220 if (d == NULL || idx >= d->getSize ())
1221 return 0L;
1222 return d->fetchULong (idx);
1223 }
1224
1225 long long
getLongValue(int prop_id,long idx)1226 DataDescriptor::getLongValue (int prop_id, long idx)
1227 {
1228 Data *d = getData (prop_id);
1229 if (d == NULL || idx >= d->getSize ())
1230 return 0L;
1231 return d->fetchLong (idx);
1232 }
1233
1234 void *
getObjValue(int prop_id,long idx)1235 DataDescriptor::getObjValue (int prop_id, long idx)
1236 {
1237 Data *d = getData (prop_id);
1238 if (d == NULL || idx >= d->getSize ())
1239 return NULL;
1240 return d->fetchObject (idx);
1241 }
1242
1243 static int
pcmp(const void * p1,const void * p2,const void * arg)1244 pcmp (const void *p1, const void *p2, const void *arg)
1245 {
1246 long idx1 = *(long*) p1; // index1 into Data
1247 long idx2 = *(long*) p2; // index2 into Data
1248 for (Data **dsorted = (Data**) arg; *dsorted != DATA_SORT_EOL; dsorted++)
1249 {
1250 Data *data = *dsorted;
1251 if (data == NULL)// sort property not in this data, skip this criteria
1252 continue;
1253 int res = data->cmpValues (idx1, idx2);
1254 if (res)
1255 return res;
1256 }
1257 // Provide stable sort
1258 return idx1 < idx2 ? -1 : idx1 > idx2 ? 1 : 0;
1259 }
1260
1261 Vector<long long> *
getSet(int prop_id)1262 DataDescriptor::getSet (int prop_id)
1263 {
1264 if (prop_id < 0 || prop_id >= setsTBR->size ())
1265 return NULL;
1266 Vector<long long> *set = setsTBR->fetch (prop_id);
1267 if (set != NULL)
1268 return set;
1269
1270 Data *d = getData (prop_id);
1271 if (d == NULL)
1272 return NULL;
1273 set = new Vector<long long>;
1274 for (long i = 0; i<*ref_size; ++i)
1275 checkEntity (set, d->fetchLong (i));
1276 setsTBR->store (prop_id, set);
1277
1278 return set;
1279 }
1280
1281 /*
1282 * class DataView
1283 */
DataView(DataDescriptor * _ddscr)1284 DataView::DataView (DataDescriptor *_ddscr)
1285 {
1286 init (_ddscr, DV_NORMAL);
1287 }
1288
DataView(DataDescriptor * _ddscr,DataViewType _type)1289 DataView::DataView (DataDescriptor *_ddscr, DataViewType _type)
1290 {
1291 init (_ddscr, _type);
1292 }
1293
1294 void
init(DataDescriptor * _ddscr,DataViewType _type)1295 DataView::init (DataDescriptor *_ddscr, DataViewType _type)
1296 {
1297 ddscr = _ddscr;
1298 type = _type;
1299 switch (type)
1300 {
1301 case DV_IMMUTABLE:
1302 ddsize = ddscr->getSize ();
1303 index = NULL;
1304 break;
1305 case DV_NORMAL:
1306 case DV_EXT_MANAGED:
1307 ddsize = 0;
1308 index = new Vector<long>;
1309 break;
1310 }
1311 for (int ii = 0; ii < (MAX_SORT_DIMENSIONS + 1); ii++)
1312 sortedBy[ii] = DATA_SORT_EOL;
1313 filter = NULL;
1314 }
1315
~DataView()1316 DataView::~DataView ()
1317 {
1318 delete filter;
1319 delete index;
1320 }
1321
1322 void
appendDataDescriptorId(long pkt_id)1323 DataView::appendDataDescriptorId (long pkt_id /* ddscr index */)
1324 {
1325 if (type != DV_EXT_MANAGED)
1326 return; // updates allowed only on externally managed DataViews
1327 long curr_ddsize = ddscr->getSize ();
1328 if (pkt_id < 0 || pkt_id >= curr_ddsize)
1329 return; // error!
1330 index->append (pkt_id);
1331 }
1332
1333 void
setDataDescriptorValue(int prop_id,long pkt_id,uint64_t val)1334 DataView::setDataDescriptorValue (int prop_id, long pkt_id, uint64_t val)
1335 {
1336 ddscr->setValue (prop_id, pkt_id, val);
1337 }
1338
1339 long long
getDataDescriptorValue(int prop_id,long pkt_id)1340 DataView::getDataDescriptorValue (int prop_id, long pkt_id)
1341 {
1342 return ddscr->getLongValue (prop_id, pkt_id);
1343 }
1344
1345 Vector<PropDescr*>*
getProps()1346 DataView::getProps ()
1347 {
1348 return ddscr->getProps ();
1349 };
1350
1351 PropDescr*
getProp(int prop_id)1352 DataView::getProp (int prop_id)
1353 {
1354 return ddscr->getProp (prop_id);
1355 };
1356
1357 void
filter_in_chunks(fltr_dbe_ctx * dctx)1358 DataView::filter_in_chunks (fltr_dbe_ctx *dctx)
1359 {
1360 Expression::Context *e_ctx = new Expression::Context (dctx->fltr->ctx->dbev, dctx->fltr->ctx->exp);
1361 Expression *n_expr = dctx->fltr->expr->copy ();
1362 bool noParFilter = dctx->fltr->noParFilter;
1363 FilterExp *nFilter = new FilterExp (n_expr, e_ctx, noParFilter);
1364 long iter = dctx->begin;
1365 long end = dctx->end;
1366 long orig_ddsize = dctx->orig_ddsize;
1367 while (iter < end)
1368 {
1369 nFilter->put (dctx->tmpView, iter);
1370 if (nFilter->passes ())
1371 dctx->idxArr[iter - orig_ddsize] = 1;
1372 iter += 1;
1373 }
1374 delete nFilter;
1375 }
1376
1377 bool
checkUpdate()1378 DataView::checkUpdate ()
1379 {
1380 long newSize = ddscr->getSize ();
1381 if (ddsize == newSize)
1382 return false;
1383 if (index == NULL)
1384 return false;
1385 if (type == DV_EXT_MANAGED)
1386 return false;
1387 bool updated = false;
1388 if (filter)
1389 {
1390 DataView *tmpView = ddscr->createImmutableView ();
1391 assert (tmpView->getSize () == newSize);
1392 while (ddsize < newSize)
1393 {
1394 filter->put (tmpView, ddsize);
1395 if (filter->passes ())
1396 index->append (ddsize);
1397 ddsize += 1;
1398 }
1399 delete tmpView;
1400 return updated;
1401 }
1402 while (ddsize < newSize)
1403 {
1404 index->append (ddsize);
1405 updated = true;
1406 ddsize += 1;
1407 }
1408 return updated;
1409 }
1410
1411 long
getSize()1412 DataView::getSize ()
1413 {
1414 if (checkUpdate () && sortedBy[0] != DATA_SORT_EOL)
1415 // note: after new filter is set, getSize() incurs cost of
1416 // sorting even if caller isn't interested in sort
1417 index->sort ((CompareFunc) pcmp, sortedBy);
1418
1419 if (index == NULL)
1420 return ddscr->getSize ();
1421 return index->size ();
1422 }
1423
1424 void
setDatumValue(int prop_id,long idx,const Datum * val)1425 DataView::setDatumValue (int prop_id, long idx, const Datum *val)
1426 {
1427 ddscr->setDatumValue (prop_id, getIdByIdx (idx), val);
1428 }
1429
1430 void
setValue(int prop_id,long idx,uint64_t val)1431 DataView::setValue (int prop_id, long idx, uint64_t val)
1432 {
1433 ddscr->setValue (prop_id, getIdByIdx (idx), val);
1434 }
1435
1436 void
setObjValue(int prop_id,long idx,void * val)1437 DataView::setObjValue (int prop_id, long idx, void *val)
1438 {
1439 ddscr->setObjValue (prop_id, getIdByIdx (idx), val);
1440 }
1441
1442 int
getIntValue(int prop_id,long idx)1443 DataView::getIntValue (int prop_id, long idx)
1444 {
1445 return ddscr->getIntValue (prop_id, getIdByIdx (idx));
1446 }
1447
1448 unsigned long long
getULongValue(int prop_id,long idx)1449 DataView::getULongValue (int prop_id, long idx)
1450 {
1451 return ddscr->getULongValue (prop_id, getIdByIdx (idx));
1452 }
1453
1454 long long
getLongValue(int prop_id,long idx)1455 DataView::getLongValue (int prop_id, long idx)
1456 {
1457 return ddscr->getLongValue (prop_id, getIdByIdx (idx));
1458 }
1459
1460 void *
getObjValue(int prop_id,long idx)1461 DataView::getObjValue (int prop_id, long idx)
1462 {
1463 return ddscr->getObjValue (prop_id, getIdByIdx (idx));
1464 }
1465
1466 void
sort(const int props[],int prop_count)1467 DataView::sort (const int props[], int prop_count)
1468 {
1469 if (index == NULL)
1470 {
1471 assert (ASSERT_SKIP);
1472 return;
1473 }
1474 assert (prop_count >= 0 && prop_count < MAX_SORT_DIMENSIONS);
1475 bool sort_changed = false; // see if sort has changed...
1476 for (int ii = 0; ii <= prop_count; ii++)
1477 { // sortedBy size is prop_count+1
1478 Data *data;
1479 if (ii == prop_count)
1480 data = DATA_SORT_EOL; // special end of array marker
1481 else
1482 data = ddscr->getData (props[ii]);
1483 if (sortedBy[ii] != data)
1484 {
1485 sortedBy[ii] = data;
1486 sort_changed = true;
1487 }
1488 }
1489 if (!checkUpdate () && !sort_changed)
1490 return;
1491 index->sort ((CompareFunc) pcmp, sortedBy);
1492 }
1493
1494 void
sort(int prop0)1495 DataView::sort (int prop0)
1496 {
1497 sort (&prop0, 1);
1498 }
1499
1500 void
sort(int prop0,int prop1)1501 DataView::sort (int prop0, int prop1)
1502 {
1503 int props[2] = {prop0, prop1};
1504 sort (props, 2);
1505 }
1506
1507 void
sort(int prop0,int prop1,int prop2)1508 DataView::sort (int prop0, int prop1, int prop2)
1509 {
1510 int props[3] = {prop0, prop1, prop2};
1511 sort (props, 3);
1512 }
1513
1514 void
setFilter(FilterExp * f)1515 DataView::setFilter (FilterExp *f)
1516 {
1517 if (index == NULL)
1518 {
1519 assert (ASSERT_SKIP);
1520 return;
1521 }
1522 delete filter;
1523 filter = f;
1524 index->reset ();
1525 ddsize = 0;
1526 checkUpdate ();
1527 }
1528
1529 long
getIdByIdx(long idx)1530 DataView::getIdByIdx (long idx)
1531 {
1532 if (index == NULL)
1533 return idx;
1534 return index->fetch (idx);
1535 }
1536
1537 static int
tvalcmp(long data_id,const Datum valColumns[],Data * sortedBy[])1538 tvalcmp (long data_id, const Datum valColumns[], Data *sortedBy[])
1539 {
1540 for (int ii = 0; ii < MAX_SORT_DIMENSIONS; ii++)
1541 {
1542 if (sortedBy[ii] == DATA_SORT_EOL)
1543 break;
1544 Data *d = sortedBy[ii];
1545 if (d == NULL)// property doesn't exist in data; compare always matches
1546 continue;
1547 const Datum *tvalue = &valColumns[ii];
1548 int res = d->cmpDatumValue (data_id, tvalue);
1549 if (res)
1550 return res;
1551 }
1552 return 0;
1553 }
1554
1555 static void
checkSortTypes(const Datum valColumns[],Data * sortedBy[])1556 checkSortTypes (const Datum valColumns[], Data *sortedBy[])
1557 {
1558 #ifndef NDEBUG
1559 for (int ii = 0; ii < MAX_SORT_DIMENSIONS; ii++)
1560 {
1561 if (sortedBy[ii] == DATA_SORT_EOL)
1562 break;
1563 Data *d = sortedBy[ii];
1564 if (d == NULL)// property doesn't exist in data; compare always matches
1565 continue;
1566 VType_type datum_type = valColumns[ii].type;
1567 VType_type data_type = d->type ();
1568 checkCompatibility (datum_type, data_type);
1569 }
1570 #endif
1571 }
1572
1573 bool
idxRootDimensionsMatch(long idx,const Datum valColumns[])1574 DataView::idxRootDimensionsMatch (long idx, const Datum valColumns[])
1575 {
1576 // compares idx vs. valColumns[] - If all dimensions match
1577 // (except sort leaf), then the leaf value is valid => return true.
1578 // Otherwise, return false.
1579 checkSortTypes (valColumns, sortedBy);
1580 if (idx < 0 || idx >= index->size ()) // fell off end of array
1581 return false;
1582 long data_id = index->fetch (idx);
1583
1584 // we will check all dimensions for a match except the "leaf" dimension
1585 for (int ii = 0; ii < (MAX_SORT_DIMENSIONS - 1); ii++)
1586 {
1587 if (sortedBy[ii + 1] == DATA_SORT_EOL)
1588 break; // we are at leaf dimension, don't care about it's value
1589 if (sortedBy[ii] == DATA_SORT_EOL)
1590 break; // end of list
1591 Data *d = sortedBy[ii];
1592 if (d == NULL) // property doesn't exist in data; compare always matches
1593 continue;
1594 const Datum *tvalue = &valColumns[ii];
1595 int res = d->cmpDatumValue (data_id, tvalue);
1596 if (res)
1597 return false;
1598 }
1599 return true;
1600 }
1601
1602 long
getIdxByVals(const Datum valColumns[],Relation rel)1603 DataView::getIdxByVals (const Datum valColumns[], Relation rel)
1604 {
1605 // checks sortedBy[] columns for match; relation only used on last column
1606 return getIdxByVals (valColumns, rel, -1, -1);
1607 }
1608
1609 long
getIdxByVals(const Datum valColumns[],Relation rel,long minIdx,long maxIdx)1610 DataView::getIdxByVals (const Datum valColumns[], Relation rel,
1611 long minIdx, long maxIdx)
1612 {
1613 // checks sortedBy[] columns for match; relation only used on last column
1614 checkSortTypes (valColumns, sortedBy);
1615 if (index == NULL || sortedBy[0] == DATA_SORT_EOL)
1616 return -1;
1617
1618 long lo;
1619 if (minIdx < 0)
1620 lo = 0;
1621 else
1622 lo = minIdx;
1623
1624 long hi;
1625 if (maxIdx < 0 || maxIdx >= index->size ())
1626 hi = index->size () - 1;
1627 else
1628 hi = maxIdx;
1629
1630 long md = -1;
1631 while (lo <= hi)
1632 {
1633 md = (lo + hi) / 2;
1634 int cmp = tvalcmp (index->fetch (md), valColumns, sortedBy);
1635 if (cmp < 0)
1636 {
1637 lo = md + 1;
1638 continue;
1639 }
1640 else if (cmp > 0)
1641 {
1642 hi = md - 1;
1643 continue;
1644 }
1645
1646 // cmp == 0, we have an exact match
1647 switch (rel)
1648 {
1649 case REL_LT:
1650 hi = md - 1; // continue searching
1651 break;
1652 case REL_GT:
1653 lo = md + 1; // continue searching
1654 break;
1655 case REL_LTEQ:
1656 case REL_GTEQ:
1657 case REL_EQ:
1658 // note: "md" may not be deterministic if multiple matches exist
1659 return md; // a match => done.
1660 }
1661 }
1662
1663 // no exact match found
1664 switch (rel)
1665 {
1666 case REL_LT:
1667 case REL_LTEQ:
1668 md = hi;
1669 break;
1670 case REL_GT:
1671 case REL_GTEQ:
1672 md = lo;
1673 break;
1674 case REL_EQ:
1675 return -1;
1676 }
1677 if (idxRootDimensionsMatch (md, valColumns))
1678 return md;
1679 return -1;
1680 }
1681
1682 void
removeDbeViewIdx(long idx)1683 DataView::removeDbeViewIdx (long idx)
1684 {
1685 index->remove (idx);
1686 }
1687
1688