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