| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_SYNC_SESSIONS_TAB_NODE_POOL_H_ |
| #define COMPONENTS_SYNC_SESSIONS_TAB_NODE_POOL_H_ |
| |
| #include <stddef.h> |
| |
| #include <map> |
| #include <set> |
| #include <string> |
| |
| #include "base/macros.h" |
| #include "components/sessions/core/session_id.h" |
| |
| namespace sync_sessions { |
| |
| // A pool for managing free/used tab sync nodes for the *local* session. |
| // Performs lazy creation of sync nodes when necessary. |
| // Note: We make use of the following "id's" |
| // - a tab_id: created by session service, unique to this client |
| // - a tab_node_id: the id for a particular sync tab node. This is used |
| // to generate the sync tab node tag through: |
| // tab_tag = StringPrintf("%s %d", local_session_tag, tab_node_id); |
| // |
| // A sync node can be in one of the two states: |
| // 1. Associated : Sync node is used and associated with a tab. |
| // 2. Free : Sync node is unused. |
| |
| class TabNodePool { |
| public: |
| TabNodePool(); |
| ~TabNodePool(); |
| |
| // If free nodes > kFreeNodesHighWatermark, delete all free nodes until |
| // free nodes <= kFreeNodesLowWatermark. |
| static const size_t kFreeNodesLowWatermark; |
| |
| // Maximum limit of FreeNodes allowed on the client. |
| static const size_t kFreeNodesHighWatermark; |
| |
| static const int kInvalidTabNodeID; |
| |
| // Returns the tab node associated with |tab_id| or kInvalidTabNodeID if |
| // no association existed. |
| int GetTabNodeIdFromTabId(SessionID tab_id) const; |
| |
| // Returns the tab_id for |tab_node_id| if it is associated else returns an |
| // invalid ID. |
| SessionID GetTabIdFromTabNodeId(int tab_node_id) const; |
| |
| // Gets the next free tab node (or creates a new one if needed) and associates |
| // it to |tab_id|. Returns the tab node ID associated to |tab_id|. If |
| // |reused_existing_node| is not null, it will be set with a value that |
| // represents if an existing free tab node was reused or a new one created. |
| // TODO(crbug.com/681921): Remove all logic related to |reused_existing_node| |
| // once the migration to USS is finished. |
| int AssociateWithFreeTabNode(SessionID tab_id, bool* reused_existing_node); |
| |
| // Reassociates |tab_node_id| with |tab_id|. If |tab_node_id| is not already |
| // known, it is added to the tab node pool before being associated. |
| void ReassociateTabNode(int tab_node_id, SessionID tab_id); |
| |
| // Removes association for |tab_id| and returns its tab node to the free node |
| // pool. |
| void FreeTab(SessionID tab_id); |
| |
| // Fills |deleted_node_ids| with any free nodes to be deleted as proscribed |
| // by the free node low/high watermarks, in order to ensure the free node pool |
| // does not grow too large. |
| void CleanupTabNodes(std::set<int>* deleted_node_ids); |
| |
| // Deletes all known mappings for |tab_node_id|. As opposed to FreeTab(), it |
| // does NOT free the node for later reuse. This is used for foreign sessions |
| // when remote deletions are received. |
| void DeleteTabNode(int tab_node_id); |
| |
| // Clear tab pool. |
| void Clear(); |
| |
| // Return the number of tab nodes this client currently has allocated |
| // (including both free and associated nodes). |
| size_t Capacity() const; |
| |
| // Return empty status (all tab nodes are in use). |
| bool Empty() const; |
| |
| // Return full status (no tab nodes are in use). |
| bool Full(); |
| |
| // Returns tab node IDs for all known (used or free) tab nodes. |
| std::set<int> GetAllTabNodeIds() const; |
| |
| private: |
| friend class SyncTabNodePoolTest; |
| using TabNodeIDToTabIDMap = std::map<int, SessionID>; |
| using TabIDToTabNodeIDMap = std::map<SessionID, int>; |
| |
| // Adds |tab_node_id| to the tab node pool. |
| // Note: this should only be called when we discover tab sync nodes from |
| // previous sessions, not for freeing tab nodes we created through |
| // GetTabNodeForTab (use FreeTab for that). |
| void AddTabNode(int tab_node_id); |
| |
| // Associates |tab_node_id| with |tab_id|. |tab_node_id| must be free. In |
| // order to associated a non-free tab node, ReassociateTabNode must be |
| // used. |
| void AssociateTabNode(int tab_node_id, SessionID tab_id); |
| |
| // Stores mapping of node ids associated with tab_ids, these are the used |
| // nodes of tab node pool. |
| // The nodes in the map can be returned to free tab node pool by calling |
| // FreeTab(..). |
| TabNodeIDToTabIDMap nodeid_tabid_map_; |
| TabIDToTabNodeIDMap tabid_nodeid_map_; |
| |
| // The node ids for the set of free sync nodes. |
| std::set<int> free_nodes_pool_; |
| |
| // The maximum used tab_node id for a sync node. A new sync node will always |
| // be created with max_used_tab_node_id_ + 1. |
| int max_used_tab_node_id_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TabNodePool); |
| }; |
| |
| } // namespace sync_sessions |
| |
| #endif // COMPONENTS_SYNC_SESSIONS_TAB_NODE_POOL_H_ |