1 /* Copyright (C) 2021-2024 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 * 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 * 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 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 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 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 * 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 * 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 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 154 FieldDescr::~FieldDescr () 155 { 156 free (name); 157 free (format); 158 } 159 160 /* 161 * class PacketDescriptor 162 */ 163 164 PacketDescriptor::PacketDescriptor (DataDescriptor *_ddscr) 165 { 166 ddscr = _ddscr; 167 fields = new Vector<FieldDescr*>; 168 } 169 170 PacketDescriptor::~PacketDescriptor () 171 { 172 fields->destroy (); 173 delete fields; 174 } 175 176 void 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 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 220 DataINT32 () 221 { 222 data = new Vector<int32_t>; 223 } 224 225 virtual 226 ~DataINT32 () 227 { 228 delete data; 229 } 230 231 virtual VType_type 232 type () 233 { 234 return TYPE_INT32; 235 } 236 237 virtual void 238 reset () 239 { 240 data->reset (); 241 } 242 243 virtual long 244 getSize () 245 { 246 return data->size (); 247 } 248 249 virtual int 250 fetchInt (long i) 251 { 252 return (int) data->fetch (i); 253 } 254 255 virtual unsigned long long 256 fetchULong (long i) 257 { 258 return (unsigned long long) data->fetch (i); 259 } 260 261 virtual long long 262 fetchLong (long i) 263 { 264 return (long long) data->fetch (i); 265 } 266 267 virtual char * 268 fetchString (long i) 269 { 270 return dbe_sprintf (NTXT ("%d"), data->fetch (i)); 271 } 272 273 virtual double 274 fetchDouble (long i) 275 { 276 return (double) data->fetch (i); 277 } 278 279 virtual void * 280 fetchObject (long) 281 { 282 assert (ASSERT_SKIP); 283 return NULL; 284 } 285 286 virtual void 287 setDatumValue (long idx, const Datum *val) 288 { 289 data->store (idx, val->i); 290 } 291 292 virtual void 293 setValue (long idx, uint64_t val) 294 { 295 data->store (idx, (int32_t) val); 296 } 297 298 virtual void 299 setObjValue (long, void*) 300 { 301 assert (ASSERT_SKIP); 302 return; 303 } 304 305 virtual int 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 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 329 DataUINT32 () 330 { 331 data = new Vector<uint32_t>; 332 } 333 334 virtual 335 ~DataUINT32 () 336 { 337 delete data; 338 } 339 340 virtual VType_type 341 type () 342 { 343 return TYPE_UINT32; 344 } 345 346 virtual void 347 reset () 348 { 349 data->reset (); 350 } 351 352 virtual long 353 getSize () 354 { 355 return data->size (); 356 } 357 358 virtual int 359 fetchInt (long i) 360 { 361 return (int) data->fetch (i); 362 } 363 364 virtual unsigned long long 365 fetchULong (long i) 366 { 367 return (unsigned long long) data->fetch (i); 368 } 369 370 virtual long long 371 fetchLong (long i) 372 { 373 return (long long) data->fetch (i); 374 } 375 376 virtual char * 377 fetchString (long i) 378 { 379 return dbe_sprintf (NTXT ("%u"), data->fetch (i)); 380 } 381 382 virtual double 383 fetchDouble (long i) 384 { 385 return (double) data->fetch (i); 386 } 387 388 virtual void * 389 fetchObject (long) 390 { 391 assert (ASSERT_SKIP); 392 return NULL; 393 } 394 395 virtual void 396 setDatumValue (long idx, const Datum *val) 397 { 398 data->store (idx, val->i); 399 } 400 401 virtual void 402 setValue (long idx, uint64_t val) 403 { 404 data->store (idx, (uint32_t) val); 405 } 406 407 virtual void 408 setObjValue (long, void*) 409 { 410 assert (ASSERT_SKIP); 411 return; 412 } 413 414 virtual int 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 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 438 DataINT64 () 439 { 440 data = new Vector<int64_t>; 441 } 442 443 virtual 444 ~DataINT64 () 445 { 446 delete data; 447 } 448 449 virtual VType_type 450 type () 451 { 452 return TYPE_INT64; 453 } 454 455 virtual void 456 reset () 457 { 458 data->reset (); 459 } 460 461 virtual long 462 getSize () 463 { 464 return data->size (); 465 } 466 467 virtual int 468 fetchInt (long i) 469 { 470 return (int) data->fetch (i); 471 } 472 473 virtual unsigned long long 474 fetchULong (long i) 475 { 476 return (unsigned long long) data->fetch (i); 477 } 478 479 virtual long long 480 fetchLong (long i) 481 { 482 return (long long) data->fetch (i); 483 } 484 485 virtual char * 486 fetchString (long i) 487 { 488 return dbe_sprintf (NTXT ("%lld"), (long long) data->fetch (i)); 489 } 490 491 virtual double 492 fetchDouble (long i) 493 { 494 return (double) data->fetch (i); 495 } 496 497 virtual void * 498 fetchObject (long) 499 { 500 assert (ASSERT_SKIP); 501 return NULL; 502 } 503 504 virtual void 505 setDatumValue (long idx, const Datum *val) 506 { 507 data->store (idx, val->ll); 508 } 509 510 virtual void 511 setValue (long idx, uint64_t val) 512 { 513 data->store (idx, (int64_t) val); 514 } 515 516 virtual void 517 setObjValue (long, void*) 518 { 519 assert (ASSERT_SKIP); 520 return; 521 } 522 523 virtual int 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 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 547 DataUINT64 () 548 { 549 data = new Vector<uint64_t>; 550 } 551 552 virtual 553 ~DataUINT64 () 554 { 555 delete data; 556 } 557 558 virtual VType_type 559 type () 560 { 561 return TYPE_UINT64; 562 } 563 564 virtual void 565 reset () 566 { 567 data->reset (); 568 } 569 570 virtual long 571 getSize () 572 { 573 return data->size (); 574 } 575 576 virtual int 577 fetchInt (long i) 578 { 579 return (int) data->fetch (i); 580 } 581 582 virtual unsigned long long 583 fetchULong (long i) 584 { 585 return (unsigned long long) data->fetch (i); 586 } 587 588 virtual long long 589 fetchLong (long i) 590 { 591 return (long long) data->fetch (i); 592 } 593 594 virtual char * 595 fetchString (long i) 596 { 597 return dbe_sprintf (NTXT ("%llu"), (long long) data->fetch (i)); 598 } 599 600 virtual double 601 fetchDouble (long i) 602 { 603 return (double) data->fetch (i); 604 } 605 606 virtual void * 607 fetchObject (long) 608 { 609 assert (ASSERT_SKIP); 610 return NULL; 611 } 612 613 virtual void 614 setDatumValue (long idx, const Datum *val) 615 { 616 data->store (idx, val->ll); 617 } 618 619 virtual void 620 setValue (long idx, uint64_t val) 621 { 622 data->store (idx, val); 623 } 624 625 virtual void 626 setObjValue (long, void*) 627 { 628 assert (ASSERT_SKIP); 629 return; 630 } 631 632 virtual int 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 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 656 DataOBJECT () 657 { 658 dtype = TYPE_OBJ; 659 data = new Vector<void*>; 660 } 661 662 DataOBJECT (VType_type _dtype) 663 { 664 dtype = _dtype; 665 data = new Vector<void*>; 666 } 667 668 virtual 669 ~DataOBJECT () 670 { 671 delete data; 672 } 673 674 virtual VType_type 675 type () 676 { 677 return dtype; 678 } 679 680 virtual void 681 reset () 682 { 683 data->reset (); 684 } 685 686 virtual long 687 getSize () 688 { 689 return data->size (); 690 } 691 692 virtual int 693 fetchInt (long) 694 { 695 assert (ASSERT_SKIP); 696 return 0; 697 } 698 699 virtual unsigned long long 700 fetchULong (long) 701 { 702 assert (ASSERT_SKIP); 703 return 0LL; 704 } 705 706 virtual long long 707 fetchLong (long) 708 { 709 assert (ASSERT_SKIP); 710 return 0LL; 711 } 712 713 virtual char * 714 fetchString (long i) 715 { 716 return dbe_sprintf (NTXT ("%lu"), (unsigned long) data->fetch (i)); 717 } 718 719 virtual double 720 fetchDouble (long) 721 { 722 assert (ASSERT_SKIP); 723 return 0.0; 724 } 725 726 virtual void * 727 fetchObject (long i) 728 { 729 return data->fetch (i); 730 } 731 732 virtual void 733 setDatumValue (long idx, const Datum *val) 734 { 735 data->store (idx, val->p); 736 } 737 738 virtual void 739 setValue (long, uint64_t) 740 { 741 assert (ASSERT_SKIP); 742 return; 743 } 744 745 virtual void 746 setObjValue (long idx, void *p) 747 { 748 data->store (idx, p); 749 } 750 751 virtual int 752 cmpValues (long, long) 753 { 754 return 0; 755 } 756 757 virtual int 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 772 DataSTRING () 773 { 774 data = new Vector<char*>; 775 } 776 777 virtual 778 ~DataSTRING () 779 { 780 data->destroy (); 781 delete data; 782 } 783 784 virtual VType_type 785 type () 786 { 787 return TYPE_STRING; 788 } 789 790 virtual void 791 reset () 792 { 793 data->reset (); 794 } 795 796 virtual long 797 getSize () 798 { 799 return data->size (); 800 } 801 802 virtual int 803 fetchInt (long) 804 { 805 return 0; 806 } 807 808 virtual unsigned long long 809 fetchULong (long) 810 { 811 return 0LL; 812 } 813 814 virtual long long 815 fetchLong (long) 816 { 817 return 0LL; 818 } 819 820 virtual char * 821 fetchString (long i) 822 { 823 return strdup (data->fetch (i)); 824 } 825 826 virtual double 827 fetchDouble (long) 828 { 829 return 0.0; 830 } 831 832 virtual void * 833 fetchObject (long i) 834 { 835 return data->fetch (i); 836 } 837 838 virtual void 839 setDatumValue (long idx, const Datum *val) 840 { 841 data->store (idx, val->l); 842 } 843 844 virtual void 845 setValue (long, uint64_t) 846 { 847 return; 848 } 849 850 virtual void 851 setObjValue (long idx, void *p) 852 { 853 data->store (idx, (char*) p); 854 } 855 856 virtual int 857 cmpValues (long, long) 858 { 859 return 0; 860 } 861 862 virtual int 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 876 DataDOUBLE () 877 { 878 data = new Vector<double>; 879 } 880 881 virtual 882 ~DataDOUBLE () 883 { 884 delete data; 885 } 886 887 virtual VType_type 888 type () 889 { 890 return TYPE_DOUBLE; 891 } 892 893 virtual void 894 reset () 895 { 896 data->reset (); 897 } 898 899 virtual long 900 getSize () 901 { 902 return data->size (); 903 } 904 905 virtual int 906 fetchInt (long i) 907 { 908 return (int) data->fetch (i); 909 } 910 911 virtual unsigned long long 912 fetchULong (long i) 913 { 914 return (unsigned long long) data->fetch (i); 915 } 916 917 virtual long long 918 fetchLong (long i) 919 { 920 return (long long) data->fetch (i); 921 } 922 923 virtual char * 924 fetchString (long i) 925 { 926 return dbe_sprintf (NTXT ("%f"), data->fetch (i)); 927 } 928 929 virtual double 930 fetchDouble (long i) 931 { 932 return data->fetch (i); 933 } 934 935 virtual void 936 setDatumValue (long idx, const Datum *val) 937 { 938 data->store (idx, val->d); 939 } 940 941 virtual void 942 setValue (long idx, uint64_t val) 943 { 944 data->store (idx, (double) val); 945 } 946 947 virtual void 948 setObjValue (long, void*) 949 { 950 return; 951 } 952 953 virtual void * 954 fetchObject (long) 955 { 956 return NULL; 957 } 958 959 virtual int 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 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 * 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 */ 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 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 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 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 * 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 * 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 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 1119 DataDescriptor::addRecord () 1120 { 1121 if (!isMaster) 1122 return -1; 1123 return master_size++; 1124 } 1125 1126 static void 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 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 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 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 * 1190 DataDescriptor::createView () 1191 { 1192 return new DataView (this); 1193 } 1194 1195 DataView * 1196 DataDescriptor::createImmutableView () 1197 { 1198 return new DataView (this, DataView::DV_IMMUTABLE); 1199 } 1200 1201 DataView * 1202 DataDescriptor::createExtManagedView () 1203 { 1204 return new DataView (this, DataView::DV_EXT_MANAGED); 1205 } 1206 1207 int 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 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 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 * 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 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> * 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 */ 1284 DataView::DataView (DataDescriptor *_ddscr) 1285 { 1286 init (_ddscr, DV_NORMAL); 1287 } 1288 1289 DataView::DataView (DataDescriptor *_ddscr, DataViewType _type) 1290 { 1291 init (_ddscr, _type); 1292 } 1293 1294 void 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 1316 DataView::~DataView () 1317 { 1318 delete filter; 1319 delete index; 1320 } 1321 1322 void 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 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 1340 DataView::getDataDescriptorValue (int prop_id, long pkt_id) 1341 { 1342 return ddscr->getLongValue (prop_id, pkt_id); 1343 } 1344 1345 Vector<PropDescr*>* 1346 DataView::getProps () 1347 { 1348 return ddscr->getProps (); 1349 }; 1350 1351 PropDescr* 1352 DataView::getProp (int prop_id) 1353 { 1354 return ddscr->getProp (prop_id); 1355 }; 1356 1357 void 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 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 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 1425 DataView::setDatumValue (int prop_id, long idx, const Datum *val) 1426 { 1427 ddscr->setDatumValue (prop_id, getIdByIdx (idx), val); 1428 } 1429 1430 void 1431 DataView::setValue (int prop_id, long idx, uint64_t val) 1432 { 1433 ddscr->setValue (prop_id, getIdByIdx (idx), val); 1434 } 1435 1436 void 1437 DataView::setObjValue (int prop_id, long idx, void *val) 1438 { 1439 ddscr->setObjValue (prop_id, getIdByIdx (idx), val); 1440 } 1441 1442 int 1443 DataView::getIntValue (int prop_id, long idx) 1444 { 1445 return ddscr->getIntValue (prop_id, getIdByIdx (idx)); 1446 } 1447 1448 unsigned long long 1449 DataView::getULongValue (int prop_id, long idx) 1450 { 1451 return ddscr->getULongValue (prop_id, getIdByIdx (idx)); 1452 } 1453 1454 long long 1455 DataView::getLongValue (int prop_id, long idx) 1456 { 1457 return ddscr->getLongValue (prop_id, getIdByIdx (idx)); 1458 } 1459 1460 void * 1461 DataView::getObjValue (int prop_id, long idx) 1462 { 1463 return ddscr->getObjValue (prop_id, getIdByIdx (idx)); 1464 } 1465 1466 void 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 1495 DataView::sort (int prop0) 1496 { 1497 sort (&prop0, 1); 1498 } 1499 1500 void 1501 DataView::sort (int prop0, int prop1) 1502 { 1503 int props[2] = {prop0, prop1}; 1504 sort (props, 2); 1505 } 1506 1507 void 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 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 1530 DataView::getIdByIdx (long idx) 1531 { 1532 if (index == NULL) 1533 return idx; 1534 return index->fetch (idx); 1535 } 1536 1537 static int 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 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 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 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 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 1683 DataView::removeDbeViewIdx (long idx) 1684 { 1685 index->remove (idx); 1686 } 1687 1688