1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
// 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_
|