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 31char * 32get_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 54char * 55get_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 77int assert_level = 0; // set to 1 to bypass problematic asserts 78 79#define ASSERT_SKIP (assert_level) 80 81/* 82 * class PropDescr 83 */ 84 85PropDescr::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 96PropDescr::~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 112void 113PropDescr::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 125char * 126PropDescr::getStateName (int value) 127{ 128 if (stateNames && value >= 0 && value < stateNames->size ()) 129 return stateNames->fetch (value); 130 return NULL; 131} 132 133char * 134PropDescr::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 145FieldDescr::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 154FieldDescr::~FieldDescr () 155{ 156 free (name); 157 free (format); 158} 159 160/* 161 * class PacketDescriptor 162 */ 163 164PacketDescriptor::PacketDescriptor (DataDescriptor *_ddscr) 165{ 166 ddscr = _ddscr; 167 fields = new Vector<FieldDescr*>; 168} 169 170PacketDescriptor::~PacketDescriptor () 171{ 172 fields->destroy (); 173 delete fields; 174} 175 176void 177PacketDescriptor::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 */ 189static void 190checkCompatibility (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 216class DataINT32 : public Data 217{ 218public: 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 321private: 322 Vector<int32_t> *data; 323}; 324 325class DataUINT32 : public Data 326{ 327public: 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 430private: 431 Vector<uint32_t> *data; 432}; 433 434class DataINT64 : public Data 435{ 436public: 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 539private: 540 Vector<int64_t> *data; 541}; 542 543class DataUINT64 : public Data 544{ 545public: 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 648private: 649 Vector<uint64_t> *data; 650}; 651 652class DataOBJECT : public Data 653{ 654public: 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 763private: 764 VType_type dtype; 765 Vector<void*> *data; 766}; 767 768class DataSTRING : public Data 769{ 770public: 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 868private: 869 Vector<char*> *data; 870}; 871 872class DataDOUBLE : public Data 873{ 874public: 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 975private: 976 Vector<double> *data; 977}; 978 979Data * 980Data::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 */ 1006DataDescriptor::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 1027DataDescriptor::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 1048DataDescriptor::~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 1062void 1063DataDescriptor::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 1079PropDescr * 1080DataDescriptor::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 1091Data * 1092DataDescriptor::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 1099void 1100DataDescriptor::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 1118long 1119DataDescriptor::addRecord () 1120{ 1121 if (!isMaster) 1122 return -1; 1123 return master_size++; 1124} 1125 1126static void 1127checkEntity (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 1146void 1147DataDescriptor::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 1164void 1165DataDescriptor::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 1179void 1180DataDescriptor::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 1189DataView * 1190DataDescriptor::createView () 1191{ 1192 return new DataView (this); 1193} 1194 1195DataView * 1196DataDescriptor::createImmutableView () 1197{ 1198 return new DataView (this, DataView::DV_IMMUTABLE); 1199} 1200 1201DataView * 1202DataDescriptor::createExtManagedView () 1203{ 1204 return new DataView (this, DataView::DV_EXT_MANAGED); 1205} 1206 1207int 1208DataDescriptor::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 1216unsigned long long 1217DataDescriptor::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 1225long long 1226DataDescriptor::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 1234void * 1235DataDescriptor::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 1243static int 1244pcmp (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 1261Vector<long long> * 1262DataDescriptor::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 */ 1284DataView::DataView (DataDescriptor *_ddscr) 1285{ 1286 init (_ddscr, DV_NORMAL); 1287} 1288 1289DataView::DataView (DataDescriptor *_ddscr, DataViewType _type) 1290{ 1291 init (_ddscr, _type); 1292} 1293 1294void 1295DataView::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 1316DataView::~DataView () 1317{ 1318 delete filter; 1319 delete index; 1320} 1321 1322void 1323DataView::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 1333void 1334DataView::setDataDescriptorValue (int prop_id, long pkt_id, uint64_t val) 1335{ 1336 ddscr->setValue (prop_id, pkt_id, val); 1337} 1338 1339long long 1340DataView::getDataDescriptorValue (int prop_id, long pkt_id) 1341{ 1342 return ddscr->getLongValue (prop_id, pkt_id); 1343} 1344 1345Vector<PropDescr*>* 1346DataView::getProps () 1347{ 1348 return ddscr->getProps (); 1349}; 1350 1351PropDescr* 1352DataView::getProp (int prop_id) 1353{ 1354 return ddscr->getProp (prop_id); 1355}; 1356 1357void 1358DataView::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 1377bool 1378DataView::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 1411long 1412DataView::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 1424void 1425DataView::setDatumValue (int prop_id, long idx, const Datum *val) 1426{ 1427 ddscr->setDatumValue (prop_id, getIdByIdx (idx), val); 1428} 1429 1430void 1431DataView::setValue (int prop_id, long idx, uint64_t val) 1432{ 1433 ddscr->setValue (prop_id, getIdByIdx (idx), val); 1434} 1435 1436void 1437DataView::setObjValue (int prop_id, long idx, void *val) 1438{ 1439 ddscr->setObjValue (prop_id, getIdByIdx (idx), val); 1440} 1441 1442int 1443DataView::getIntValue (int prop_id, long idx) 1444{ 1445 return ddscr->getIntValue (prop_id, getIdByIdx (idx)); 1446} 1447 1448unsigned long long 1449DataView::getULongValue (int prop_id, long idx) 1450{ 1451 return ddscr->getULongValue (prop_id, getIdByIdx (idx)); 1452} 1453 1454long long 1455DataView::getLongValue (int prop_id, long idx) 1456{ 1457 return ddscr->getLongValue (prop_id, getIdByIdx (idx)); 1458} 1459 1460void * 1461DataView::getObjValue (int prop_id, long idx) 1462{ 1463 return ddscr->getObjValue (prop_id, getIdByIdx (idx)); 1464} 1465 1466void 1467DataView::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 1494void 1495DataView::sort (int prop0) 1496{ 1497 sort (&prop0, 1); 1498} 1499 1500void 1501DataView::sort (int prop0, int prop1) 1502{ 1503 int props[2] = {prop0, prop1}; 1504 sort (props, 2); 1505} 1506 1507void 1508DataView::sort (int prop0, int prop1, int prop2) 1509{ 1510 int props[3] = {prop0, prop1, prop2}; 1511 sort (props, 3); 1512} 1513 1514void 1515DataView::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 1529long 1530DataView::getIdByIdx (long idx) 1531{ 1532 if (index == NULL) 1533 return idx; 1534 return index->fetch (idx); 1535} 1536 1537static int 1538tvalcmp (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 1555static void 1556checkSortTypes (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 1573bool 1574DataView::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 1602long 1603DataView::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 1609long 1610DataView::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 1682void 1683DataView::removeDbeViewIdx (long idx) 1684{ 1685 index->remove (idx); 1686} 1687 1688