Skip to content

Commit 423cab7

Browse files
authored
Add a Sizer abstraction to MemoryPersistence (#3692)
This breaks the link between MemoryPersistence-related classes and FSTLocalSerializer, making it possible to use these in straight C++.
1 parent 58256d2 commit 423cab7

File tree

9 files changed

+194
-30
lines changed

9 files changed

+194
-30
lines changed

Firestore/Source/Local/FSTMemoryPersistence.mm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h"
3030
#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h"
3131
#include "Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h"
32+
#include "Firestore/core/src/firebase/firestore/local/proto_sizer.h"
3233
#include "Firestore/core/src/firebase/firestore/local/reference_set.h"
3334
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
3435
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
@@ -43,6 +44,7 @@
4344
using firebase::firestore::local::MemoryMutationQueue;
4445
using firebase::firestore::local::MemoryQueryCache;
4546
using firebase::firestore::local::MemoryRemoteDocumentCache;
47+
using firebase::firestore::local::ProtoSizer;
4648
using firebase::firestore::local::QueryData;
4749
using firebase::firestore::local::ReferenceSet;
4850
using firebase::firestore::local::TargetCallback;
@@ -325,8 +327,9 @@ - (size_t)byteSize {
325327
// used for testing. The algorithm here (loop through everything, serialize it
326328
// and count bytes) is inefficient and inexact, but won't run in production.
327329
size_t count = 0;
328-
count += _persistence.queryCache->CalculateByteSize(_serializer);
329-
count += _persistence.remoteDocumentCache->CalculateByteSize(_serializer);
330+
ProtoSizer sizer(_serializer);
331+
count += _persistence.queryCache->CalculateByteSize(sizer);
332+
count += _persistence.remoteDocumentCache->CalculateByteSize(sizer);
330333
const MutationQueues &queues = [_persistence mutationQueues];
331334
for (const auto &entry : queues) {
332335
count += entry.second->CalculateByteSize(_serializer);

Firestore/core/src/firebase/firestore/local/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ cc_library(
7575
reference_set.cc
7676
reference_set.h
7777
remote_document_cache.h
78+
sizer.h
7879
DEPENDS
7980
# TODO(b/111328563) Force nanopb first to work around ODR violations
8081
protobuf-nanopb-static

Firestore/core/src/firebase/firestore/local/memory_query_cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ namespace firebase {
4343
namespace firestore {
4444
namespace local {
4545

46+
class Sizer;
47+
4648
class MemoryQueryCache : public QueryCache {
4749
public:
4850
explicit MemoryQueryCache(FSTMemoryPersistence* persistence);
@@ -74,7 +76,7 @@ class MemoryQueryCache : public QueryCache {
7476
bool Contains(const model::DocumentKey& key) override;
7577

7678
// Other methods and accessors
77-
size_t CalculateByteSize(FSTLocalSerializer* serializer);
79+
size_t CalculateByteSize(const Sizer& sizer);
7880

7981
size_t size() const override {
8082
return queries_.size();

Firestore/core/src/firebase/firestore/local/memory_query_cache.mm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@
1616

1717
#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h"
1818

19-
#import <Protobuf/GPBMessage.h>
20-
2119
#include <vector>
2220

23-
#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h"
2421
#import "Firestore/Source/Local/FSTMemoryPersistence.h"
2522

2623
#include "Firestore/core/src/firebase/firestore/local/query_data.h"
24+
#include "Firestore/core/src/firebase/firestore/local/sizer.h"
2725
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
2826

2927
NS_ASSUME_NONNULL_BEGIN
@@ -124,11 +122,10 @@
124122
return references_.ContainsKey(key);
125123
}
126124

127-
size_t MemoryQueryCache::CalculateByteSize(FSTLocalSerializer* serializer) {
125+
size_t MemoryQueryCache::CalculateByteSize(const Sizer& sizer) {
128126
size_t count = 0;
129127
for (const auto& kv : queries_) {
130-
const QueryData& query_data = kv.second;
131-
count += [[serializer encodedQueryData:query_data] serializedSize];
128+
count += sizer.CalculateByteSize(kv.second);
132129
}
133130
return count;
134131
}

Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ namespace firebase {
3939
namespace firestore {
4040
namespace local {
4141

42+
class Sizer;
43+
4244
class MemoryRemoteDocumentCache : public RemoteDocumentCache {
4345
public:
4446
explicit MemoryRemoteDocumentCache(FSTMemoryPersistence* persistence);
@@ -56,7 +58,7 @@ class MemoryRemoteDocumentCache : public RemoteDocumentCache {
5658
FSTMemoryLRUReferenceDelegate* reference_delegate,
5759
model::ListenSequenceNumber upper_bound);
5860

59-
size_t CalculateByteSize(FSTLocalSerializer* serializer);
61+
size_t CalculateByteSize(const Sizer& sizer);
6062

6163
private:
6264
/** Underlying cache of documents. */

Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.mm

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818

1919
#include <utility>
2020

21-
#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h"
2221
#import "Firestore/Source/Local/FSTMemoryPersistence.h"
2322

23+
#include "Firestore/core/src/firebase/firestore/local/sizer.h"
2424
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
2525

2626
namespace firebase {
2727
namespace firestore {
2828
namespace local {
29-
namespace {
3029

3130
using core::Query;
3231
using model::Document;
@@ -38,20 +37,6 @@
3837
using model::MaybeDocumentMap;
3938
using model::OptionalMaybeDocumentMap;
4039

41-
/**
42-
* Returns an estimate of the number of bytes used to store the given
43-
* document key in memory. This is only an estimate and includes the size
44-
* of the segments of the path, but not any object overhead or path separators.
45-
*/
46-
size_t DocumentKeyByteSize(const DocumentKey& key) {
47-
size_t count = 0;
48-
for (const auto& segment : key.path()) {
49-
count += segment.size();
50-
}
51-
return count;
52-
}
53-
} // namespace
54-
5540
MemoryRemoteDocumentCache::MemoryRemoteDocumentCache(
5641
FSTMemoryPersistence* persistence) {
5742
persistence_ = persistence;
@@ -130,12 +115,10 @@ size_t DocumentKeyByteSize(const DocumentKey& key) {
130115
return removed;
131116
}
132117

133-
size_t MemoryRemoteDocumentCache::CalculateByteSize(
134-
FSTLocalSerializer* serializer) {
118+
size_t MemoryRemoteDocumentCache::CalculateByteSize(const Sizer& sizer) {
135119
size_t count = 0;
136120
for (const auto& kv : docs_) {
137-
count += DocumentKeyByteSize(kv.first);
138-
count += [[serializer encodedMaybeDocument:kv.second] serializedSize];
121+
count += sizer.CalculateByteSize(kv.second);
139122
}
140123
return count;
141124
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_PROTO_SIZER_H_
18+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_PROTO_SIZER_H_
19+
20+
#if !defined(__OBJC__)
21+
#error "This header only supports Objective-C++"
22+
#endif // !defined(__OBJC__)
23+
24+
#include "Firestore/core/src/firebase/firestore/local/sizer.h"
25+
26+
@class FSTLocalSerializer;
27+
28+
namespace firebase {
29+
namespace firestore {
30+
namespace local {
31+
32+
/**
33+
* Estimates the stored size of documents and queries by translating to protos
34+
* and using the serialized sizes to estimate.
35+
*/
36+
class ProtoSizer : public Sizer {
37+
public:
38+
explicit ProtoSizer(FSTLocalSerializer* serializer);
39+
40+
size_t CalculateByteSize(
41+
const model::MaybeDocument& maybe_doc) const override;
42+
43+
size_t CalculateByteSize(const QueryData& query_data) const override;
44+
45+
private:
46+
FSTLocalSerializer* serializer_;
47+
};
48+
49+
} // namespace local
50+
} // namespace firestore
51+
} // namespace firebase
52+
53+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_PROTO_SIZER_H_
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "Firestore/core/src/firebase/firestore/local/proto_sizer.h"
18+
19+
#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h"
20+
#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h"
21+
#import "Firestore/Source/Local/FSTLocalSerializer.h"
22+
23+
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
24+
#include "Firestore/core/src/firebase/firestore/model/maybe_document.h"
25+
26+
namespace firebase {
27+
namespace firestore {
28+
namespace local {
29+
namespace {
30+
31+
using model::DocumentKey;
32+
using model::MaybeDocument;
33+
34+
/**
35+
* Returns an estimate of the number of bytes used to store the given document
36+
* key in memory. This is only an estimate and includes the size of the segments
37+
* of the path, but not any object overhead or path separators.
38+
*/
39+
size_t DocumentKeyByteSize(const DocumentKey& key) {
40+
size_t count = 0;
41+
for (const auto& segment : key.path()) {
42+
count += segment.size();
43+
}
44+
return count;
45+
}
46+
47+
} // namespace
48+
49+
ProtoSizer::ProtoSizer(FSTLocalSerializer* serializer)
50+
: serializer_(serializer) {
51+
}
52+
53+
size_t ProtoSizer::CalculateByteSize(const MaybeDocument& maybe_doc) const {
54+
size_t count = DocumentKeyByteSize(maybe_doc.key());
55+
count += [[serializer_ encodedMaybeDocument:maybe_doc] serializedSize];
56+
return count;
57+
}
58+
59+
size_t ProtoSizer::CalculateByteSize(const QueryData& query_data) const {
60+
return [[serializer_ encodedQueryData:query_data] serializedSize];
61+
}
62+
63+
} // namespace local
64+
} // namespace firestore
65+
} // namespace firebase
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_SIZER_H_
18+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_SIZER_H_
19+
20+
#include <cstddef>
21+
22+
namespace firebase {
23+
namespace firestore {
24+
namespace model {
25+
26+
class MaybeDocument;
27+
28+
} // namespace model
29+
30+
namespace local {
31+
32+
class QueryData;
33+
34+
/**
35+
* Estimates the stored size of documents and queries.
36+
*/
37+
class Sizer {
38+
public:
39+
virtual ~Sizer() = default;
40+
41+
/**
42+
* Calculates the size of the given maybe_doc in bytes. Note that even
43+
* NoDocuments have an associated size.
44+
*/
45+
virtual size_t CalculateByteSize(
46+
const model::MaybeDocument& maybe_doc) const = 0;
47+
48+
/**
49+
* Calculates the size of the given query_data in bytes.
50+
*/
51+
virtual size_t CalculateByteSize(const QueryData& query_data) const = 0;
52+
};
53+
54+
} // namespace local
55+
} // namespace firestore
56+
} // namespace firebase
57+
58+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_SIZER_H_

0 commit comments

Comments
 (0)