blob: 7fb21b76e2205812af10759ab474745a3e7d8c5d [file] [log] [blame]
David Srbecky04b05262015-11-09 18:05:48 +00001/*
2 * Copyright (C) 2015 The Android Open Source Project
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 ART_COMPILER_DWARF_DEDUP_VECTOR_H_
18#define ART_COMPILER_DWARF_DEDUP_VECTOR_H_
19
20#include <vector>
21#include <unordered_map>
22
23namespace art {
24namespace dwarf {
25 class DedupVector {
26 public:
27 // Returns an offset to previously inserted identical block of data,
28 // or appends the data at the end of the vector and returns offset to it.
29 size_t Insert(const uint8_t* ptr, size_t num_bytes) {
30 // See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
31 uint32_t hash = 2166136261u;
32 for (size_t i = 0; i < num_bytes; i++) {
33 hash = (hash ^ ptr[i]) * 16777619u;
34 }
35 // Try to find existing copy of the data.
36 const auto& range = hash_to_offset_.equal_range(hash);
37 for (auto it = range.first; it != range.second; ++it) {
38 const size_t offset = it->second;
39 if (offset + num_bytes <= vector_.size() &&
40 memcmp(vector_.data() + offset, ptr, num_bytes) == 0) {
41 return offset;
42 }
43 }
44 // Append the data at the end of the vector.
45 const size_t new_offset = vector_.size();
46 hash_to_offset_.emplace(hash, new_offset);
47 vector_.insert(vector_.end(), ptr, ptr + num_bytes);
48 return new_offset;
49 }
50
51 const std::vector<uint8_t>& Data() const { return vector_; }
52
53 private:
54 struct IdentityHash {
55 size_t operator()(uint32_t v) const { return v; }
56 };
57
58 // We store the full hash as the key to simplify growing of the table.
59 // It avoids storing or referencing the actual data in the hash-table.
60 std::unordered_multimap<uint32_t, size_t, IdentityHash> hash_to_offset_;
61
62 std::vector<uint8_t> vector_;
63 };
64} // namespace dwarf
65} // namespace art
66
67#endif // ART_COMPILER_DWARF_DEDUP_VECTOR_H_