a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * VBox Debugger GUI - Statistics.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2012 Oracle Corporation
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * available from http://www.virtualbox.org. This file is free software;
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * you can redistribute it and/or modify it under the terms of the GNU
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * General Public License (GPL) as published by the Free Software
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Header Files *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Defined Constants And Macros *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** The number of column. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Structures and Typedefs *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The state of a statistics sample node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is used for two pass refresh (1. get data, 2. update the view) and
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * for saving the result of a diff.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The typical invalid zeroth entry. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The node is the root node. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The node is visible. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The node should be refreshed. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** diff: The node equals. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** diff: The node in set 1 is less than the one in set 2. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** diff: The node in set 1 is greater than the one in set 2. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** diff: The node is only in set 1. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** diff: The node is only in set 2. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The end of the valid state values. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * A tree node representing a statistic sample.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The nodes carry a reference to the parent and to its position among its
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * siblings. Both of these need updating when the grand parent or parent adds a
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * new child. This will hopefully not be too expensive but rather pay off when
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * we need to create a parent index.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Pointer to the parent. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Array of pointers to the child nodes. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The number of children. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Our index among the parent's children. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The unit. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The data type.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * For filler nodes not containing data, this will be set to STAMTYPE_INVALID. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The data at last update. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_COUNTER. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_PROFILE. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_PROFILE_ADV. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_RATIO_U32. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_U8 & STAMTYPE_U8_RESET. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_U16 & STAMTYPE_U16_RESET. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_U32 & STAMTYPE_U32_RESET. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_U64 & STAMTYPE_U64_RESET. */
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync /** STAMTYPE_BOOL and STAMTYPE_BOOL_RESET. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** STAMTYPE_CALLBACK. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The delta. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The name. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The length of the name. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The description string. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The node state. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Recursion stack.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The top stack entry. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The stack array. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The node. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The current child. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The item model for the statistics tree view.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This manages the DBGGUISTATSNODE trees.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The root of the sample tree. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Next update child. This is UINT32_MAX when invalid. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Pointer to the node m_szUpdateParent represent and m_iUpdateChild refers to. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The length of the path. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The path to the current update parent, including a trailing slash. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Inserted or/and removed nodes during the update. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Constructor.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pParent The parent object. See QAbstractItemModel in the Qt
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * docs for details.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Destructor.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This will free all the data the model holds.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Updates the data matching the specified pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This will should invoke updatePrep, updateCallback and updateDone.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * It is vitally important that updateCallback is fed the data in the right
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * order. The code make very definite ASSUMPTIONS about the ordering being
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * strictly sorted and taking the slash into account when doing so.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns true if we reset the model and it's necessary to set the root index.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rPatStr The selection pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @remarks The default implementation is an empty stub.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual bool updateStatsByPattern(const QString &a_rPatStr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Similar to updateStatsByPattern, except that it only works on a sub-tree and
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * will not remove anything that's outside that tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rIndex The sub-tree root. Invalid index means root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @todo Create a default implementation using updateStatsByPattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual void updateStatsByIndex(QModelIndex const &a_rIndex);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Reset the stats matching the specified pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rPatStr The selection pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @remarks The default implementation is an empty stub.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual void resetStatsByPattern(QString const &a_rPatStr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Reset the stats of a sub-tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rIndex The sub-tree root. Invalid index means root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_fSubTree Whether to reset the sub-tree as well. Default is true.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @remarks The default implementation makes use of resetStatsByPattern
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual void resetStatsByIndex(QModelIndex const &a_rIndex, bool a_fSubTree = true);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Gets the model index of the root node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns root index.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Set the root node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This will free all the current data before taking the ownership of the new
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * root node and its children.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pRoot The new root node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Creates the root node. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Creates and insert a node under the given parent. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE createAndInsertNode(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Creates and insert a node under the given parent with correct Qt
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * signalling. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE createAndInsert(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Resets the node to a pristine state.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Initializes a pristine node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static int initNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Updates (or reinitializes if you like) a node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static void updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Called by updateStatsByPattern(), makes the necessary preparations.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Success indicator.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Called by updateStatsByPattern(), finalizes the update.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @return See updateStatsByPattern().
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_fSuccess Whether the update was successful or not.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * updateCallback() worker taking care of in-tree inserts and removals.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszName The name of the tree element to update.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE updateCallbackHandleOutOfOrder(const char *pszName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * updateCallback() worker taking care of tail insertions.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszName The name of the tree element to update.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE updateCallbackHandleTail(const char *pszName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * updateCallback() worker that advances the update state to the next data node
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * in anticipation of the next updateCallback call.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void updateCallbackAdvance(PDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Callback used by updateStatsByPattern() and updateStatsByIndex() to feed
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc FNSTAMR3ENUM */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static DECLCALLBACK(int) updateCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Calculates the full path of a node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Number of bytes returned, negative value on buffer overflow
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param psz The output buffer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cch The size of the buffer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static ssize_t getNodePath(PCDBGGUISTATSNODE pNode, char *psz, ssize_t cch);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync * Calculates the full path of a node, returning the string pointer.
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync * @returns @a psz. On failure, NULL.
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync * @param pNode The node.
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync * @param psz The output buffer.
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync * @param cch The size of the buffer.
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync static char *getNodePath2(PCDBGGUISTATSNODE pNode, char *psz, ssize_t cch);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Check if the first node is an ancestor to the second one.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pAncestor The first node, the alleged ancestor.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pDescendant The second node, the alleged descendant.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static bool isNodeAncestorOf(PCDBGGUISTATSNODE pAncestor, PCDBGGUISTATSNODE pDescendant);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Advance to the next node in the tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the next node, NULL if we've reached the end or
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * was handed a NULL node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE nextNode(PDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Advance to the next node in the tree that contains data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the next data node, NULL if we've reached the end or
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * was handed a NULL node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE nextDataNode(PDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Advance to the previous node in the tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the previous node, NULL if we've reached the end or
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * was handed a NULL node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE prevNode(PDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Advance to the previous node in the tree that contains data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the previous data node, NULL if we've reached the end or
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * was handed a NULL node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The current node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE prevDataNode(PDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Removes a node from the tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns pNode.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static PDBGGUISTATSNODE removeNode(PDBGGUISTATSNODE pNode);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * Removes a node from the tree and destroys it and all its descendants.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pNode The node.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static void removeAndDestroyNode(PDBGGUISTATSNODE pNode);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** Removes a node from the tree and destroys it and all its descendants
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * performing the required Qt signalling. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Destroys a statistics tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pRoot The root of the tree. NULL is fine.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Stringifies exactly one node, no children.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is for logging and clipboard.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pNode The node.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * @param a_rString The string to append the stringified node to.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static void stringifyNodeNoRecursion(PDBGGUISTATSNODE a_pNode, QString &a_rString);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Stringifies a node and its children.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is for logging and clipboard.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pNode The node.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * @param a_rString The string to append the stringified node to.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static void stringifyNode(PDBGGUISTATSNODE a_pNode, QString &a_rString);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Converts the specified tree to string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is for logging and clipboard.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rRoot Where to start. Use QModelIndex() to start at the root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rString Where to return to return the string dump.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void stringifyTree(QModelIndex &a_rRoot, QString &a_rString) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Dumps the given (sub-)tree as XML.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rRoot Where to start. Use QModelIndex() to start at the root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rString Where to return to return the XML dump.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void xmlifyTree(QModelIndex &a_rRoot, QString &a_rString) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Puts the stringified tree on the clipboard.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rRoot Where to start. Use QModelIndex() to start at the root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void copyTreeToClipboard(QModelIndex &a_rRoot) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Worker for logTree. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static void logNode(PDBGGUISTATSNODE a_pNode, bool a_fReleaseLog);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Logs a (sub-)tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rRoot Where to start. Use QModelIndex() to start at the root.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_fReleaseLog Whether to use the release log (true) or the debug log (false).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void logTree(QModelIndex &a_rRoot, bool a_fReleaseLog) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the unit. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the value/times. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strValueTimes(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the minimum value. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strMinValue(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the average value. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strAvgValue(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the maximum value. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strMaxValue(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the total value. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strTotalValue(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Gets the delta value. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static QString strDeltaValue(PCDBGGUISTATSNODE pNode);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Destroys a node and all its children.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pNode The node to destroy.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Converts an index to a node pointer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the node, NULL if invalid reference.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rIndex Reference to the index
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync inline PDBGGUISTATSNODE nodeFromIndex(const QModelIndex &a_rIndex) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return (PDBGGUISTATSNODE)a_rIndex.internalPointer();
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** @name Overridden QAbstractItemModel methods
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual int columnCount(const QModelIndex &a_rParent) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual QVariant data(const QModelIndex &a_rIndex, int a_eRole) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual Qt::ItemFlags flags(const QModelIndex &a_rIndex) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual bool hasChildren(const QModelIndex &a_rParent) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual QVariant headerData(int a_iSection, Qt::Orientation a_ePrientation, int a_eRole) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual QModelIndex index(int a_iRow, int a_iColumn, const QModelIndex &a_rParent) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual QModelIndex parent(const QModelIndex &a_rChild) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual int rowCount(const QModelIndex &a_rParent) const;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync ///virtual void sort(int a_iColumn, Qt::SortOrder a_eOrder);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Model using the VM / STAM interface as data source.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncclass VBoxDbgStatsModelVM : public VBoxDbgStatsModel, public VBoxDbgBase
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Constructor.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pDbgGui Pointer to the debugger gui object.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rPatStr The selection pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_pParent The parent object. NULL is fine.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync VBoxDbgStatsModelVM(VBoxDbgGui *a_pDbgGui, QString &a_rPatStr, QObject *a_pParent);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Destructor */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual bool updateStatsByPattern(const QString &a_rPatStr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync virtual void resetStatsByPattern(const QString &a_rPatStr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Enumeration callback used by createNewTree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static DECLCALLBACK(int) createNewTreeCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Constructs a new statistics tree by query data from the VM.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns Pointer to the root of the tree we've constructed. This will be NULL
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * if the STAM API throws an error or we run out of memory.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param a_rPatStr The selection pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE createNewTree(QString &a_rPatStr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Internal Functions *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Formats a number into a 64-byte buffer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Formats a number into a 64-byte buffer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * (18 446 744 073 709 551 615)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic char *formatNumberSigned(char *psz, int64_t i64)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync unsigned cDigits = 0;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Formats a unsigned hexadecimal number into a into a 64-byte buffer.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic char *formatHexNumber(char *psz, uint64_t u64, unsigned cZeros)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static const char s_szDigits[] = "0123456789abcdef";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync unsigned cDigits = 0;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#if 0/* unused */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Formats a sort key number.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static const char s_szDigits[] = "0123456789abcdef";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* signed */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* 16 hex digits */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync unsigned i = 16;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (i-- > 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#if 0/* unused */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Formats a sort key number.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic void formatSortKeySigned(char *psz, int64_t i64)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync static const char s_szDigits[] = "0123456789abcdef";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* signed */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* 16 hex digits */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync unsigned i = 16;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (i-- > 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::VBoxDbgStatsModel(QObject *a_pParent)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pRoot(NULL), m_iUpdateChild(UINT32_MAX), m_pUpdateParent(NULL), m_cchUpdateParent(0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::destroyTree(PDBGGUISTATSNODE a_pRoot)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/* static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::destroyNode(PDBGGUISTATSNODE a_pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* destroy all our children */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (i-- > 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* free the resources we're using */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* poison it. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Finally ourselves */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync a_pNode->enmState = kDbgGuiStatsNodeState_kInvalid;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pRoot = (PDBGGUISTATSNODE)RTMemAllocZ(sizeof(DBGGUISTATSNODE));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pRoot->pszName = (char *)RTMemDup("/", sizeof("/"));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::createAndInsertNode(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create it.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pNode = (PDBGGUISTATSNODE)RTMemAllocZ(sizeof(DBGGUISTATSNODE));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode->pszName = (char *)RTMemDupEx(pszName, cchName, 1);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do we need to expand the array?
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync void *pvNew = RTMemRealloc(pParent->papChildren, sizeof(*pParent->papChildren) * (pParent->cChildren + 32));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Insert it.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Last. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Shift all the items after ours. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pChild = pParent->papChildren[iShift];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Insert ours */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::createAndInsert(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsertNode(pParent, pszName, cchName, iPosition);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync beginInsertRows(createIndex(pParent->iSelf, 0, pParent), 0, 0);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsertNode(pParent, pszName, cchName, iPosition);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::removeNode(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pChild = pParent->papChildren[iPosition + 1];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pParent->papChildren[iPosition] = (PDBGGUISTATSNODE)0x42;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::removeAndDestroyNode(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::removeAndDestroy(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Removing is fun since the docs are imprecise as to how persistent
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * indexes are updated (or aren't). So, let try a few different ideas
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * and see which works.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* destroy the children first with the appropriate begin/endRemoveRows signals. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* get top element */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pNode = Stack.a[Stack.iTop].pNode;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(Stack.iTop < (int32_t)RT_ELEMENTS(Stack.a));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Stack.a[Stack.iTop].pNode = pNode->papChildren[iChild];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* pop and destroy all the children. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync beginRemoveRows(createIndex(pNode->iSelf, 0, pNode), 0, i - 1);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (i-- > 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* finally the node it self. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync beginRemoveRows(createIndex(pParent->iSelf, 0, pParent), pNode->iSelf, pNode->iSelf);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* This ain't working, leaves invalid indexes behind. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync beginRemoveRows(createIndex(pParent->iSelf, 0, pParent), pNode->iSelf, pNode->iSelf);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Force reset() of the model after the update. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::resetNode(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* free and reinit the data. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* free the description. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ int
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::initNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Copy the data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode->pDescStr = new QString(pszDesc); /* ignore allocation failure (well, at least up to the point we can ignore it) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Reset and init the node if the type changed.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync initNode(pNode, enmType, pvSample, enmUnit, pszDesc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * ASSUME that only the sample value will change and that the unit, visibility
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * and description remains the same.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint64_t cPrevPeriods = pNode->Data.Profile.cPeriods;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync iDelta = pNode->Data.Profile.cPeriods - cPrevPeriods;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int32_t iDeltaA = pNode->Data.RatioU32.u32A - Prev.u32A;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int32_t iDeltaB = pNode->Data.RatioU32.u32B - Prev.u32B;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode->i64Delta = iDeltaA + (iDeltaB >= 0 ? iDeltaB : -iDeltaB);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode->i64Delta = iDeltaA + (iDeltaB < 0 ? iDeltaB : -iDeltaB);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync iDelta = (int32_t)pNode->Data.u16 - (int32_t)uPrev;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync iDelta = (int64_t)pNode->Data.u32 - (int64_t)uPrev;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::getNodePath(PCDBGGUISTATSNODE pNode, char *psz, ssize_t cch)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* root - don't add it's slash! */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync memcpy(&psz[off], pNode->pszName, pNode->cchName + 1);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync/*static*/ char *
71955773a7f477f9a159a491f765ba97e1f00e1avboxsyncVBoxDbgStatsModel::getNodePath2(PCDBGGUISTATSNODE pNode, char *psz, ssize_t cch)
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync if (VBoxDbgStatsModel::getNodePath(pNode, psz, cch) < 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ bool
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::isNodeAncestorOf(PCDBGGUISTATSNODE pAncestor, PCDBGGUISTATSNODE pDescendant)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return true;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return false;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* descend to children. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* next sibling. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ascend and advanced to a parent's sibiling. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::nextDataNode(PDBGGUISTATSNODE pNode)
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* previous sibling's latest descendant (better expression anyone?). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ascend to the parent. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::prevDataNode(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::createNewTree(IMachineDebugger *a_pIMachineDebugger)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::createNewTree(const char *pszFilename)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::createDiffTree(PDBGGUISTATSNODE pTree1, PDBGGUISTATSNODE pTree2)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateCallbackHandleOutOfOrder(const char *pszName)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * We might be inserting a new node between pPrev and pNode
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * or we might be removing one or more nodes. Either case is
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * handled in the same rough way.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Might consider optimizing insertion at some later point since this
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * is a normal occurrence (dynamic statistics in PATM, IOM, MM, ++).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(m_szUpdateParent[m_cchUpdateParent - 1] == '/');
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Start with the current parent node and look for a common ancestor
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * hoping that this is faster than going from the root (saves lookup).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pNode = m_pUpdateParent->papChildren[m_iUpdateChild];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE const pPrev = prevDataNode(pNode);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync AssertMsg(strcmp(pszName, getNodePath2(pNode, szStrict, sizeof(szStrict))), ("%s\n", szStrict));
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync AssertMsg(strcmp(pszName, getNodePath2(pPrev, szStrict, sizeof(szStrict))), ("%s\n", szStrict));
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync Log(("updateCallbackHandleOutOfOrder: pszName='%s' m_szUpdateParent='%s' m_cchUpdateParent=%u pNode='%s'\n",
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync pszName, m_szUpdateParent, m_cchUpdateParent, getNodePath2(pNode, szStrict, sizeof(szStrict))));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!strncmp(pszName, m_szUpdateParent, m_cchUpdateParent))
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync Log2(("updateCallbackHandleOutOfOrder: m_szUpdateParent='%s' m_cchUpdateParent=%u, removed '/%s' (%u)\n", m_szUpdateParent, m_cchUpdateParent, pNode->pszName, __LINE__));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(m_szUpdateParent[m_cchUpdateParent - 1] == '/');
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Descend until we've found/created the node pszName indicates,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * modifying m_szUpdateParent as we go along.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Find the end of this component. */
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync const char * const pszSubName = &pszName[m_cchUpdateParent];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Add the name to the path. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync memcpy(&m_szUpdateParent[m_cchUpdateParent], pszSubName, cchSubName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(m_cchUpdateParent < sizeof(m_szUpdateParent));
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync Log2(("updateCallbackHandleOutOfOrder: m_szUpdateParent='%s' m_cchUpdateParent=%u (%u)\n", m_szUpdateParent, m_cchUpdateParent, __LINE__));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* first child */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsert(pNode, pszSubName, cchSubName, 0);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* binary search. */
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync size_t const cchCompare = RT_MIN(pNode->papChildren[i]->cchName, cchSubName);
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync iDiff = memcmp(pszSubName, pNode->papChildren[i]->pszName, cchCompare);
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync iDiff = cchSubName == cchCompare ? 0 : cchSubName > cchCompare ? 1 : -1;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsert(pNode, pszSubName, cchSubName, iStart);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else if (iDiff < 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsert(pNode, pszSubName, cchSubName, i);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert( !memcmp(pszName, m_szUpdateParent, m_cchUpdateParent - 2)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Remove all the nodes between pNode and pPrev but keep all
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * of pNode's ancestors (or it'll get orphaned).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pAdv = prevNode(pCur); Assert(pAdv || !pPrev);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Remove the data from all ancestors of pNode that it doesn't
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * share them pPrev.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Finally, adjust the globals (szUpdateParent is one level too deep).
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync Log2(("updateCallbackHandleOutOfOrder: m_szUpdateParent='%s' m_cchUpdateParent=%u (%u)\n", m_szUpdateParent, m_cchUpdateParent, __LINE__));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateCallbackHandleTail(const char *pszName)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Insert it at the end of the tree.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do the same as we're doing down in createNewTreeCallback, walk from the
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * root and create whatever we need.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AssertReturn(*pszName == '/' && pszName[1] != '/', NULL);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Find the end of this component. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Create it if it doesn't exist (it will be last if it exists). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || strncmp(pNode->papChildren[pNode->cChildren - 1]->pszName, pszCur, cchCur)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || pNode->papChildren[pNode->cChildren - 1]->pszName[cchCur])
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsert(pNode, pszCur, pszNext - pszCur, pNode->cChildren);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Advance */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateCallbackAdvance(PDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Advance to the next node with data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * ASSUMES a leaf *must* have data and again we're ASSUMING the sorting
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * on slash separated sub-strings.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE const pCorrectNext = nextDataNode(pNode);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* descend to the first child. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(m_cchUpdateParent + pNode->cchName + 2 < sizeof(m_szUpdateParent));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync memcpy(&m_szUpdateParent[m_cchUpdateParent], pNode->pszName, pNode->cchName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* next sibling or one if its descendants. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* move up and down- / on-wards */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ascend */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* try advance */
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* descend to a node containing data and finalize the globals. (ASSUMES leaf has data.) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(pNode->enmState == kDbgGuiStatsNodeState_kVisible);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(m_cchUpdateParent + pNode->cchName + 2 < sizeof(m_szUpdateParent));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync memcpy(&m_szUpdateParent[m_cchUpdateParent], pNode->pszName, pNode->cchName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* else: we're at the end */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync VBoxDbgStatsModelVM *pThis = (VBoxDbgStatsModelVM *)pvUser;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Skip the ones which shouldn't be visible in the GUI.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The default assumption is that nothing has changed.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * For now we'll reset the model when ever something changes.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = pThis->m_pUpdateParent->papChildren[pThis->m_iUpdateChild];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( !strncmp(pszName, pThis->m_szUpdateParent, pThis->m_cchUpdateParent)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && !strcmp(pszName + pThis->m_cchUpdateParent, pNode->pszName))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* got it! */;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = pThis->updateCallbackHandleOutOfOrder(pszName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* append */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Perform the update and advance to the next one.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync updateNode(pNode, enmType, pvSample, enmUnit, pszDesc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Find the first child with data and set it up as the 'next'
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * node to be updated.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pUpdateParent = pFirst->pParent; Assert(m_pUpdateParent);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_cchUpdateParent = getNodePath(m_pUpdateParent, m_szUpdateParent, sizeof(m_szUpdateParent) - 1);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Set the flag and signal possible layout change.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* emit layoutAboutToBeChanged(); - debug this, it gets stuck... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return true;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Remove any nodes following the last in the update (unless the update failed).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE const pLast = prevDataNode(m_pUpdateParent->papChildren[m_iUpdateChild]);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* nuking the whole tree. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * We're done making layout changes (if I understood it correctly), so,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * signal this and then see what to do next. If we did too many removals
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * we'll just reset the whole shebang.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* emit layoutChanged(); - hrmpf, doesn't work reliably... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Send dataChanged events.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * We do this here instead of from the updateCallback because it reduces
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * the clutter in that method and allow us to emit bulk signals in an
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * easier way because we can traverse the tree in a different fashion.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* get top element */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pNode = Stack.a[Stack.iTop].pNode;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(Stack.iTop < (int32_t)RT_ELEMENTS(Stack.a));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Stack.a[Stack.iTop].pNode = pNode->papChildren[iChild];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* do the actual work. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* skip to the first needing updating. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kRefresh)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex TopLeft = createIndex(iChild, 0, pNode->papChildren[iChild]);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode->papChildren[iChild]->enmState = kDbgGuiStatsNodeState_kVisible;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* any subsequent nodes that also needs refreshing? */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pNode->papChildren[iChild]->enmState == kDbgGuiStatsNodeState_kRefresh)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync do pNode->papChildren[iChild]->enmState = kDbgGuiStatsNodeState_kVisible;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pNode->papChildren[iChild]->enmState == kDbgGuiStatsNodeState_kRefresh);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex BottomRight = createIndex(iChild - 1, DBGGUI_STATS_COLUMNS - 1, pNode->papChildren[iChild - 1]);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* emit the refresh signal */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* emit the refresh signal */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* emit layoutChanged(); - hrmpf, doesn't work reliably... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateStatsByPattern(const QString &a_rPatStr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return false;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::updateStatsByIndex(QModelIndex const &a_rIndex)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo implement this based on updateStatsByPattern. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::resetStatsByPattern(QString const &a_rPatStr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::resetStatsByIndex(QModelIndex const &a_rIndex, bool fSubTree /*= true*/)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* everything from the root down. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* the node pattern. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* the sub-tree pattern. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::setRootNode(PDBGGUISTATSNODE a_pRoot)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::flags(const QModelIndex &a_rIndex) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Qt::ItemFlags fFlags = QAbstractItemModel::flags(a_rIndex);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::columnCount(const QModelIndex &a_rParent) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::rowCount(const QModelIndex &a_rParent) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pParent = nodeFromIndex(a_rParent);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pParent ? pParent->cChildren : 1 /* root */;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::hasChildren(const QModelIndex &a_rParent) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pParent = nodeFromIndex(a_rParent);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pParent ? pParent->cChildren > 0 : true /* root */;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::index(int iRow, int iColumn, const QModelIndex &a_rParent) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pParent = nodeFromIndex(a_rParent);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("index: iRow=%d >= cChildren=%u (iColumn=%d)\n", iRow, (unsigned)pParent->cChildren, iColumn));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("index: iColumn=%d (iRow=%d)\n", iColumn, iRow));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pChild = pParent->papChildren[iRow];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::parent(const QModelIndex &a_rChild) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::headerData(int a_iSection, Qt::Orientation a_eOrientation, int a_eRole) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strValueTimes(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return formatNumber(sz, pNode->Data.Profile.cPeriods);
31e6eca958b963f334405a9086d0bab7a974a9cavboxsync char *psz = formatNumber(szTmp, pNode->Data.RatioU32.u32A);
31e6eca958b963f334405a9086d0bab7a974a9cavboxsync strcpy(&sz[off], formatNumber(szTmp, pNode->Data.RatioU32.u32B));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strMinValue(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return formatNumber(sz, pNode->Data.Profile.cTicksMin);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strAvgValue(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return formatNumber(sz, pNode->Data.Profile.cTicks / pNode->Data.Profile.cPeriods);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strMaxValue(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return formatNumber(sz, pNode->Data.Profile.cTicksMax);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strTotalValue(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return formatNumber(sz, pNode->Data.Profile.cTicks);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::strDeltaValue(PCDBGGUISTATSNODE pNode)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return "0";
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* fall thru */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::data(const QModelIndex &a_rIndex, int a_eRole) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pNode->pDescStr ? QString(*pNode->pDescStr) : QString("");
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::stringifyNodeNoRecursion(PDBGGUISTATSNODE a_pNode, QString &a_rString)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Get the path, padding it to 32-chars and add it to the string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync ssize_t off = getNodePath(a_pNode, szBuf, sizeof(szBuf) - 2);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The following is derived from stamR3PrintOne, except
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * we print to szBuf, do no visibility checks and can skip
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * the path bit.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8llu %s", a_pNode->Data.Counter.c, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint64_t u64 = a_pNode->Data.Profile.cPeriods ? a_pNode->Data.Profile.cPeriods : 1;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync "%8llu %s (%12llu ticks, %7llu times, max %9llu, min %7lld)",
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync a_pNode->Data.Profile.cTicks / u64, STAMR3GetUnit(a_pNode->enmUnit),
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync a_pNode->Data.Profile.cTicks, a_pNode->Data.Profile.cPeriods, a_pNode->Data.Profile.cTicksMax, a_pNode->Data.Profile.cTicksMin);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync "%8u:%-8u %s",
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync a_pNode->Data.RatioU32.u32A, a_pNode->Data.RatioU32.u32B, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), " %s", STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8u %s", a_pNode->Data.u8, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8x %s", a_pNode->Data.u8, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8u %s", a_pNode->Data.u16, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8x %s", a_pNode->Data.u16, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8u %s", a_pNode->Data.u32, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8x %s", a_pNode->Data.u32, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8llu %s", a_pNode->Data.u64, STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%8llx %s", a_pNode->Data.u64, STAMR3GetUnit(a_pNode->enmUnit));
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync RTStrPrintf(szBuf, sizeof(szBuf), "%s %s", a_pNode->Data.f ? "true " : "false ", STAMR3GetUnit(a_pNode->enmUnit));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AssertMsgFailed(("enmType=%d\n", a_pNode->enmType));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::stringifyNode(PDBGGUISTATSNODE a_pNode, QString &a_rString)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* this node (if it has data) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* the children */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::stringifyTree(QModelIndex &a_rRoot, QString &a_rString) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pRoot = a_rRoot.isValid() ? nodeFromIndex(a_rRoot) : m_pRoot;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::copyTreeToClipboard(QModelIndex &a_rRoot) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QClipboard *pClipboard = QApplication::clipboard();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pClipboard->setText(String, QClipboard::Clipboard);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*static*/ void
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::logNode(PDBGGUISTATSNODE a_pNode, bool a_fReleaseLog)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* this node (if it has data) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* the children */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModel::logTree(QModelIndex &a_rRoot, bool a_fReleaseLog) const
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGGUISTATSNODE pRoot = a_rRoot.isValid() ? nodeFromIndex(a_rRoot) : m_pRoot;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l V M
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l V M
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s M o d e l V M
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModelVM::VBoxDbgStatsModelVM(VBoxDbgGui *a_pDbgGui, QString &a_rPatStr, QObject *a_pParent)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync : VBoxDbgStatsModel(a_pParent), VBoxDbgBase(a_pDbgGui)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create a model containing the STAM entries matching the pattern.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * (The original idea was to get everything and rely on some hide/visible
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * flag that it turned out didn't exist.)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* nothing to do here. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModelVM::updateStatsByPattern(const QString &a_rPatStr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo the way we update this stuff is independent of the source (XML, file, STAM), our only
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * ASSUMPTION is that the input is strictly ordered by (fully slashed) name. So, all this stuff
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * should really move up into the parent class. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc = stamEnum(a_rPatStr, updateCallback, this);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModelVM::resetStatsByPattern(QString const &a_rPatStr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModelVM::createNewTreeCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Skip the ones which shouldn't be visible in the GUI.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Perform a mkdir -p like operation till we've walked / created the entire path down
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * to the node specfied node. Remember the last node as that will be the one we will
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * stuff the data into.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AssertReturn(*pszName == '/' && pszName[1] != '/', VERR_INTERNAL_ERROR);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* find the end of this component. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Create it if it doesn't exist (it will be last if it exists). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || strncmp(pNode->papChildren[pNode->cChildren - 1]->pszName, pszCur, cchCur)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || pNode->papChildren[pNode->cChildren - 1]->pszName[cchCur])
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pNode = createAndInsertNode(pNode, pszCur, pszNext - pszCur, UINT32_MAX);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Advance */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Save the data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return initNode(pNode, enmType, pvSample, enmUnit, pszDesc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsModelVM::createNewTree(QString &a_rPatStr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc = stamEnum(a_rPatStr, createNewTreeCallback, pRoot);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* failed, cleanup. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s V i e w
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s V i e w
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s V i e w
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsView::VBoxDbgStatsView(VBoxDbgGui *a_pDbgGui, VBoxDbgStatsModel *a_pModel, VBoxDbgStats *a_pParent/* = NULL*/)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync : QTreeView(a_pParent), VBoxDbgBase(a_pDbgGui), m_pModel(a_pModel), m_PatStr(), m_pParent(a_pParent),
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pLeafMenu(NULL), m_pBranchMenu(NULL), m_pViewMenu(NULL), m_pCurMenu(NULL), m_CurIndex()
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Set the model and view defaults.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex RootIdx = m_pModel->getRootIndex(); /* This should really be QModelIndex(), but Qt on darwin does wrong things then. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /// @todo sorting setSortingEnabled(true);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create and setup the actions.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pCollapseAct = new QAction("Collapse Tree", this);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pToRelLogAct = new QAction("T&o Release Log", this);
f4579b5474998fc38afbbfc31c53609219d526a8vboxsync m_pAdjColumns = new QAction("&Adjust Columns", this);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pCollapseAct->setShortcut(QKeySequence("Ctrl+D"));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pRefreshAct->setShortcut(QKeySequence("Ctrl+R"));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pToRelLogAct->setShortcut(QKeySequence("Alt+Z"));
f4579b5474998fc38afbbfc31c53609219d526a8vboxsync m_pAdjColumns->setShortcut(QKeySequence("Ctrl+A"));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pExpandAct, SIGNAL(triggered(bool)), this, SLOT(actExpand()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pCollapseAct, SIGNAL(triggered(bool)), this, SLOT(actCollapse()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pRefreshAct, SIGNAL(triggered(bool)), this, SLOT(actRefresh()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pResetAct, SIGNAL(triggered(bool)), this, SLOT(actReset()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pCopyAct, SIGNAL(triggered(bool)), this, SLOT(actCopy()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pToLogAct, SIGNAL(triggered(bool)), this, SLOT(actToLog()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pToRelLogAct, SIGNAL(triggered(bool)), this, SLOT(actToRelLog()));
f4579b5474998fc38afbbfc31c53609219d526a8vboxsync connect(m_pAdjColumns, SIGNAL(triggered(bool)), this, SLOT(actAdjColumns()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create the menus and populate them.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* the header menu */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pHdrView->setContextMenuPolicy(Qt::CustomContextMenu);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(pHdrView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(headerContextMenuRequested(const QPoint &)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define DELETE_IT(m) if (m) { delete m; m = NULL; } else do {} while (0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsView::updateStats(const QString &rPatStr)
f4579b5474998fc38afbbfc31c53609219d526a8vboxsync for (int i = 0; i <= 8; i++)
37cdd9fa67b42ac9ef00ab4bf01da37aa5fa1440vboxsync /* Some extra room for distinguishing numbers better in Value, Min, Avg, Max, Total, dInt columns. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsView::setSubTreeExpanded(QModelIndex const &a_rIndex, bool a_fExpanded)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync for (int i = 0; i < cRows; i++)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync setSubTreeExpanded(a_rIndex.child(i, 0), a_fExpanded);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsView::contextMenuEvent(QContextMenuEvent *a_pEvt)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Get the selected item.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * If it's a mouse event select the item under the cursor (if any).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Popup the corresponding menu.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pRefreshAct->setEnabled(!Idx.isValid() || Idx == m_pModel->getRootIndex());
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStatsView::headerContextMenuRequested(const QPoint &a_rPos)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Show the view menu.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!Idx.isValid() || Idx == m_pModel->getRootIndex())
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!Idx.isValid() || Idx == m_pModel->getRootIndex())
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync QModelIndex Idx = m_pCurMenu ? m_CurIndex : currentIndex();
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * V B o x D b g S t a t s
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncVBoxDbgStats::VBoxDbgStats(VBoxDbgGui *a_pDbgGui, const char *pszPat/* = NULL*/, unsigned uRefreshRate/* = 0*/, QWidget *pParent/* = NULL*/)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync : VBoxDbgBaseWindow(a_pDbgGui, pParent), m_PatStr(pszPat), m_pPatCB(NULL), m_uRefreshRate(0), m_pTimer(NULL), m_pView(NULL)
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync /* Assign window-title: */
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync setWindowTitle(QString("%1 - Statistics").arg(parentWidget()->windowTitle()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * On top, a horizontal box with the pattern field, buttons and refresh interval.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pPatCB, SIGNAL(activated(const QString &)), this, SLOT(apply(const QString &)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(pPB, SIGNAL(clicked()), this, SLOT(applyAll()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(pSB, SIGNAL(valueChanged(int)), this, SLOT(setRefresh(int)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create the tree view and setup the layout.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync VBoxDbgStatsModelVM *pModel = new VBoxDbgStatsModelVM(a_pDbgGui, m_PatStr, NULL);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pView = new VBoxDbgStatsView(a_pDbgGui, pModel, this);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Resize the columns.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Seems this has to be done with all nodes expanded.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Create a refresh timer and start it.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pTimer, SIGNAL(timeout()), this, SLOT(refresh()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * And some shortcuts.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync m_pFocusToPat->setShortcut(QKeySequence("Ctrl+L"));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync connect(m_pFocusToPat, SIGNAL(triggered(bool)), this, SLOT(actFocusToPat()));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync delete this;
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsyncbool VBoxDbgStats::eventFilter(QObject *pWatched, QEvent *pEvent)
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync /* Skip events which are not related to our parent: */
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync return VBoxDbgBaseWindow::eventFilter(pWatched, pEvent);
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync /* Depending on event-type: */
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync case QEvent::WindowTitleChange: setWindowTitle(QString("%1 - Statistics").arg(parentWidget()->windowTitle())); break;
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync default: break;
78b53d2559005e2deb0fd645a8ae539b25810b9dvboxsync /* Call to base-class: */