File indexing completed on 2024-04-28 05:41:25

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 #ifndef COST_H
0010 #define COST_H
0011 
0012 #include <QString>
0013 
0014 #include "subcost.h"
0015 #include "context.h"
0016 #include "utils.h"
0017 
0018 class EventType;
0019 class EventTypeSet;
0020 class EventTypeMapping;
0021 class TracePart;
0022 class TraceData;
0023 
0024 /**
0025  * Base class for cost items.
0026  */
0027 class CostItem
0028 {
0029 public:
0030 
0031     explicit CostItem(ProfileContext*);
0032     virtual ~CostItem();
0033 
0034     ProfileContext* context() const { return _context; }
0035     ProfileContext::Type type() const { return context()->type(); }
0036 
0037     /**
0038      * Returns dynamic name info (without type)
0039      */
0040     virtual QString name() const;
0041 
0042     /**
0043      * Similar to name, but prettyfied = more descriptive to humans
0044      */
0045     virtual QString prettyName() const;
0046 
0047     /**
0048      * A HTMLified version of name, can return empty string
0049      */
0050     virtual QString formattedName() const;
0051 
0052     /**
0053      * Returns text of all cost metrics
0054      */
0055     virtual QString costString(EventTypeSet*);
0056 
0057     /**
0058      * Returns type name + dynamic name
0059      */
0060     QString fullName() const;
0061 
0062     /**
0063      * Returns full name + cost text
0064      */
0065     QString toString();
0066 
0067     /**
0068      * Set all cost counters to zero
0069      */
0070     virtual void clear();
0071 
0072     /** Invalidate the cost attributes.
0073      * An invalidated object needs to be recalculated when a cost
0074      * attribute is requested (e.g. by subCost()).
0075      * Has to be overwritten by subclasses when the cost influences costs of
0076      * other cost items. If only one item depends on the cost of this item,
0077      * it can by set with setDependent() without a need for overwriting.
0078      */
0079     virtual void invalidate();
0080 
0081     /**
0082      * Sets a dependent to be invalidated when this cost is invalidated.
0083      * Call this function directly after the constructor.
0084      */
0085     void setDependent(CostItem* d) { _dep = d; }
0086 
0087     CostItem* dependent() { return _dep; }
0088 
0089     /**
0090      * If this item is from a single profile data file, position
0091      * points to a TracePart, otherwise to a TraceData object.
0092      */
0093     void setPosition(CostItem* p) { _position = p; }
0094 
0095     /**
0096      * Redefine the context after construction
0097      */
0098     void setContext(ProfileContext* context) { _context = context; }
0099 
0100     // getters for specific positions, to be overwritten
0101     virtual TracePart* part();
0102     virtual const TracePart* part() const;
0103     virtual TraceData* data();
0104     virtual const TraceData* data() const;
0105 
0106 protected:
0107     /** Updates cost attributes.
0108      * This has to be called by subclasses that access cost attributes
0109      * directly
0110      */
0111     virtual void update();
0112 
0113     ProfileContext* _context;
0114     bool _dirty;
0115 
0116     CostItem* _position;
0117     CostItem* _dep;
0118 };
0119 
0120 
0121 // The maximal number of subcosts in a ProfileCostArray and
0122 // event types in a EventSet. Does not really matter for memory
0123 // consumption as cost for a ProfileCostArray is dynamically
0124 // allocated depending on used number of event types, and there
0125 // will be only a low number of objects for EventType{,Set,Mapping}.
0126 #define MaxRealIndexValue 200
0127 
0128 /**
0129  * An array of basic cost metrics for a trace item.
0130  *
0131  * The semantic of specific indexes is stored in the
0132  * EventTypeSet of the TraceData object holding this ProfileCostArray.
0133  */
0134 class ProfileCostArray: public CostItem
0135 {
0136     friend class EventType;
0137 public:
0138     /**
0139      */
0140     static const int MaxRealIndex;
0141     static const int InvalidIndex;
0142 
0143 
0144     explicit ProfileCostArray(ProfileContext*);
0145     ProfileCostArray();
0146     ~ProfileCostArray() override;
0147 
0148     QString costString(EventTypeSet*) override;
0149 
0150     void clear() override;
0151 
0152     // reserve space for cost
0153     void reserve(int);
0154 
0155     // set costs according to the mapping order of event types
0156     void set(EventTypeMapping*, const char*);
0157     void set(EventTypeMapping*, FixString&);
0158     // add costs according to the mapping order of event types
0159     void addCost(EventTypeMapping*, const char*);
0160     void addCost(EventTypeMapping*, FixString&);
0161     // add the cost of another item
0162     void addCost(ProfileCostArray* item);
0163     void addCost(int index, SubCost value);
0164 
0165     // maximal cost
0166     void maxCost(EventTypeMapping*, FixString&);
0167     void maxCost(ProfileCostArray* item);
0168     void maxCost(int index, SubCost value);
0169     ProfileCostArray diff(ProfileCostArray* item);
0170 
0171     void invalidate() override;
0172 
0173     /** Returns a sub cost. This automatically triggers
0174      * a call to update() if needed.
0175      */
0176     SubCost subCost(EventType*);
0177 
0178     /** Returns a cost attribute converted to a string
0179      * (with space after every 3 digits)
0180      */
0181     QString prettySubCost(EventType*);
0182 
0183     QString prettySubCostPerCall(EventType* t, uint64 calls);
0184 
0185 protected:
0186     void update() override;
0187 
0188 private:
0189     // Only used by friend class EventType: return subcost by index
0190     SubCost subCost(int);
0191 
0192     SubCost* _cost;
0193     int _count; // only _count first indexes of _cost are used
0194     int _allocCount; // number of allocated subcost entries
0195 
0196     // cache last virtual subcost for faster access
0197     SubCost _cachedCost;
0198     EventType* _cachedType;
0199 };
0200 
0201 
0202 #endif // COST_H