| Index: chrome/browser/sync/glue/tab_node_pool.cc
|
| diff --git a/chrome/browser/sync/glue/tab_node_pool.cc b/chrome/browser/sync/glue/tab_node_pool.cc
|
| index 2ec77b2904313c24b917db471179a4bd2cdd8ba9..5d44c392c630cde284896cc36eb9f9f65493b74f 100644
|
| --- a/chrome/browser/sync/glue/tab_node_pool.cc
|
| +++ b/chrome/browser/sync/glue/tab_node_pool.cc
|
| @@ -20,11 +20,10 @@ static const char kNoSessionsFolderError[] =
|
| "Server did not create the top-level sessions node. We "
|
| "might be running against an out-of-date server.";
|
|
|
| -TabNodePool::TabNodePool(
|
| - ProfileSyncService* sync_service)
|
| - : tab_pool_fp_(-1),
|
| - sync_service_(sync_service) {
|
| -}
|
| +static const size_t kMaxNumberOfFreeNodes = 25;
|
| +
|
| +TabNodePool::TabNodePool(ProfileSyncService* sync_service)
|
| + : max_used_tab_node_id_(0), sync_service_(sync_service) {}
|
|
|
| TabNodePool::~TabNodePool() {}
|
|
|
| @@ -35,14 +34,30 @@ std::string TabNodePool::TabIdToTag(
|
| return base::StringPrintf("%s %" PRIuS "", machine_tag.c_str(), tab_node_id);
|
| }
|
|
|
| -void TabNodePool::AddTabNode(int64 sync_id) {
|
| - tab_syncid_pool_.resize(tab_syncid_pool_.size() + 1);
|
| - tab_syncid_pool_[static_cast<size_t>(++tab_pool_fp_)] = sync_id;
|
| +void TabNodePool::AddTabNode(int64 sync_id,
|
| + const SessionID& tab_id,
|
| + size_t tab_node_id) {
|
| + DCHECK_GT(sync_id, syncer::kInvalidId);
|
| + DCHECK_GT(tab_id.id(), kInvalidTabID);
|
| + DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
|
| + syncid_tabid_map_[sync_id] = tab_id.id();
|
| + if (max_used_tab_node_id_ < tab_node_id)
|
| + max_used_tab_node_id_ = tab_node_id;
|
| +}
|
| +
|
| +void TabNodePool::AssociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
|
| + DCHECK_GT(sync_id, 0);
|
| + // Remove node from free node pool and associate it with tab.
|
| + std::set<int64>::iterator it = free_nodes_pool_.find(sync_id);
|
| + DCHECK(it != free_nodes_pool_.end());
|
| + free_nodes_pool_.erase(it);
|
| + DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
|
| + syncid_tabid_map_[sync_id] = tab_id;
|
| }
|
|
|
| int64 TabNodePool::GetFreeTabNode() {
|
| DCHECK_GT(machine_tag_.length(), 0U);
|
| - if (tab_pool_fp_ == -1) {
|
| + if (free_nodes_pool_.empty()) {
|
| // Tab pool has no free nodes, allocate new one.
|
| syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
|
| syncer::ReadNode root(&trans);
|
| @@ -51,7 +66,7 @@ int64 TabNodePool::GetFreeTabNode() {
|
| LOG(ERROR) << kNoSessionsFolderError;
|
| return syncer::kInvalidId;
|
| }
|
| - size_t tab_node_id = tab_syncid_pool_.size();
|
| + size_t tab_node_id = ++max_used_tab_node_id_;
|
| std::string tab_node_tag = TabIdToTag(machine_tag_, tab_node_id);
|
| syncer::WriteNode tab_node(&trans);
|
| syncer::WriteNode::InitUniqueByCreationResult result =
|
| @@ -69,23 +84,86 @@ int64 TabNodePool::GetFreeTabNode() {
|
| specifics.set_tab_node_id(tab_node_id);
|
| tab_node.SetSessionSpecifics(specifics);
|
|
|
| - // Grow the pool by 1 since we created a new node. We don't actually need
|
| - // to put the node's id in the pool now, since the pool is still empty.
|
| - // The id will be added when that tab is closed and the node is freed.
|
| - tab_syncid_pool_.resize(tab_node_id + 1);
|
| - DVLOG(1) << "Adding sync node "
|
| - << tab_node.GetId() << " to tab syncid pool";
|
| + // Grow the pool by 1 since we created a new node.
|
| + DVLOG(1) << "Adding sync node " << tab_node.GetId()
|
| + << " to tab syncid pool";
|
| + free_nodes_pool_.insert(tab_node.GetId());
|
| return tab_node.GetId();
|
| } else {
|
| - // There are nodes available, grab next free and decrement free pointer.
|
| - return tab_syncid_pool_[static_cast<size_t>(tab_pool_fp_--)];
|
| + // Return the next free node.
|
| + return *free_nodes_pool_.begin();
|
| }
|
| }
|
|
|
| void TabNodePool::FreeTabNode(int64 sync_id) {
|
| - // Pool size should always match # of free tab nodes.
|
| - DCHECK_LT(tab_pool_fp_, static_cast<int64>(tab_syncid_pool_.size()));
|
| - tab_syncid_pool_[static_cast<size_t>(++tab_pool_fp_)] = sync_id;
|
| + SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
|
| + DCHECK(it != syncid_tabid_map_.end());
|
| + syncid_tabid_map_.erase(it);
|
| + DCHECK(free_nodes_pool_.find(sync_id) == free_nodes_pool_.end());
|
| +
|
| + // If number of free nodes exceed number of maximum allowed free nodes,
|
| + // delete the sync node.
|
| + if (free_nodes_pool_.size() < kMaxNumberOfFreeNodes) {
|
| + free_nodes_pool_.insert(sync_id);
|
| + } else {
|
| + syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
|
| + syncer::WriteNode tab_node(&trans);
|
| + if (tab_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) {
|
| + LOG(ERROR) << "Could not find sync node with id: " << sync_id;
|
| + return;
|
| + }
|
| + tab_node.Tombstone();
|
| + }
|
| +}
|
| +
|
| +bool TabNodePool::ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
|
| + SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
|
| + if (it != syncid_tabid_map_.end()) {
|
| + syncid_tabid_map_[sync_id] = tab_id;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +SessionID::id_type TabNodePool::GetTabIdFromSyncId(int64 sync_id) const {
|
| + SyncIDToTabIDMap::const_iterator it = syncid_tabid_map_.find(sync_id);
|
| + if (it != syncid_tabid_map_.end()) {
|
| + return it->second;
|
| + }
|
| + return kInvalidTabID;
|
| +}
|
| +
|
| +void TabNodePool::FreeUnusedTabNodes(const std::set<int64>& used_sync_ids) {
|
| + for (SyncIDToTabIDMap::iterator it = syncid_tabid_map_.begin();
|
| + it != syncid_tabid_map_.end();) {
|
| + if (used_sync_ids.find(it->first) == used_sync_ids.end()) {
|
| + // This sync node is not used, return it to free node pool.
|
| + int64 sync_id = it->first;
|
| + ++it;
|
| + FreeTabNode(sync_id);
|
| + } else {
|
| + ++it;
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Clear tab pool.
|
| +void TabNodePool::Clear() {
|
| + free_nodes_pool_.clear();
|
| + syncid_tabid_map_.clear();
|
| + max_used_tab_node_id_ = 0;
|
| +}
|
| +
|
| +size_t TabNodePool::Capacity() const {
|
| + return syncid_tabid_map_.size() + free_nodes_pool_.size();
|
| +}
|
| +
|
| +bool TabNodePool::Empty() const { return free_nodes_pool_.empty(); }
|
| +
|
| +bool TabNodePool::Full() { return syncid_tabid_map_.empty(); }
|
| +
|
| +void TabNodePool::SetMachineTag(const std::string& machine_tag) {
|
| + machine_tag_ = machine_tag;
|
| }
|
|
|
| } // namespace browser_sync
|
|
|