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