10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef CHROME_BROWSER_SYNC_SESSIONS_TAB_NODE_POOL_H_ 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define CHROME_BROWSER_SYNC_SESSIONS_TAB_NODE_POOL_H_ 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <map> 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <set> 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <string> 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/basictypes.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/gtest_prod_util.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/sessions/session_id.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "sync/api/sync_change_processor.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace syncer { 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class SyncChangeProcessor; 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace browser_sync { 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A pool for managing free/used tab sync nodes for the *local* session. 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Performs lazy creation of sync nodes when necessary. 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Note: We make use of the following "id's" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a tab_id: created by session service, unique to this client 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a tab_node_id: the id for a particular sync tab node. This is used 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// to generate the sync tab node tag through: 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id); 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A sync node can be in one of the three states: 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// 1. Associated : Sync node is used and associated with a tab. 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// 2. Unassociated : Sync node is used but currently unassociated with any tab. 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This is true for old nodes that remain from a session 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// restart. Nodes are only unassociated temporarily while the 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// model associator figures out which tabs belong to which 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// nodes. Eventually any remaining unassociated nodes are 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// freed. 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// 3. Free : Sync node is unused. 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass TabNodePool { 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TabNodePool(); 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ~TabNodePool(); 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enum InvalidTab { 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kInvalidTabID = -1 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If free nodes > kFreeNodesHighWatermark, delete all free nodes until 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // free nodes <= kFreeNodesLowWatermark. 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const size_t kFreeNodesLowWatermark; 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Maximum limit of FreeNodes allowed on the client. 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const size_t kFreeNodesHighWatermark; 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const int kInvalidTabNodeID; 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Build a sync tag from tab_node_id. 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static std::string TabIdToTag(const std::string machine_tag, 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int tab_node_id); 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns the tab_node_id for the next free tab node. If none are available, 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // creates a new tab node and adds it to free nodes pool. The free node can 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // then be used to associate with a tab by calling AssociateTabNode. 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Note: The node is considered free until it has been associated. Repeated 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // calls to GetFreeTabNode will return the same id until node has been 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // associated. 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |change_output| *must* be provided. It is the TabNodePool's link to 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the SyncChange pipeline that exists in the caller context. If the need 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // to create nodes arises in the implementation, associated SyncChanges will 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be appended to this list for later application by the caller via the 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // SyncChangeProcessor. 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int GetFreeTabNode(syncer::SyncChangeList* change_output); 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Removes association for |tab_node_id| and returns it to the free node pool. 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |change_output| *must* be provided. It is the TabNodePool's link to 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the SyncChange pipeline that exists in the caller's context. If the need 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // to delete sync nodes arises in the implementation, associated SyncChanges 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // will be appended to this list for later application by the caller via the 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // SyncChangeProcessor. 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void FreeTabNode(int tab_node_id, syncer::SyncChangeList* change_output); 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Associates |tab_node_id| with |tab_id|. |tab_node_id| should either be 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // unassociated or free. If |tab_node_id| is free, |tab_node_id| is removed 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // from the free node pool In order to associate a non free sync node, 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // use ReassociateTabNode. 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AssociateTabNode(int tab_node_id, SessionID::id_type tab_id); 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Adds |tab_node_id| as an unassociated sync node. 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Note: this should only be called when we discover tab sync nodes from 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // previous sessions, not for freeing tab nodes we created through 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // GetFreeTabNode (use FreeTabNode below for that). 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddTabNode(int tab_node_id); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns the tab_id for |tab_node_id| if it is associated else returns 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // kInvalidTabID. 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SessionID::id_type GetTabIdFromTabNodeId(int tab_node_id) const; 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Reassociates |tab_node_id| with |tab_id|. |tab_node_id| must be either 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // associated with a tab or in the set of unassociated nodes. 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ReassociateTabNode(int tab_node_id, SessionID::id_type tab_id); 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns true if |tab_node_id| is an unassociated tab node. 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool IsUnassociatedTabNode(int tab_node_id); 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns any unassociated nodes to the free node pool. 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |change_output| *must* be provided. It is the TabNodePool's link to 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the SyncChange pipeline that exists in the caller's context. 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See FreeTabNode for more detail. 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void DeleteUnassociatedTabNodes(syncer::SyncChangeList* change_output); 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Clear tab pool. 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void Clear(); 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Return the number of tab nodes this client currently has allocated 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // (including both free, unassociated and associated nodes) 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t Capacity() const; 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Return empty status (all tab nodes are in use). 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool Empty() const; 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Return full status (no tab nodes are in use). 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool Full(); 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void SetMachineTag(const std::string& machine_tag); 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch friend class SyncTabNodePoolTest; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) typedef std::map<int, SessionID::id_type> TabNodeIDToTabIDMap; 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Adds |tab_node_id| to free node pool. 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |change_output| *must* be provided. It is the TabNodePool's link to 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the SyncChange pipeline that exists in the caller's context. 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See FreeTabNode for more detail. 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void FreeTabNodeInternal(int tab_node_id, 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) syncer::SyncChangeList* change_output); 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Stores mapping of node ids associated with tab_ids, these are the used 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // nodes of tab node pool. 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The nodes in the map can be returned to free tab node pool by calling 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // FreeTabNode(tab_node_id). 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TabNodeIDToTabIDMap nodeid_tabid_map_; 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The node ids for the set of free sync nodes. 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<int> free_nodes_pool_; 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The node ids that are added to pool using AddTabNode and are currently 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // not associated with any tab. They can be reassociated using 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // ReassociateTabNode. 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<int> unassociated_nodes_; 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The maximum used tab_node id for a sync node. A new sync node will always 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be created with max_used_tab_node_id_ + 1. 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int max_used_tab_node_id_; 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The machine tag associated with this tab pool. Used in the title of new 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // sync nodes. 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string machine_tag_; 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(TabNodePool); 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace browser_sync 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif // CHROME_BROWSER_SYNC_SESSIONS_TAB_NODE_POOL_H_ 166