blob: 2951d8bd06292a7e4cee0dd119b3972529822588 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_MODEL_IMPL_PROCESSOR_ENTITY_H_
#define COMPONENTS_SYNC_MODEL_IMPL_PROCESSOR_ENTITY_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "base/time/time.h"
#include "components/sync/base/model_type.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/protocol/entity_metadata.pb.h"
namespace syncer {
struct CommitRequestData;
struct CommitResponseData;
struct UpdateResponseData;
// This class is used by the ClientTagBasedModelTypeProcessor to track the state
// of each entity with its type. It can be considered a helper class internal to
// the processor. It manages the metadata for its entity and caches entity data
// upon a local change until commit confirmation is received.
class ProcessorEntity {
public:
// Construct an instance representing a new locally-created item.
static std::unique_ptr<ProcessorEntity> CreateNew(
const std::string& storage_key,
const std::string& client_tag_hash,
const std::string& id,
base::Time creation_time);
// Construct an instance representing an item loaded from storage on init.
static std::unique_ptr<ProcessorEntity> CreateFromMetadata(
const std::string& storage_key,
sync_pb::EntityMetadata metadata);
~ProcessorEntity();
const std::string& storage_key() const { return storage_key_; }
const sync_pb::EntityMetadata& metadata() const { return metadata_; }
const EntityData& commit_data() { return *commit_data_; }
base::Time unsynced_time() const { return unsynced_time_; }
// Returns true if this data is out of sync with the server.
// A commit may or may not be in progress at this time.
bool IsUnsynced() const;
// Returns true if this data is out of sync with the sync thread.
//
// There may or may not be a commit in progress for this item, but there's
// definitely no commit in progress for this (most up to date) version of
// this item.
bool RequiresCommitRequest() const;
// Whether commit data is needed to be cached before a commit request can be
// created. Note that deletions do not require cached data.
bool RequiresCommitData() const;
// Whether it's safe to clear the metadata for this entity. This means that
// the entity is deleted and either knowledge of this entity has never left
// this client or it is up to date with the server.
bool CanClearMetadata() const;
// Returns true if the specified update version does not contain new data.
bool UpdateIsReflection(int64_t update_version) const;
void RecordEntityUpdateLatency(int64_t update_version, ModelType type);
// Records that an update from the server was received but ignores its data.
void RecordIgnoredUpdate(const UpdateResponseData& response_data);
// Records an update from the server assuming its data is the new data for
// this entity.
void RecordAcceptedUpdate(const UpdateResponseData& response_data);
// Squashes a pending commit with an update from the server.
void RecordForcedUpdate(const UpdateResponseData& response_data);
// Applies a local change to this item.
void MakeLocalChange(std::unique_ptr<EntityData> data);
// Applies a local deletion to this item. Returns true if entity was
// previously committed to server and tombstone should be sent.
bool Delete();
// Initializes a message representing this item's uncommitted state
// and assumes that it is forwarded to the sync engine for commiting.
void InitializeCommitRequestData(CommitRequestData* request);
// Receives a successful commit response.
//
// Successful commit responses can overwrite an item's ID.
//
// Note that the receipt of a successful commit response does not necessarily
// unset IsUnsynced(). If many local changes occur in quick succession, it's
// possible that the committed item was already out of date by the time it
// reached the server.
void ReceiveCommitResponse(const CommitResponseData& data,
bool commit_only,
ModelType type_for_uma);
// Clears any in-memory sync state associated with outstanding commits.
void ClearTransientSyncState();
// Update storage_key_. Allows setting storage key for datatypes that don't
// generate storage key from syncer::EntityData. Should only be called for
// an entity initialized with empty storage key.
void SetStorageKey(const std::string& storage_key);
// Undoes SetStorageKey(), which is needed in certain conflict resolution
// scenarios.
void ClearStorageKey();
// Takes the passed commit data updates its fields with values from metadata
// and caches it in the instance.
void SetCommitData(std::unique_ptr<EntityData> data);
void CacheCommitData(std::unique_ptr<EntityData> data);
// Check if the instance has cached commit data.
bool HasCommitData() const;
// Check whether |data| matches the stored specifics hash.
bool MatchesData(const EntityData& data) const;
// Check whether the current metadata of an unsynced entity matches the stored
// base specifics hash.
bool MatchesOwnBaseData() const;
// Check whether |data| matches the stored base specifics hash.
bool MatchesBaseData(const EntityData& data) const;
// Increment sequence number in the metadata. This will also update the
// base_specifics_hash if the entity was not already unsynced.
void IncrementSequenceNumber(base::Time modification_time);
// Returns the estimate of dynamically allocated memory in bytes.
size_t EstimateMemoryUsage() const;
private:
friend class ProcessorEntityTest;
// The constructor swaps the data from the passed metadata.
ProcessorEntity(const std::string& storage_key,
sync_pb::EntityMetadata metadata);
// Check whether |specifics| matches the stored specifics_hash.
bool MatchesSpecificsHash(const sync_pb::EntitySpecifics& specifics) const;
// Update hash string for EntitySpecifics in the metadata.
void UpdateSpecificsHash(const sync_pb::EntitySpecifics& specifics);
// Storage key. Should always be available.
std::string storage_key_;
// Serializable Sync metadata.
sync_pb::EntityMetadata metadata_;
// Sync data that exists for items being committed only. The data is moved
// away when sending the commit request.
std::unique_ptr<EntityData> commit_data_;
// The sequence number of the last item sent to the sync thread.
int64_t commit_requested_sequence_number_;
// The time when this entity transition from being synced to being unsynced
// (i.e. a local change happened).
base::Time unsynced_time_;
std::map<int64_t, base::Time> unsynced_time_per_committed_server_version_;
};
} // namespace syncer
#endif // COMPONENTS_SYNC_MODEL_IMPL_PROCESSOR_ENTITY_H_