1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_SYNC_GLUE_TAB_NODE_POOL_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_TAB_NODE_POOL_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/gtest_prod_util.h" 14 #include "chrome/browser/sessions/session_id.h" 15 16 class ProfileSyncService; 17 18 namespace browser_sync { 19 20 // A pool for managing free/used tab sync nodes for the *local* session. 21 // Performs lazy creation of sync nodes when necessary. 22 // Note: We make use of the following "id's" 23 // - a tab_id: created by session service, unique to this client 24 // - a tab_node_id: the id for a particular sync tab node. This is used 25 // to generate the sync tab node tag through: 26 // tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id); 27 // 28 // A sync node can be in one of the three states: 29 // 1. Associated : Sync node is used and associated with a tab. 30 // 2. Unassociated : Sync node is used but currently unassociated with any tab. 31 // This is true for old nodes that remain from a session 32 // restart. Nodes are only unassociated temporarily while the 33 // model associator figures out which tabs belong to which 34 // nodes. Eventually any remaining unassociated nodes are 35 // deleted. 36 // 3. Free : Sync node is unused. 37 38 class TabNodePool { 39 public: 40 explicit TabNodePool(ProfileSyncService* sync_service); 41 ~TabNodePool(); 42 enum InvalidTab { 43 kInvalidTabID = -1 44 }; 45 46 // If free nodes > kFreeNodesHighWatermark, delete all free nodes until 47 // free nodes <= kFreeNodesLowWatermark. 48 static const size_t kFreeNodesLowWatermark; 49 50 // Maximum limit of FreeNodes allowed on the client. 51 static const size_t kFreeNodesHighWatermark; 52 53 static const int kInvalidTabNodeID; 54 55 // Build a sync tag from tab_node_id. 56 static std::string TabIdToTag(const std::string machine_tag, 57 int tab_node_id); 58 59 // Returns the tab_node_id for the next free tab node. If none are available, 60 // creates a new tab node and adds it to free nodes pool. The free node can 61 // then be used to associate with a tab by calling AssociateTabNode. 62 // Note: The node is considered free until it has been associated. Repeated 63 // calls to GetFreeTabNode will return the same id until node has been 64 // associated. 65 int GetFreeTabNode(); 66 67 // Removes association for |tab_node_id| and returns it to the free node pool. 68 void FreeTabNode(int tab_node_id); 69 70 // Associates |tab_node_id| with |tab_id|. |tab_node_id| should either be 71 // unassociated or free. If |tab_node_id| is free, |tab_node_id| is removed 72 // from the free node pool In order to associate a non free sync node, 73 // use ReassociateTabNode. 74 void AssociateTabNode(int tab_node_id, SessionID::id_type tab_id); 75 76 // Adds |tab_node_id| as an unassociated sync node. 77 // Note: this should only be called when we discover tab sync nodes from 78 // previous sessions, not for freeing tab nodes we created through 79 // GetFreeTabNode (use FreeTabNode below for that). 80 void AddTabNode(int tab_node_id); 81 82 // Returns the tab_id for |tab_node_id| if it is associated else returns 83 // kInvalidTabID. 84 SessionID::id_type GetTabIdFromTabNodeId(int tab_node_id) const; 85 86 // Reassociates |tab_node_id| with |tab_id|. |tab_node_id| must be either 87 // associated with a tab or in the set of unassociated nodes. 88 void ReassociateTabNode(int tab_node_id, SessionID::id_type tab_id); 89 90 // Returns true if |tab_node_id| is an unassociated tab node. 91 bool IsUnassociatedTabNode(int tab_node_id); 92 93 // Deletes any unassociated nodes. 94 void DeleteUnassociatedTabNodes(); 95 96 // Clear tab pool. 97 void Clear(); 98 99 // Return the number of tab nodes this client currently has allocated 100 // (including both free, unassociated and associated nodes) 101 size_t Capacity() const; 102 103 // Return empty status (all tab nodes are in use). 104 bool Empty() const; 105 106 // Return full status (no tab nodes are in use). 107 bool Full(); 108 109 void SetMachineTag(const std::string& machine_tag); 110 111 private: 112 friend class SyncTabNodePoolTest; 113 typedef std::map<int, SessionID::id_type> TabNodeIDToTabIDMap; 114 115 // Adds |tab_node_id| to free node pool. 116 void FreeTabNodeInternal(int tab_node_id); 117 118 // Stores mapping of node ids associated with tab_ids, these are the used 119 // nodes of tab node pool. 120 // The nodes in the map can be returned to free tab node pool by calling 121 // FreeTabNode(tab_node_id). 122 TabNodeIDToTabIDMap nodeid_tabid_map_; 123 124 // The node ids for the set of free sync nodes. 125 std::set<int> free_nodes_pool_; 126 127 // The node ids that are added to pool using AddTabNode and are currently 128 // not associated with any tab. They can be reassociated using 129 // ReassociateTabNode. 130 std::set<int> unassociated_nodes_; 131 132 // The maximum used tab_node id for a sync node. A new sync node will always 133 // be created with max_used_tab_node_id_ + 1. 134 int max_used_tab_node_id_; 135 136 // The machine tag associated with this tab pool. Used in the title of new 137 // sync nodes. 138 std::string machine_tag_; 139 140 // Our sync service profile (for making changes to the sync db) 141 ProfileSyncService* sync_service_; 142 143 DISALLOW_COPY_AND_ASSIGN(TabNodePool); 144 }; 145 146 } // namespace browser_sync 147 148 #endif // CHROME_BROWSER_SYNC_GLUE_TAB_NODE_POOL_H_ 149