| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_SYNC_MODEL_PROCESSOR_ENTITY_H_ |
| #define COMPONENTS_SYNC_MODEL_PROCESSOR_ENTITY_H_ |
| |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <utility> |
| |
| #include "base/time/time.h" |
| #include "components/sync/base/deletion_origin.h" |
| #include "components/sync/protocol/entity_metadata.pb.h" |
| |
| namespace sync_pb { |
| class EntitySpecifics; |
| class UniquePosition; |
| } // namespace sync_pb |
| |
| namespace syncer { |
| |
| class ClientTagHash; |
| struct EntityData; |
| struct CommitRequestData; |
| struct CommitResponseData; |
| struct UpdateResponseData; |
| |
| // This class is used by the ClientTagBasedDataTypeProcessor 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 either a new locally-created item, or a |
| // newly-received remote item. |
| static std::unique_ptr<ProcessorEntity> CreateNew( |
| const std::string& storage_key, |
| const ClientTagHash& client_tag_hash, |
| const std::string& server_id, |
| base::Time creation_time); |
| |
| // Construct an instance representing an item loaded from storage on init. May |
| // return nullptr if the passed-in `metadata` is invalid. |
| 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_; } |
| |
| // 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 it is up to date with the server (i.e. is *not* |
| // unsynced). |
| bool CanClearMetadata() const; |
| |
| // Returns true if the specified `update_version` is already known, i.e. is |
| // smaller or equal to the last known server version. |
| // This is the case for reflections, but can also be true in some other edge |
| // cases (e.g. updates were received out of order). |
| bool IsVersionAlreadyKnown(int64_t update_version) const; |
| |
| // Records that an update from the server was received but ignores its data. |
| void RecordIgnoredRemoteUpdate(const UpdateResponseData& response_data); |
| |
| // Records an update from the server assuming its data is the new data for |
| // this entity. |
| void RecordAcceptedRemoteUpdate( |
| const UpdateResponseData& response_data, |
| sync_pb::EntitySpecifics trimmed_specifics, |
| std::optional<sync_pb::UniquePosition> unique_position); |
| |
| // Squashes a pending commit with an update from the server. |
| void RecordForcedRemoteUpdate( |
| const UpdateResponseData& response_data, |
| sync_pb::EntitySpecifics trimmed_specifics, |
| std::optional<sync_pb::UniquePosition> unique_position); |
| |
| // Applies a local change to this item. |
| void RecordLocalUpdate( |
| std::unique_ptr<EntityData> data, |
| sync_pb::EntitySpecifics trimmed_specifics, |
| std::optional<sync_pb::UniquePosition> unique_position); |
| |
| // Applies a local deletion to this item. Returns true if entity was |
| // previously committed to server and tombstone should be sent. |
| bool RecordLocalDeletion(const DeletionOrigin& origin); |
| |
| // Initializes a message representing this item's uncommitted state |
| // and assumes that it is forwarded to the sync engine for committing. |
| 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); |
| |
| // Clears any in-memory sync state associated with outstanding commits. |
| void ClearTransientSyncState(); |
| |
| // Updates `storage_key_`. Allows setting storage key for datatypes that don't |
| // generate storage keys from syncer::EntityData. Should only be called for |
| // an entity initialized with empty storage key, or for which the storage key |
| // was explicitly cleared. |
| 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); |
| |
| // 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; |
| |
| const EntityData& GetCommitDataForTesting() { return *commit_data_; } |
| |
| private: |
| 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; |
| |
| // Updates hash string for EntitySpecifics in the metadata. |
| void UpdateSpecificsHash(const sync_pb::EntitySpecifics& specifics); |
| |
| // Storage key. |
| 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_; |
| }; |
| |
| } // namespace syncer |
| |
| #endif // COMPONENTS_SYNC_MODEL_PROCESSOR_ENTITY_H_ |