Home | History | Annotate | Download | only in engine
      1 // Copyright (c) 2006-2009 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 #ifndef CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
      6 #define CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
      7 #pragma once
      8 
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "chrome/browser/sync/engine/syncer_command.h"
     13 #include "chrome/browser/sync/engine/syncer_util.h"
     14 #include "chrome/browser/sync/sessions/ordered_commit_set.h"
     15 #include "chrome/browser/sync/sessions/sync_session.h"
     16 
     17 using std::pair;
     18 using std::vector;
     19 
     20 namespace browser_sync {
     21 
     22 class GetCommitIdsCommand : public SyncerCommand {
     23   friend class SyncerTest;
     24 
     25  public:
     26   explicit GetCommitIdsCommand(int commit_batch_size);
     27   virtual ~GetCommitIdsCommand();
     28 
     29   // SyncerCommand implementation.
     30   virtual void ExecuteImpl(sessions::SyncSession* session);
     31 
     32   // Builds a vector of IDs that should be committed.
     33   void BuildCommitIds(const vector<int64>& unsynced_handles,
     34                       syncable::WriteTransaction* write_transaction,
     35                       const ModelSafeRoutingInfo& routes);
     36 
     37   // TODO(chron): Remove writes from this iterator. As a warning, this
     38   // iterator causes writes to entries and so isn't a pure iterator.
     39   // It will do Put(IS_UNSYNCED). Refactor this out later.
     40   class CommitMetahandleIterator {
     41    public:
     42     // TODO(chron): Cache ValidateCommitEntry responses across iterators to save
     43     // UTF8 conversion and filename checking
     44     CommitMetahandleIterator(const vector<int64>& unsynced_handles,
     45                              syncable::WriteTransaction* write_transaction,
     46                              sessions::OrderedCommitSet* commit_set)
     47         : write_transaction_(write_transaction),
     48           handle_iterator_(unsynced_handles.begin()),
     49           unsynced_handles_end_(unsynced_handles.end()),
     50           commit_set_(commit_set) {
     51 
     52       // TODO(chron): Remove writes from this iterator.
     53       DCHECK(write_transaction_);
     54 
     55       if (Valid() && !ValidateMetahandleForCommit(*handle_iterator_))
     56         Increment();
     57     }
     58     ~CommitMetahandleIterator() {}
     59 
     60     int64 Current() const {
     61       DCHECK(Valid());
     62       return *handle_iterator_;
     63     }
     64 
     65     bool Increment() {
     66       if (!Valid())
     67         return false;
     68 
     69       for (++handle_iterator_;
     70            handle_iterator_ != unsynced_handles_end_;
     71            ++handle_iterator_) {
     72         if (ValidateMetahandleForCommit(*handle_iterator_))
     73           return true;
     74       }
     75 
     76       return false;
     77     }
     78 
     79     bool Valid() const {
     80       return !(handle_iterator_ == unsynced_handles_end_);
     81     }
     82 
     83     private:
     84      bool ValidateMetahandleForCommit(int64 metahandle) {
     85        if (commit_set_->HaveCommitItem(metahandle))
     86           return false;
     87 
     88        // We should really not WRITE in this iterator, but we can fix that
     89        // later. We should move that somewhere else later.
     90        syncable::MutableEntry entry(write_transaction_,
     91            syncable::GET_BY_HANDLE, metahandle);
     92        VerifyCommitResult verify_result =
     93            SyncerUtil::ValidateCommitEntry(&entry);
     94        if (verify_result == VERIFY_UNSYNCABLE) {
     95          // Drop unsyncable entries.
     96          entry.Put(syncable::IS_UNSYNCED, false);
     97        }
     98        return verify_result == VERIFY_OK;
     99      }
    100 
    101      syncable::WriteTransaction* const write_transaction_;
    102      vector<int64>::const_iterator handle_iterator_;
    103      vector<int64>::const_iterator unsynced_handles_end_;
    104      sessions::OrderedCommitSet* commit_set_;
    105 
    106      DISALLOW_COPY_AND_ASSIGN(CommitMetahandleIterator);
    107   };
    108 
    109  private:
    110   void AddUncommittedParentsAndTheirPredecessors(
    111       syncable::BaseTransaction* trans,
    112       syncable::Id parent_id,
    113       const ModelSafeRoutingInfo& routes);
    114 
    115   // OrderedCommitSet helpers for adding predecessors in order.
    116   // TODO(ncarter): Refactor these so that the |result| parameter goes away,
    117   // and AddItem doesn't need to consider two OrderedCommitSets.
    118   bool AddItem(syncable::Entry* item, sessions::OrderedCommitSet* result);
    119   bool AddItemThenPredecessors(syncable::BaseTransaction* trans,
    120                                syncable::Entry* item,
    121                                syncable::IndexedBitField inclusion_filter,
    122                                sessions::OrderedCommitSet* result);
    123   void AddPredecessorsThenItem(syncable::BaseTransaction* trans,
    124                                syncable::Entry* item,
    125                                syncable::IndexedBitField inclusion_filter,
    126                                const ModelSafeRoutingInfo& routes);
    127 
    128   bool IsCommitBatchFull();
    129 
    130   void AddCreatesAndMoves(const vector<int64>& unsynced_handles,
    131                           syncable::WriteTransaction* write_transaction,
    132                           const ModelSafeRoutingInfo& routes);
    133 
    134   void AddDeletes(const vector<int64>& unsynced_handles,
    135                   syncable::WriteTransaction* write_transaction);
    136 
    137   scoped_ptr<sessions::OrderedCommitSet> ordered_commit_set_;
    138 
    139   int requested_commit_batch_size_;
    140 
    141   DISALLOW_COPY_AND_ASSIGN(GetCommitIdsCommand);
    142 };
    143 
    144 }  // namespace browser_sync
    145 
    146 #endif  // CHROME_BROWSER_SYNC_ENGINE_GET_COMMIT_IDS_COMMAND_H_
    147