diff options
Diffstat (limited to 'include/llvm/Support/BinaryItemStream.h')
| -rw-r--r-- | include/llvm/Support/BinaryItemStream.h | 39 | 
1 files changed, 26 insertions, 13 deletions
| diff --git a/include/llvm/Support/BinaryItemStream.h b/include/llvm/Support/BinaryItemStream.h index f4b319217819e..fe7e6caeaafb7 100644 --- a/include/llvm/Support/BinaryItemStream.h +++ b/include/llvm/Support/BinaryItemStream.h @@ -62,32 +62,45 @@ public:      return Error::success();    } -  void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; } +  void setItems(ArrayRef<T> ItemArray) { +    Items = ItemArray; +    computeItemOffsets(); +  }    uint32_t getLength() override { -    uint32_t Size = 0; -    for (const auto &Item : Items) -      Size += Traits::length(Item); -    return Size; +    return ItemEndOffsets.empty() ? 0 : ItemEndOffsets.back();    }  private: -  Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const { +  void computeItemOffsets() { +    ItemEndOffsets.clear(); +    ItemEndOffsets.reserve(Items.size());      uint32_t CurrentOffset = 0; -    uint32_t CurrentIndex = 0;      for (const auto &Item : Items) { -      if (CurrentOffset >= Offset) -        break; -      CurrentOffset += Traits::length(Item); -      ++CurrentIndex; +      uint32_t Len = Traits::length(Item); +      assert(Len > 0 && "no empty items"); +      CurrentOffset += Len; +      ItemEndOffsets.push_back(CurrentOffset);      } -    if (CurrentOffset != Offset) +  } + +  Expected<uint32_t> translateOffsetIndex(uint32_t Offset) { +    // Make sure the offset is somewhere in our items array. +    if (Offset >= getLength())        return make_error<BinaryStreamError>(stream_error_code::stream_too_short); -    return CurrentIndex; +    ++Offset; +    auto Iter = +        std::lower_bound(ItemEndOffsets.begin(), ItemEndOffsets.end(), Offset); +    size_t Idx = std::distance(ItemEndOffsets.begin(), Iter); +    assert(Idx < Items.size() && "binary search for offset failed"); +    return Idx;    }    llvm::support::endianness Endian;    ArrayRef<T> Items; + +  // Sorted vector of offsets to accelerate lookup. +  std::vector<uint32_t> ItemEndOffsets;  };  } // end namespace llvm | 
