1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// 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"
#include "components/sync/model/sync_change_processor.h"
namespace syncer {
class SyncChangeProcessor;
} // namespace syncer
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_%ui", local_session_tag, tab_node_id);
//
// A sync node can be in one of the three states:
// 1. Associated : Sync node is used and associated with a tab.
// 2. Unassociated : Sync node is used but currently unassociated with any tab.
// This is true for old nodes that remain from a session
// restart. Nodes are only unassociated temporarily while the
// model associator figures out which tabs belong to which
// nodes. Eventually any remaining unassociated nodes are
// freed.
// 3. Free : Sync node is unused.
class TabNodePool {
public:
TabNodePool();
~TabNodePool();
enum InvalidTab { kInvalidTabID = -1 };
// 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;
// Build a sync tag from tab_node_id.
static std::string TabIdToTag(const std::string& machine_tag,
int tab_node_id);
// Returns the tab_node_id for the next free tab node. If none are available,
// creates a new tab node and adds it to free nodes pool. The free node can
// then be used to associate with a tab by calling AssociateTabNode.
// Note: The node is considered free until it has been associated. Repeated
// calls to GetFreeTabNode will return the same id until node has been
// associated.
// |change_output| *must* be provided. It is the TabNodePool's link to
// the SyncChange pipeline that exists in the caller context. If the need
// to create nodes arises in the implementation, associated SyncChanges will
// be appended to this list for later application by the caller via the
// SyncChangeProcessor.
int GetFreeTabNode(syncer::SyncChangeList* change_output);
// Removes association for |tab_node_id| and returns it to the free node pool.
// |change_output| *must* be provided. It is the TabNodePool's link to
// the SyncChange pipeline that exists in the caller's context. If the need
// to delete sync nodes arises in the implementation, associated SyncChanges
// will be appended to this list for later application by the caller via the
// SyncChangeProcessor.
void FreeTabNode(int tab_node_id, syncer::SyncChangeList* change_output);
// Associates |tab_node_id| with |tab_id|. |tab_node_id| should either be
// unassociated or free. If |tab_node_id| is free, |tab_node_id| is removed
// from the free node pool In order to associate a non free sync node,
// use ReassociateTabNode.
void AssociateTabNode(int tab_node_id, SessionID::id_type tab_id);
// Adds |tab_node_id| as an unassociated sync node.
// Note: this should only be called when we discover tab sync nodes from
// previous sessions, not for freeing tab nodes we created through
// GetFreeTabNode (use FreeTabNode below for that).
void AddTabNode(int tab_node_id);
// Returns the tab_id for |tab_node_id| if it is associated else returns
// kInvalidTabID.
SessionID::id_type GetTabIdFromTabNodeId(int tab_node_id) const;
// Reassociates |tab_node_id| with |tab_id|. |tab_node_id| must be either
// associated with a tab or in the set of unassociated nodes.
void ReassociateTabNode(int tab_node_id, SessionID::id_type tab_id);
// Returns true if |tab_node_id| is an unassociated tab node.
bool IsUnassociatedTabNode(int tab_node_id);
// Returns any unassociated nodes to the free node pool.
// |change_output| *must* be provided. It is the TabNodePool's link to
// the SyncChange pipeline that exists in the caller's context.
// See FreeTabNode for more detail.
void DeleteUnassociatedTabNodes(syncer::SyncChangeList* change_output);
// Clear tab pool.
void Clear();
// Return the number of tab nodes this client currently has allocated
// (including both free, unassociated 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();
void SetMachineTag(const std::string& machine_tag);
private:
friend class SyncTabNodePoolTest;
typedef std::map<int, SessionID::id_type> TabNodeIDToTabIDMap;
// Adds |tab_node_id| to free node pool.
// |change_output| *must* be provided. It is the TabNodePool's link to
// the SyncChange pipeline that exists in the caller's context.
// See FreeTabNode for more detail.
void FreeTabNodeInternal(int tab_node_id,
syncer::SyncChangeList* change_output);
// 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
// FreeTabNode(tab_node_id).
TabNodeIDToTabIDMap nodeid_tabid_map_;
// The node ids for the set of free sync nodes.
std::set<int> free_nodes_pool_;
// The node ids that are added to pool using AddTabNode and are currently
// not associated with any tab. They can be reassociated using
// ReassociateTabNode.
std::set<int> unassociated_nodes_;
// 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_;
// The machine tag associated with this tab pool. Used in the title of new
// sync nodes.
std::string machine_tag_;
DISALLOW_COPY_AND_ASSIGN(TabNodePool);
};
} // namespace sync_sessions
#endif // COMPONENTS_SYNC_SESSIONS_TAB_NODE_POOL_H_
|