cord_rep_btree_reader.h
Go to the documentation of this file.
1 // Copyright 2021 The Abseil Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
16 #define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
17 
18 #include <cassert>
19 
20 #include "absl/base/config.h"
22 #include "absl/strings/internal/cord_internal.h"
25 #include "absl/strings/internal/cord_rep_flat.h"
26 
27 namespace absl {
29 namespace cord_internal {
30 
31 // CordRepBtreeReader implements logic to iterate over cord btrees.
32 // References to the underlying data are returned as absl::string_view values.
33 // The most typical use case is a forward only iteration over tree data.
34 // The class also provides `Skip()`, `Seek()` and `Read()` methods similar to
35 // CordRepBtreeNavigator that allow more advanced navigation.
36 //
37 // Example: iterate over all data inside a cord btree:
38 //
39 // CordRepBtreeReader reader;
40 // for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) {
41 // DoSomethingWithDataIn(sv);
42 // }
43 //
44 // All navigation methods always return the next 'chunk' of data. The class
45 // assumes that all data is directly 'consumed' by the caller. For example:
46 // invoking `Skip()` will skip the desired number of bytes, and directly
47 // read and return the next chunk of data directly after the skipped bytes.
48 //
49 // Example: iterate over all data inside a btree skipping the first 100 bytes:
50 //
51 // CordRepBtreeReader reader;
52 // absl::string_view sv = reader.Init(tree);
53 // if (sv.length() > 100) {
54 // sv.RemovePrefix(100);
55 // } else {
56 // sv = reader.Skip(100 - sv.length());
57 // }
58 // while (!sv.empty()) {
59 // DoSomethingWithDataIn(sv);
60 // absl::string_view sv = reader.Next();
61 // }
62 //
63 // It is important to notice that `remaining` is based on the end position of
64 // the last data edge returned to the caller, not the cumulative data returned
65 // to the caller which can be less in cases of skipping or seeking over data.
66 //
67 // For example, consider a cord btree with five data edges: "abc", "def", "ghi",
68 // "jkl" and "mno":
69 //
70 // absl::string_view sv;
71 // CordRepBtreeReader reader;
72 //
73 // sv = reader.Init(tree); // sv = "abc", remaining = 12
74 // sv = reader.Skip(4); // sv = "hi", remaining = 6
75 // sv = reader.Skip(2); // sv = "l", remaining = 3
76 // sv = reader.Next(); // sv = "mno", remaining = 0
77 // sv = reader.Seek(1); // sv = "bc", remaining = 12
78 //
80  public:
83 
84  // Returns true if this instance is not empty.
85  explicit operator bool() const { return navigator_.btree() != nullptr; }
86 
87  // Returns the tree referenced by this instance or nullptr if empty.
88  CordRepBtree* btree() const { return navigator_.btree(); }
89 
90  // Returns the current data edge inside the referenced btree.
91  // Requires that the current instance is not empty.
92  CordRep* node() const { return navigator_.Current(); }
93 
94  // Returns the length of the referenced tree.
95  // Requires that the current instance is not empty.
96  size_t length() const;
97 
98  // Returns the number of remaining bytes available for iteration, which is the
99  // number of bytes directly following the end of the last chunk returned.
100  // This value will be zero if we iterated over the last edge in the bound
101  // tree, in which case any call to Next() or Skip() will return an empty
102  // string_view reflecting the EOF state.
103  // Note that a call to `Seek()` resets `remaining` to a value based on the
104  // end position of the chunk returned by that call.
105  size_t remaining() const { return remaining_; }
106 
107  // Resets this instance to an empty value.
108  void Reset() { navigator_.Reset(); }
109 
110  // Initializes this instance with `tree`. `tree` must not be null.
111  // Returns a reference to the first data edge of the provided tree.
113 
114  // Navigates to and returns the next data edge of the referenced tree.
115  // Returns an empty string_view if an attempt is made to read beyond the end
116  // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition.
117  // Requires that the current instance is not empty.
119 
120  // Skips the provided amount of bytes and returns a reference to the data
121  // directly following the skipped bytes.
122  absl::string_view Skip(size_t skip);
123 
124  // Reads `n` bytes into `tree`.
125  // If `chunk_size` is zero, starts reading at the next data edge. If
126  // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of
127  // the last returned data edge. Effectively, this means that the read starts
128  // at offset `consumed() - chunk_size`.
129  // Requires that `chunk_size` is less than or equal to the length of the
130  // last returned data edge. The purpose of `chunk_size` is to simplify code
131  // partially consuming a returned chunk and wanting to include the remaining
132  // bytes in the Read call. For example, the below code will read 1000 bytes of
133  // data into a cord tree if the first chunk starts with "big:":
134  //
135  // CordRepBtreeReader reader;
136  // absl::string_view sv = reader.Init(tree);
137  // if (absl::StartsWith(sv, "big:")) {
138  // CordRepBtree tree;
139  // sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree);
140  // }
141  //
142  // This method will return an empty string view if all remaining data was
143  // read. If `n` exceeded the amount of remaining data this function will
144  // return an empty string view and `tree` will be set to nullptr.
145  // In both cases, `consumed` will be set to `length`.
146  absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree);
147 
148  // Navigates to the chunk at offset `offset`.
149  // Returns a reference into the navigated to chunk, adjusted for the relative
150  // position of `offset` into that chunk. For example, calling `Seek(13)` on a
151  // cord tree containing 2 chunks of 10 and 20 bytes respectively will return
152  // a string view into the second chunk starting at offset 3 with a size of 17.
153  // Returns an empty string view if `offset` is equal to or greater than the
154  // length of the referenced tree.
155  absl::string_view Seek(size_t offset);
156 
157  private:
158  size_t remaining_ = 0;
160 };
161 
162 inline size_t CordRepBtreeReader::length() const {
163  assert(btree() != nullptr);
164  return btree()->length;
165 }
166 
168  assert(tree != nullptr);
169  const CordRep* edge = navigator_.InitFirst(tree);
170  remaining_ = tree->length - edge->length;
171  return EdgeData(edge);
172 }
173 
175  if (remaining_ == 0) return {};
176  const CordRep* edge = navigator_.Next();
177  assert(edge != nullptr);
178  remaining_ -= edge->length;
179  return EdgeData(edge);
180 }
181 
183  // As we are always positioned on the last 'consumed' edge, we
184  // need to skip the current edge as well as `skip`.
185  const size_t edge_length = navigator_.Current()->length;
187  if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) {
188  remaining_ = 0;
189  return {};
190  }
191  // The combined length of all edges skipped before `pos.edge` is `skip -
192  // pos.offset`, all of which are 'consumed', as well as the current edge.
193  remaining_ -= skip - pos.offset + pos.edge->length;
194  return EdgeData(pos.edge).substr(pos.offset);
195 }
196 
199  if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) {
200  remaining_ = 0;
201  return {};
202  }
203  absl::string_view chunk = EdgeData(pos.edge).substr(pos.offset);
204  remaining_ = length() - offset - chunk.length();
205  return chunk;
206 }
207 
208 } // namespace cord_internal
210 } // namespace absl
211 
212 #endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
ABSL_PREDICT_FALSE
#define ABSL_PREDICT_FALSE(x)
Definition: abseil-cpp/absl/base/optimization.h:180
absl::cord_internal::CordRepBtreeReader::Init
absl::string_view Init(CordRepBtree *tree)
Definition: cord_rep_btree_reader.h:167
absl::cord_internal::CordRepBtreeReader::Reset
void Reset()
Definition: cord_rep_btree_reader.h:108
cord_data_edge.h
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
bool
bool
Definition: setup_once.h:312
absl::cord_internal::EdgeData
absl::string_view EdgeData(const CordRep *edge)
Definition: cord_data_edge.h:45
mkowners.skip
bool skip
Definition: mkowners.py:224
absl::cord_internal::CordRepBtreeReader::Seek
absl::string_view Seek(size_t offset)
Definition: cord_rep_btree_reader.h:197
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
absl::cord_internal::CordRepBtreeReader::Next
absl::string_view Next()
Definition: cord_rep_btree_reader.h:174
absl::cord_internal::CordRepBtreeReader::navigator_
CordRepBtreeNavigator navigator_
Definition: cord_rep_btree_reader.h:159
absl::cord_internal::CordRepBtreeReader::length
size_t length() const
Definition: cord_rep_btree_reader.h:162
absl::cord_internal::CordRepBtreeNavigator::Seek
Position Seek(size_t offset)
Definition: cord_rep_btree_navigator.h:190
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::cord_internal::CordRep
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:209
absl::cord_internal::CordRepBtreeReader
Definition: cord_rep_btree_reader.h:79
absl::string_view::length
constexpr size_type length() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:282
absl::cord_internal::CordRepBtreeNavigator::Current
CordRep * Current() const
Definition: cord_rep_btree_navigator.h:157
absl::cord_internal::CordRepBtreeNavigator
Definition: cord_rep_btree_navigator.h:46
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::cord_internal::CordRepBtreeReader::node
CordRep * node() const
Definition: cord_rep_btree_reader.h:92
absl::cord_internal::CordRepBtreeReader::Skip
absl::string_view Skip(size_t skip)
Definition: cord_rep_btree_reader.h:182
cord_rep_btree.h
absl::cord_internal::CordRepBtreeNavigator::Reset
void Reset()
Definition: cord_rep_btree_navigator.h:162
absl::cord_internal::CordRepBtreeReader::remaining
size_t remaining() const
Definition: cord_rep_btree_reader.h:105
absl::cord_internal::ReadResult
CordRepBtreeNavigator::ReadResult ReadResult
Definition: cord_rep_btree_navigator.cc:27
absl::cord_internal::CordRep::length
size_t length
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:228
absl::cord_internal::CordRepBtreeReader::remaining_
size_t remaining_
Definition: cord_rep_btree_reader.h:158
absl::cord_internal::CordRepBtreeNavigator::InitFirst
CordRep * InitFirst(CordRepBtree *tree)
Definition: cord_rep_btree_navigator.h:164
absl::cord_internal::CordRepBtree
Definition: cord_rep_btree.h:63
absl::cord_internal::CordRepBtreeNavigator::Next
CordRep * Next()
Definition: cord_rep_btree_navigator.h:217
absl::cord_internal::CordRepBtreeReader::btree
CordRepBtree * btree() const
Definition: cord_rep_btree_reader.h:88
absl::cord_internal::CordRepBtreeNavigator::btree
CordRepBtree * btree() const
Definition: cord_rep_btree_navigator.h:153
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::cord_internal::CordRepBtreeNavigator::Position
Definition: cord_rep_btree_navigator.h:51
cord_rep_btree_navigator.h
absl::cord_internal::CordRepBtreeReader::Read
absl::string_view Read(size_t n, size_t chunk_size, CordRep *&tree)
Definition: cord_rep_btree_reader.cc:30
absl::string_view::substr
constexpr string_view substr(size_type pos=0, size_type n=npos) const
Definition: abseil-cpp/absl/strings/string_view.h:399
absl::cord_internal::CordRepBtreeNavigator::Skip
Position Skip(size_t n)
Definition: cord_rep_btree_navigator.cc:68
absl::cord_internal::CordRepBtreeNavigator::ReadResult
Definition: cord_rep_btree_navigator.h:61
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:56