| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sync/engine/build_commit_command.h" | 5 #include "sync/engine/build_commit_command.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "sync/engine/syncer_proto_util.h" | 13 #include "sync/engine/syncer_proto_util.h" |
| 14 #include "sync/internal_api/public/base/unique_position.h" |
| 14 #include "sync/protocol/bookmark_specifics.pb.h" | 15 #include "sync/protocol/bookmark_specifics.pb.h" |
| 15 #include "sync/protocol/sync.pb.h" | 16 #include "sync/protocol/sync.pb.h" |
| 16 #include "sync/sessions/ordered_commit_set.h" | 17 #include "sync/sessions/ordered_commit_set.h" |
| 17 #include "sync/sessions/sync_session.h" | 18 #include "sync/sessions/sync_session.h" |
| 18 #include "sync/syncable/directory.h" | 19 #include "sync/syncable/directory.h" |
| 19 #include "sync/syncable/mutable_entry.h" | 20 #include "sync/syncable/mutable_entry.h" |
| 20 #include "sync/syncable/syncable_changes_version.h" | 21 #include "sync/syncable/syncable_changes_version.h" |
| 21 #include "sync/syncable/syncable_proto_util.h" | 22 #include "sync/syncable/syncable_proto_util.h" |
| 22 #include "sync/syncable/write_transaction.h" | 23 #include "sync/syncable/write_transaction.h" |
| 23 #include "sync/util/time.h" | 24 #include "sync/util/time.h" |
| 24 | 25 |
| 25 // TODO(vishwath): Remove this include after node positions have | |
| 26 // shifted to completely using Ordinals. | |
| 27 // See http://crbug.com/145412 . | |
| 28 #include "sync/internal_api/public/base/node_ordinal.h" | |
| 29 | |
| 30 using std::set; | 26 using std::set; |
| 31 using std::string; | 27 using std::string; |
| 32 using std::vector; | 28 using std::vector; |
| 33 | 29 |
| 34 namespace syncer { | 30 namespace syncer { |
| 35 | 31 |
| 36 using sessions::SyncSession; | 32 using sessions::SyncSession; |
| 37 using syncable::Entry; | 33 using syncable::Entry; |
| 38 using syncable::IS_DEL; | 34 using syncable::IS_DEL; |
| 39 using syncable::SERVER_ORDINAL_IN_PARENT; | |
| 40 using syncable::IS_UNAPPLIED_UPDATE; | 35 using syncable::IS_UNAPPLIED_UPDATE; |
| 41 using syncable::IS_UNSYNCED; | 36 using syncable::IS_UNSYNCED; |
| 42 using syncable::Id; | 37 using syncable::Id; |
| 43 using syncable::MutableEntry; | 38 using syncable::MutableEntry; |
| 39 using syncable::SERVER_UNIQUE_POSITION; |
| 44 using syncable::SPECIFICS; | 40 using syncable::SPECIFICS; |
| 45 | 41 using syncable::UNIQUE_POSITION; |
| 46 // static | |
| 47 int64 BuildCommitCommand::GetFirstPosition() { | |
| 48 return std::numeric_limits<int64>::min(); | |
| 49 } | |
| 50 | |
| 51 // static | |
| 52 int64 BuildCommitCommand::GetLastPosition() { | |
| 53 return std::numeric_limits<int64>::max(); | |
| 54 } | |
| 55 | |
| 56 // static | |
| 57 int64 BuildCommitCommand::GetGap() { | |
| 58 return 1LL << 20; | |
| 59 } | |
| 60 | 42 |
| 61 BuildCommitCommand::BuildCommitCommand( | 43 BuildCommitCommand::BuildCommitCommand( |
| 62 const sessions::OrderedCommitSet& batch_commit_set, | 44 const sessions::OrderedCommitSet& batch_commit_set, |
| 63 sync_pb::ClientToServerMessage* commit_message) | 45 sync_pb::ClientToServerMessage* commit_message) |
| 64 : batch_commit_set_(batch_commit_set), commit_message_(commit_message) { | 46 : batch_commit_set_(batch_commit_set), commit_message_(commit_message) { |
| 65 } | 47 } |
| 66 | 48 |
| 67 BuildCommitCommand::~BuildCommitCommand() {} | 49 BuildCommitCommand::~BuildCommitCommand() {} |
| 68 | 50 |
| 69 void BuildCommitCommand::AddExtensionsActivityToMessage( | 51 void BuildCommitCommand::AddExtensionsActivityToMessage( |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 sync_entry->set_version(meta_entry.Get(syncable::BASE_VERSION)); | 171 sync_entry->set_version(meta_entry.Get(syncable::BASE_VERSION)); |
| 190 } | 172 } |
| 191 sync_entry->set_ctime(TimeToProtoTime(meta_entry.Get(syncable::CTIME))); | 173 sync_entry->set_ctime(TimeToProtoTime(meta_entry.Get(syncable::CTIME))); |
| 192 sync_entry->set_mtime(TimeToProtoTime(meta_entry.Get(syncable::MTIME))); | 174 sync_entry->set_mtime(TimeToProtoTime(meta_entry.Get(syncable::MTIME))); |
| 193 | 175 |
| 194 // Deletion is final on the server, let's move things and then delete them. | 176 // Deletion is final on the server, let's move things and then delete them. |
| 195 if (meta_entry.Get(IS_DEL)) { | 177 if (meta_entry.Get(IS_DEL)) { |
| 196 sync_entry->set_deleted(true); | 178 sync_entry->set_deleted(true); |
| 197 } else { | 179 } else { |
| 198 if (meta_entry.Get(SPECIFICS).has_bookmark()) { | 180 if (meta_entry.Get(SPECIFICS).has_bookmark()) { |
| 199 // Common data in both new and old protocol. | 181 const Id& prev_id = meta_entry.GetPredecessorId(); |
| 200 const Id& prev_id = meta_entry.Get(syncable::PREV_ID); | |
| 201 string prev_id_string = | 182 string prev_id_string = |
| 202 prev_id.IsRoot() ? string() : prev_id.GetServerId(); | 183 prev_id.IsRoot() ? string() : prev_id.GetServerId(); |
| 203 sync_entry->set_insert_after_item_id(prev_id_string); | 184 sync_entry->set_insert_after_item_id(prev_id_string); |
| 204 | 185 sync_entry->set_position_in_parent( |
| 205 // Compute a numeric position based on what we know locally. | 186 meta_entry.Get(UNIQUE_POSITION).ToInt64()); |
| 206 std::pair<int64, int64> position_block( | 187 sync_entry->set_unique_position( |
| 207 GetFirstPosition(), GetLastPosition()); | 188 meta_entry.Get(UNIQUE_POSITION).ToInternalValue()); |
| 208 std::map<Id, std::pair<int64, int64> >::iterator prev_pos = | |
| 209 position_map.find(prev_id); | |
| 210 if (prev_pos != position_map.end()) { | |
| 211 position_block = prev_pos->second; | |
| 212 position_map.erase(prev_pos); | |
| 213 } else { | |
| 214 position_block = std::make_pair( | |
| 215 FindAnchorPosition(syncable::PREV_ID, meta_entry), | |
| 216 FindAnchorPosition(syncable::NEXT_ID, meta_entry)); | |
| 217 } | |
| 218 position_block.first = InterpolatePosition(position_block.first, | |
| 219 position_block.second); | |
| 220 | |
| 221 position_map[id] = position_block; | |
| 222 sync_entry->set_position_in_parent(position_block.first); | |
| 223 } | 189 } |
| 224 SetEntrySpecifics(&meta_entry, sync_entry); | 190 SetEntrySpecifics(&meta_entry, sync_entry); |
| 225 } | 191 } |
| 226 } | 192 } |
| 227 | 193 |
| 228 return SYNCER_OK; | 194 return SYNCER_OK; |
| 229 } | 195 } |
| 230 | 196 |
| 231 int64 BuildCommitCommand::FindAnchorPosition(syncable::IdField direction, | |
| 232 const syncable::Entry& entry) { | |
| 233 Id next_id = entry.Get(direction); | |
| 234 while (!next_id.IsRoot()) { | |
| 235 Entry next_entry(entry.trans(), | |
| 236 syncable::GET_BY_ID, | |
| 237 next_id); | |
| 238 if (!next_entry.Get(IS_UNSYNCED) && !next_entry.Get(IS_UNAPPLIED_UPDATE)) { | |
| 239 return NodeOrdinalToInt64(next_entry.Get(SERVER_ORDINAL_IN_PARENT)); | |
| 240 } | |
| 241 next_id = next_entry.Get(direction); | |
| 242 } | |
| 243 return | |
| 244 direction == syncable::PREV_ID ? | |
| 245 GetFirstPosition() : GetLastPosition(); | |
| 246 } | |
| 247 | |
| 248 int64 BuildCommitCommand::InterpolatePosition(const int64 lo, | |
| 249 const int64 hi) { | |
| 250 DCHECK_LE(lo, hi); | |
| 251 | |
| 252 // The first item to be added under a parent gets a position of zero. | |
| 253 if (lo == GetFirstPosition() && hi == GetLastPosition()) | |
| 254 return 0; | |
| 255 | |
| 256 // For small gaps, we do linear interpolation. For larger gaps, | |
| 257 // we use an additive offset of |GetGap()|. We are careful to avoid | |
| 258 // signed integer overflow. | |
| 259 uint64 delta = static_cast<uint64>(hi) - static_cast<uint64>(lo); | |
| 260 if (delta <= static_cast<uint64>(GetGap()*2)) | |
| 261 return lo + (static_cast<int64>(delta) + 7) / 8; // Interpolate. | |
| 262 else if (lo == GetFirstPosition()) | |
| 263 return hi - GetGap(); // Extend range just before successor. | |
| 264 else | |
| 265 return lo + GetGap(); // Use or extend range just after predecessor. | |
| 266 } | |
| 267 | |
| 268 | |
| 269 } // namespace syncer | 197 } // namespace syncer |
| OLD | NEW |