1 // Copyright (c) 2010 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 #include "chrome/browser/sync/sessions/ordered_commit_set.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 11 namespace browser_sync { 12 namespace sessions { 13 14 OrderedCommitSet::OrderedCommitSet( 15 const browser_sync::ModelSafeRoutingInfo& routes) 16 : routes_(routes) { 17 } 18 19 OrderedCommitSet::~OrderedCommitSet() {} 20 21 void OrderedCommitSet::AddCommitItem(const int64 metahandle, 22 const syncable::Id& commit_id, 23 syncable::ModelType type) { 24 if (!HaveCommitItem(metahandle)) { 25 inserted_metahandles_.insert(metahandle); 26 metahandle_order_.push_back(metahandle); 27 commit_ids_.push_back(commit_id); 28 projections_[GetGroupForModelType(type, routes_)].push_back( 29 commit_ids_.size() - 1); 30 types_.push_back(type); 31 } 32 } 33 34 void OrderedCommitSet::AppendReverse(const OrderedCommitSet& other) { 35 for (int i = other.Size() - 1; i >= 0; i--) { 36 CommitItem item = other.GetCommitItemAt(i); 37 AddCommitItem(item.meta, item.id, item.group); 38 } 39 } 40 41 void OrderedCommitSet::Truncate(size_t max_size) { 42 if (max_size < metahandle_order_.size()) { 43 for (size_t i = max_size; i < metahandle_order_.size(); ++i) { 44 inserted_metahandles_.erase(metahandle_order_[i]); 45 } 46 47 // Some projections may refer to indices that are getting chopped. 48 // Since projections are in increasing order, it's easy to fix. Except 49 // that you can't erase(..) using a reverse_iterator, so we use binary 50 // search to find the chop point. 51 Projections::iterator it = projections_.begin(); 52 for (; it != projections_.end(); ++it) { 53 // For each projection, chop off any indices larger than or equal to 54 // max_size by looking for max_size using binary search. 55 Projection& p = it->second; 56 Projection::iterator element = std::lower_bound(p.begin(), p.end(), 57 max_size); 58 if (element != p.end()) 59 p.erase(element, p.end()); 60 } 61 commit_ids_.resize(max_size); 62 metahandle_order_.resize(max_size); 63 types_.resize(max_size); 64 } 65 } 66 67 OrderedCommitSet::CommitItem OrderedCommitSet::GetCommitItemAt( 68 const int position) const { 69 DCHECK(position < Size()); 70 CommitItem return_item = {metahandle_order_[position], 71 commit_ids_[position], 72 types_[position]}; 73 return return_item; 74 } 75 76 bool OrderedCommitSet::HasBookmarkCommitId() const { 77 ModelSafeRoutingInfo::const_iterator group 78 = routes_.find(syncable::BOOKMARKS); 79 if (group == routes_.end()) 80 return false; 81 Projections::const_iterator proj = projections_.find(group->second); 82 if (proj == projections_.end()) 83 return false; 84 DCHECK_LE(proj->second.size(), types_.size()); 85 for (size_t i = 0; i < proj->second.size(); i++) { 86 if (types_[proj->second[i]] == syncable::BOOKMARKS) 87 return true; 88 } 89 return false; 90 } 91 92 void OrderedCommitSet::operator=(const OrderedCommitSet& other) { 93 inserted_metahandles_ = other.inserted_metahandles_; 94 commit_ids_ = other.commit_ids_; 95 metahandle_order_ = other.metahandle_order_; 96 projections_ = other.projections_; 97 types_ = other.types_; 98 routes_ = other.routes_; 99 } 100 101 } // namespace sessions 102 } // namespace browser_sync 103 104