diff options
author | Abseil Team <absl-team@google.com> | 2021-01-21 12:04:50 -0800 |
---|---|---|
committer | vslashg <gfalcon@google.com> | 2021-01-21 15:32:08 -0500 |
commit | 3a2d6572d06709da32a17f053ca1e3c8e2af90df (patch) | |
tree | 91a3261c35d04c4b2b912e60f1630a3f2b75ad3b /absl/strings/internal | |
parent | 22771d471930ce88e1e75d0ca9dd8c65a7b0f895 (diff) |
Export of internal Abseil changes
--
3b43586da865534cf86401d2cae09c65c60b8474 by Abseil Team <absl-team@google.com>:
Introduce CordRepRingReader class
PiperOrigin-RevId: 353070937
--
0bff6e4bcca34fdd1e6610da5fb3c37fd49b2940 by Abseil Team <absl-team@google.com>:
Fix docstring typo "Exmaple" -> "Example"
PiperOrigin-RevId: 352927688
--
1ef4e0a1100cfa7bc9d9e8f155acf0e469348b56 by Abseil Team <absl-team@google.com>:
Refactor tree initialization of ChunkIterator and CordReader
PiperOrigin-RevId: 352916786
--
919c3eb175b87294184a405785eef4fab520d47e by Abseil Team <absl-team@google.com>:
Disable `preserve_most` when compiling with sanitizers.
PiperOrigin-RevId: 352890630
GitOrigin-RevId: 3b43586da865534cf86401d2cae09c65c60b8474
Change-Id: I8a733494b353af69a46862a4019a7f9b40148f49
Diffstat (limited to 'absl/strings/internal')
-rw-r--r-- | absl/strings/internal/cord_internal.h | 5 | ||||
-rw-r--r-- | absl/strings/internal/cord_rep_ring_reader.h | 114 |
2 files changed, 119 insertions, 0 deletions
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 011b49d3..7a1ef6b1 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -203,10 +203,15 @@ struct CordRep { // platforms; we intentionally allow LLVM to ignore the attribute rather than // attempting to hardcode the list of supported platforms. #if defined(__clang__) && !defined(__i386__) +#if !(defined(ABSL_HAVE_MEMORY_SANITIZER) || \ + defined(ABSL_HAVE_THREAD_SANITIZER) || \ + defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ + defined(UNDEFINED_BEHAVIOR_SANITIZER)) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wattributes" __attribute__((preserve_most)) #pragma clang diagnostic pop +#endif // *_SANITIZER #endif static void Destroy(CordRep* rep); diff --git a/absl/strings/internal/cord_rep_ring_reader.h b/absl/strings/internal/cord_rep_ring_reader.h new file mode 100644 index 00000000..396c0e2c --- /dev/null +++ b/absl/strings/internal/cord_rep_ring_reader.h @@ -0,0 +1,114 @@ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_ + +#include <cassert> +#include <cstddef> +#include <cstdint> + +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_ring.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordRepRingReader provides basic navigation over CordRepRing data. +class CordRepRingReader { + public: + // Returns true if this instance is not empty. + explicit operator bool() const { return ring_ != nullptr; } + + // Returns the ring buffer reference for this instance, or nullptr if empty. + CordRepRing* ring() const { return ring_; } + + // Returns the current node index inside the ring buffer for this instance. + // The returned value is undefined if this instance is empty. + CordRepRing::index_type index() const { return index_; } + + // Returns the length of the referenced ring buffer. + // Requires the current instance to be non empty. + size_t length() const { + assert(ring_); + return ring_->length; + } + + // Returns the end offset of the last navigated-to chunk, which represents the + // total bytes 'consumed' relative to the start of the ring. The returned + // value is never zero. For example, initializing a reader with a ring buffer + // with a first chunk of 19 bytes will return consumed() = 19. + // Requires the current instance to be non empty. + size_t consumed() const { + assert(ring_); + return ring_->entry_end_offset(index_); + } + + // Returns the number of bytes remaining beyond the last navigated-to chunk. + // Requires the current instance to be non empty. + size_t remaining() const { + assert(ring_); + return length() - consumed(); + } + + // Resets this instance to an empty value + void Reset() { ring_ = nullptr; } + + // Resets this instance to the start of `ring`. `ring` must not be null. + // Returns a reference into the first chunk of the provided ring. + absl::string_view Reset(CordRepRing* ring) { + assert(ring); + ring_ = ring; + index_ = ring_->head(); + return ring_->entry_data(index_); + } + + // Navigates to the next chunk inside the reference ring buffer. + // Returns a reference into the navigated-to chunk. + // Requires remaining() to be non zero. + absl::string_view Next() { + assert(remaining()); + index_ = ring_->advance(index_); + return ring_->entry_data(index_); + } + + // Navigates to the chunk at offset `offset`. + // Returns a reference into the navigated-to chunk, adjusted for the relative + // position of `offset` into that chunk. For example, calling Seek(13) on a + // ring buffer containing 2 chunks of 10 and 20 bytes respectively will return + // a string view into the second chunk starting at offset 3 with a size of 17. + // Requires `offset` to be less than `length()` + absl::string_view Seek(size_t offset) { + assert(offset < length()); + size_t current = ring_->entry_end_offset(index_); + CordRepRing::index_type hint = (offset >= current) ? index_ : ring_->head(); + const CordRepRing::Position head = ring_->Find(hint, offset); + index_ = head.index; + auto data = ring_->entry_data(head.index); + data.remove_prefix(head.offset); + return data; + } + + private: + CordRepRing* ring_ = nullptr; + CordRepRing::index_type index_; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_ |