1193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier/*
2193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * Copyright (C) 2013 The Android Open Source Project
3193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier *
4193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
5193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * you may not use this file except in compliance with the License.
6193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * You may obtain a copy of the License at
7193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier *
8193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
9193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier *
10193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * Unless required by applicable law or agreed to in writing, software
11193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
12193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * See the License for the specific language governing permissions and
14193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier * limitations under the License.
15193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier */
16193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
17193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#include "dedupe_set.h"
18e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe
19e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe#include <algorithm>
20e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe#include <cstdio>
2135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include <vector>
22e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe
23d9c90373d640a5e08072cf469c372e24a8c0fc35David Brazdil#include "base/array_ref.h"
2435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "dedupe_set-inl.h"
25ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom#include "gtest/gtest.h"
26b486a98aadc95d80548953410cf23edba62259faAndreas Gampe#include "thread-current-inl.h"
27193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
28193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartiernamespace art {
29193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
3035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoclass DedupeSetTestHashFunc {
31193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier public:
3235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  size_t operator()(const ArrayRef<const uint8_t>& array) const {
33193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    size_t hash = 0;
34193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    for (uint8_t c : array) {
35193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      hash += c;
36193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      hash += hash << 10;
37193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      hash += hash >> 6;
38193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    }
39193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    return hash;
40193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  }
41193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier};
4235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
4335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoclass DedupeSetTestAlloc {
4435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko public:
4535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  const std::vector<uint8_t>* Copy(const ArrayRef<const uint8_t>& src) {
4635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    return new std::vector<uint8_t>(src.begin(), src.end());
4735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
4835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
4935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  void Destroy(const std::vector<uint8_t>* key) {
5035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    delete key;
5135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
5235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko};
5335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
54413e89f277ec6ba1bdf2040f5b5611f29a27a447Brian CarlstromTEST(DedupeSetTest, Test) {
55193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  Thread* self = Thread::Current();
5635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  DedupeSetTestAlloc alloc;
5735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  DedupeSet<ArrayRef<const uint8_t>,
5835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko            std::vector<uint8_t>,
5935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko            DedupeSetTestAlloc,
6035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko            size_t,
6135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko            DedupeSetTestHashFunc> deduplicator("test", alloc);
6235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  const std::vector<uint8_t>* array1;
63193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  {
6435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    uint8_t raw_test1[] = { 10u, 20u, 30u, 45u };
6535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ArrayRef<const uint8_t> test1(raw_test1);
66193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    array1 = deduplicator.Add(self, test1);
67e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe    ASSERT_NE(array1, nullptr);
68e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe    ASSERT_TRUE(std::equal(test1.begin(), test1.end(), array1->begin()));
69193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  }
70193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
7135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  const std::vector<uint8_t>* array2;
72193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  {
7335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    uint8_t raw_test2[] = { 10u, 20u, 30u, 45u };
7435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ArrayRef<const uint8_t> test2(raw_test2);
7535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    array2 = deduplicator.Add(self, test2);
76193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    ASSERT_EQ(array2, array1);
7735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ASSERT_TRUE(std::equal(test2.begin(), test2.end(), array2->begin()));
78193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  }
79193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
8035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  const std::vector<uint8_t>* array3;
81193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  {
8235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    uint8_t raw_test3[] = { 10u, 22u, 30u, 47u };
8335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ArrayRef<const uint8_t> test3(raw_test3);
8435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    array3 = deduplicator.Add(self, test3);
85e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe    ASSERT_NE(array3, nullptr);
8635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ASSERT_NE(array3, array1);
8735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ASSERT_TRUE(std::equal(test3.begin(), test3.end(), array3->begin()));
88193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  }
89193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
90193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
91193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}  // namespace art
92