1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright 2007 Google Inc.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Author: Lincoln Smith
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Licensed under the Apache License, Version 2.0 (the "License");
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// you may not use this file except in compliance with the License.
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// You may obtain a copy of the License at
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//      http://www.apache.org/licenses/LICENSE-2.0
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Unless required by applicable law or agreed to in writing, software
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// distributed under the License is distributed on an "AS IS" BASIS,
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// See the License for the specific language governing permissions and
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// limitations under the License.
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <config.h>
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "addrcache.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <limits.h>  // INT_MAX, INT_MIN
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdint.h>  // uint32_t
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h>  // rand, srand
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <iostream>
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector>
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing.h"
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "varint_bigendian.h"
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "vcdiff_defs.h"  // RESULT_ERROR
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace open_vcdiff {
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Provides an address_stream_ buffer and functions to manually encode
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// values into the buffer, and to manually decode and verify test results
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// from the buffer.
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass VCDiffAddressCacheTest : public testing::Test {
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  typedef std::string string;
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCacheTest() : decode_position_(NULL),
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             decode_position_end_(NULL),
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             verify_encode_position_(NULL),
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             last_encode_size_(0),
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             last_decode_position_(NULL) { }
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~VCDiffAddressCacheTest() { }
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void SetUp() {
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_TRUE(cache_.Init());
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Benchmarks for timing encode/decode operations
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void BM_Setup(int test_size);
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void BM_CacheEncode(int iterations, int test_size);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void BM_CacheDecode(int iterations, int test_size);
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void TestBody() { }  // to allow instantiation of this class
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void BeginDecode() {
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    decode_position_ = address_stream_.data();
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_TRUE(decode_position_ != NULL);
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    last_decode_position_ = decode_position_;
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    decode_position_end_ = decode_position_ + address_stream_.size();
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ExpectEncodedSizeInBytes(int n) {
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(last_encode_size_ + n, address_stream_.size());
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    last_encode_size_ = address_stream_.size();
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ExpectDecodedSizeInBytes(int n) {
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(last_decode_position_ + n, decode_position_);
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    last_decode_position_ = decode_position_;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ManualEncodeVarint(VCDAddress value) {
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    VarintBE<VCDAddress>::AppendToString(value, &address_stream_);
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ManualEncodeByte(unsigned char byte) {
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    address_stream_.push_back(byte);
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ExpectEncodedVarint(VCDAddress expected_value, int expected_size) {
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!verify_encode_position_) {
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      verify_encode_position_ = address_stream_.data();
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(expected_size, VarintBE<VCDAddress>::Length(expected_value));
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    VCDAddress output_val = VarintBE<VCDAddress>::Parse(
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        address_stream_.data() + address_stream_.size(),
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        &verify_encode_position_);
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(expected_value, output_val);
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ExpectEncodedByte(unsigned char expected_value) {
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!verify_encode_position_) {
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      verify_encode_position_ = address_stream_.data();
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(expected_value, *verify_encode_position_);
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++verify_encode_position_;
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void TestEncode(VCDAddress address,
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  VCDAddress here_address,
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  unsigned char mode,
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  int size) {
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    VCDAddress encoded_addr = 0;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(mode, cache_.EncodeAddress(address, here_address, &encoded_addr));
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (cache_.WriteAddressAsVarintForMode(mode)) {
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ManualEncodeVarint(encoded_addr);
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      EXPECT_GT(256, encoded_addr);
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ManualEncodeByte(static_cast<unsigned char>(encoded_addr));
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ExpectEncodedSizeInBytes(size);
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache cache_;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  string address_stream_;
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* decode_position_;
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* decode_position_end_;
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  string large_address_stream_;
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<unsigned char> mode_stream_;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<VCDAddress> verify_stream_;
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* verify_encode_position_;
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  string::size_type last_encode_size_;
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char*       last_decode_position_;
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef GTEST_HAS_DEATH_TEST
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This synonym is needed for the tests that use ASSERT_DEATH
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef VCDiffAddressCacheTest VCDiffAddressCacheDeathTest;
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // GTEST_HAS_DEATH_TEST
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Having either or both cache size == 0 is acceptable
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, ZeroCacheSizes) {
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache zero_cache(0, 0);
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(zero_cache.Init());
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, NegativeCacheSizes) {
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(-1, -1);   // The constructor must not fail
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(negative_cache.Init());
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, OnlySameCacheSizeIsNegative) {
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(0, -1);   // The constructor must not fail
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(negative_cache.Init());
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, ExtremePositiveCacheSizes) {
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The constructor must not fail
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache int_max_cache(INT_MAX, INT_MAX);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(int_max_cache.Init());
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, ExtremeNegativeCacheSizes) {
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The constructor must not fail
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache int_min_cache(INT_MIN, INT_MIN);
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(int_min_cache.Init());
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// VCD_MAX_MODES is the maximum number of modes, including SAME and HERE modes.
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// So neither the SAME cache nor the HERE cache can be larger than
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (VCD_MAX_MODES - 2).
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, NearCacheSizeIsTooBig) {
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(VCD_MAX_MODES - 1, 0);
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(negative_cache.Init());
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, SameCacheSizeIsTooBig) {
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(0, VCD_MAX_MODES - 1);
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(negative_cache.Init());
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, CombinedSizesAreTooBig) {
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache((VCD_MAX_MODES / 2),
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    (VCD_MAX_MODES / 2) - 1);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(negative_cache.Init());
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, MaxLegalNearCacheSize) {
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(VCD_MAX_MODES - 2, 0);
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(negative_cache.Init());
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, MaxLegalSameCacheSize) {
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache(0, VCD_MAX_MODES - 2);
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(negative_cache.Init());
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, MaxLegalCombinedSizes) {
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache negative_cache((VCD_MAX_MODES / 2) - 1,
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    (VCD_MAX_MODES / 2) - 1);
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(negative_cache.Init());
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DestroyWithoutInitialization) {
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache no_init_cache(4, 3);
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Should be destroyed without crashing
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DestroyDefaultWithoutInitialization) {
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache no_init_cache;
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Should be destroyed without crashing
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, CacheContentsInitiallyZero) {
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress test_address = 0;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that caches are initially set to zero
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (test_address = 0; test_address < 4; ++test_address) {
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0, cache_.NearAddress(test_address));
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (test_address = 0; test_address < 256 * 3; ++test_address) {
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0, cache_.SameAddress(test_address));
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Inserts values 1, 2, ... , 10 into the cache and tests its entire
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// contents for consistency.
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, InsertFirstTen) {
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress test_address = 0;
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (test_address = 1; test_address <= 10; ++test_address) {
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache_.UpdateCache(test_address);
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(9, cache_.NearAddress(0));   // slot 0: 1 => 5 => 9
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(10, cache_.NearAddress(1));  // slot 1: 2 => 6 => 10
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(7, cache_.NearAddress(2));   // slot 2: 3 => 7
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(8, cache_.NearAddress(3));   // slot 3: 4 => 8
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache_.SameAddress(0));
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (test_address = 1; test_address <= 10; ++test_address) {
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(test_address, cache_.SameAddress(test_address));
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (test_address = 11; test_address < 256 * 3; ++test_address) {
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0, cache_.SameAddress(test_address));
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, InsertIntMax) {
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache_.UpdateCache(INT_MAX);
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(INT_MAX, cache_.NearAddress(0));
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(INT_MAX, cache_.SameAddress(INT_MAX % (256 * 3)));
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache_.SameAddress((INT_MAX - 256) % (256 * 3)));
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, cache_.SameAddress((INT_MAX - 512) % (256 * 3)));
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Exercises all four addressing mode types by encoding five values
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// with EncodeAddress.
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Checks to see that the proper mode was selected in each case,
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and that the encoding is correct.
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, EncodeAddressModes) {
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEncode(0x0000FFFF, 0x10000000,  VCD_SELF_MODE, 3);
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEncode(0x10000000, 0x10000010,  VCD_HERE_MODE, 1);
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEncode(0x10000004, 0x10000020,  cache_.FirstNearMode() + 0x01, 1);
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEncode(0x0FFFFFFE, 0x10000030,  VCD_HERE_MODE, 1);
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEncode(0x10000004, 0x10000040,  cache_.FirstSameMode() + 0x01, 1);
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectEncodedVarint(0xFFFF, 3);  // SELF mode: addr 0x0000FFFF
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectEncodedVarint(0x10, 1);    // HERE mode: here - 0x10 = 0x10000000
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectEncodedVarint(0x04, 1);    // NEAR cache #1:
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                   // last addr + 0x4 = 0x10000004
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectEncodedVarint(0x32, 1);    // HERE mode: here - 0x32 = 0x0FFFFFFE
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectEncodedByte(0x04);         // SAME cache #1: 0x10000004 hits
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Exercises all four addressing mode types by manually encoding six values
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and calling DecodeAddress on each one.
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeAddressModes) {
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0x1000);
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeByte(0xFE);   // SAME mode uses a byte, not a Varint
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xFE);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0x1000);
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xCAFE,
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x10000,
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_SELF_MODE,
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x20000 - 0xCAFE,
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x20000,
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_HERE_MODE,
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xDAFE,
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x30000,
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 cache_.FirstNearMode(),
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0x1000));
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xCAFE,
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x40000,
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 cache_.FirstSameMode() + (0xCA % 3),
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(sizeof(unsigned char));  // a byte, not a Varint
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xFE,
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x50000,
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_SELF_MODE,
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xFE));
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NEAR mode #0 has been overwritten by fifth computed addr (wrap around)
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x10FE,
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x60000,
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 cache_.FirstNearMode(),
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0x1000));
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test with both cache sizes == 0.  The encoder should not choose
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a SAME or NEAR mode under these conditions.
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, EncodeAddressZeroCacheSizes) {
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress encoded_addr = 0;
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache zero_cache(0, 0);
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(zero_cache.Init());
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(VCD_SELF_MODE,
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            zero_cache.EncodeAddress(0x0000FFFF, 0x10000000, &encoded_addr));
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xFFFF, encoded_addr);
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(VCD_HERE_MODE,
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            zero_cache.EncodeAddress(0x10000000, 0x10000010, &encoded_addr));
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x10, encoded_addr);
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(VCD_HERE_MODE,
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            zero_cache.EncodeAddress(0x10000004, 0x10000020, &encoded_addr));
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x1C, encoded_addr);
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(VCD_HERE_MODE,
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            zero_cache.EncodeAddress(0x0FFFFFFE, 0x10000030, &encoded_addr));
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x32, encoded_addr);
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(VCD_HERE_MODE,
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            zero_cache.EncodeAddress(0x10000004, 0x10000040, &encoded_addr));
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x3C, encoded_addr);
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeAddressZeroCacheSizes) {
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDiffAddressCache zero_cache(0, 0);
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(zero_cache.Init());
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xDAFE);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xCAFE, zero_cache.DecodeAddress(0x10000,
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             VCD_SELF_MODE,
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             &decode_position_,
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             decode_position_end_));
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0x20000 - 0xCAFE, zero_cache.DecodeAddress(0x20000,
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       VCD_HERE_MODE,
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       &decode_position_,
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                       decode_position_end_));
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xDAFE, zero_cache.DecodeAddress(0x30000,
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             VCD_SELF_MODE,
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             &decode_position_,
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             decode_position_end_));
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xDAFE));
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef GTEST_HAS_DEATH_TEST
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheDeathTest, EncodeNegativeAddress) {
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress dummy_encoded_address = 0;
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(cache_.EncodeAddress(-1, -1, &dummy_encoded_address),
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "negative");
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheDeathTest, EncodeAddressPastHereAddress) {
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress dummy_encoded_address = 0;
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(cache_.EncodeAddress(0x100, 0x100, &dummy_encoded_address),
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "address.*<.*here_address");
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(cache_.EncodeAddress(0x200, 0x100, &dummy_encoded_address),
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "address.*<.*here_address");
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheDeathTest, DecodeInvalidMode) {
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                               cache_.DecodeAddress(0x10000000,
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    cache_.LastMode() + 1,
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    &decode_position_,
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    decode_position_end_)),
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "mode");
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                               cache_.DecodeAddress(0x10000000,
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    0xFF,
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    &decode_position_,
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    decode_position_end_)),
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "mode");
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheDeathTest, DecodeZeroOrNegativeHereAddress) {
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Using a Debug build, the check will fail; using a Release build,
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the check will not occur, and the SELF mode does not depend on
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the value of here_address, so DecodeAddress() will succeed.
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(cache_.DecodeAddress(-1,
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          VCD_SELF_MODE,
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          &decode_position_,
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                          decode_position_end_),
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "negative");
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A zero value for here_address should not kill the decoder,
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // but instead should return an error value.  A delta file may contain
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a window that has no source segment and that (erroneously)
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // uses a COPY instruction as its first instruction.  This should
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // cause an error to be reported, not a debug check failure.
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0,
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_SELF_MODE,
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // GTEST_HAS_DEATH_TEST
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeAddressPastHereAddress) {
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x1000,
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_SELF_MODE,
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, HereModeAddressTooLarge) {
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0x10001);  // here_address + 1
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_HERE_MODE,
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, NearModeAddressOverflow) {
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0x7FFFFFFF);
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xCAFE, cache_.DecodeAddress(0x10000,
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_SELF_MODE,
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now decode a NEAR mode address of base address 0xCAFE
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (the first decoded address) + offset 0x7FFFFFFF.  This will cause
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // an integer overflow and should signal an error.
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000000,
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         cache_.FirstNearMode(),
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A Varint should contain at most 9 bytes that have their continuation bit
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (the uppermost, or 7 bit) set.  A longer string of bytes that all have
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// bit 7 set is not a valid Varint.  Try to parse such a string as a Varint
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and confirm that it does not run off the end of the input buffer and
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// it returns an error value (RESULT_ERROR).
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeInvalidVarint) {
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  address_stream_.clear();
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Write 512 0xFE bytes
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  address_stream_.append(512, static_cast<char>(0xFE));
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000000,
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_SELF_MODE,
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If only part of a Varint appears in the data to be decoded,
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// then DecodeAddress should return RESULT_END_OF_DATA,
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// which means that the Varint *may* be valid if there is more
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// data expected to be returned.
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodePartialVarint) {
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  address_stream_.clear();
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeByte(0xFE);
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeByte(0xFE);
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeByte(0xFE);
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_END_OF_DATA,
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x10000000,
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_SELF_MODE,
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now add the missing last byte (supposedly read from a stream of data)
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and verify that the Varint is now valid.
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeByte(0x01);  // End the Varint with an additional byte
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();  // Reset read position to start of data
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xFDFBF01,
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x10000000,
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_SELF_MODE,
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(4);  // ManualEncodeByte was called for 4 byte values
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef GTEST_HAS_DEATH_TEST
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheDeathTest, DecodeBadMode) {
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                               cache_.DecodeAddress(0x10000,
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    cache_.LastMode() + 1,
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    &decode_position_,
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                    decode_position_end_)),
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     "maximum");
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // GTEST_HAS_DEATH_TEST
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeInvalidHereAddress) {
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0x10001);  // offset larger than here_address
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         VCD_HERE_MODE,
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, DecodeInvalidNearAddress) {
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(0xCAFE);
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ManualEncodeVarint(INT_MAX);  // offset will cause integer overflow
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BeginDecode();
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0xCAFE,
538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            cache_.DecodeAddress(0x10000,
539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 VCD_SELF_MODE,
540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 &decode_position_,
541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 decode_position_end_));
542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         cache_.FirstNearMode(),
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         &decode_position_,
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         decode_position_end_));
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ExpectDecodedSizeInBytes(0);
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VCDiffAddressCacheTest::BM_Setup(int test_size) {
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  mode_stream_.resize(test_size);
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  verify_stream_.resize(test_size);
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress here_address = 1;
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  srand(1);
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < test_size; ++i) {
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    verify_stream_[i] = PortableRandomInRange(here_address - 1);
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    here_address += 4;
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BM_CacheEncode(1, test_size);  // populate large_address_stream_, mode_stream_
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VCDiffAddressCacheTest::BM_CacheEncode(int iterations, int test_size) {
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress here_address = 1;
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress encoded_addr = 0;
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int test_iteration = 0; test_iteration < iterations; ++test_iteration) {
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache_.Init();
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    large_address_stream_.clear();
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    here_address = 1;
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (int i = 0; i < test_size; ++i) {
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const unsigned char mode = cache_.EncodeAddress(verify_stream_[i],
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                      here_address,
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                                      &encoded_addr);
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (cache_.WriteAddressAsVarintForMode(mode)) {
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        VarintBE<VCDAddress>::AppendToString(encoded_addr,
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                             &large_address_stream_);
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      } else {
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        EXPECT_GT(256, encoded_addr);
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        large_address_stream_.push_back(
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            static_cast<unsigned char>(encoded_addr));
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      mode_stream_[i] = mode;
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      here_address += 4;
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VCDiffAddressCacheTest::BM_CacheDecode(int iterations, int test_size) {
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VCDAddress here_address = 1;
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int test_iteration = 0; test_iteration < iterations; ++test_iteration) {
590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache_.Init();
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* large_decode_pointer = large_address_stream_.data();
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* const end_of_encoded_data =
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        large_decode_pointer + large_address_stream_.size();
594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    here_address = 1;
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (int i = 0; i < test_size; ++i) {
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      EXPECT_EQ(verify_stream_[i],
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                cache_.DecodeAddress(here_address,
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                     mode_stream_[i],
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                     &large_decode_pointer,
600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                     end_of_encoded_data));
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      here_address += 4;
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(end_of_encoded_data, large_decode_pointer);
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(VCDiffAddressCacheTest, PerformanceTest) {
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int test_size = 20 * 1024;  // 20K random encode/decode operations
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int num_iterations = 40;  // run test 40 times and take average
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  BM_Setup(test_size);
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CycleTimer encode_timer;
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    encode_timer.Start();
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    BM_CacheEncode(num_iterations, test_size);
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    encode_timer.Stop();
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    double encode_time_in_ms =
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        static_cast<double>(encode_timer.GetInUsec()) / 1000;
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::cout << "Time to encode: "
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              << (encode_time_in_ms / num_iterations) << " ms" << std::endl;
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CycleTimer decode_timer;
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    decode_timer.Start();
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    BM_CacheDecode(num_iterations, test_size);
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    decode_timer.Stop();
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    double decode_time_in_ms =
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        static_cast<double>(decode_timer.GetInUsec()) / 1000;
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::cout << "Time to decode: "
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              << (decode_time_in_ms / num_iterations) << " ms" << std::endl;
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // unnamed namespace
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace open_vcdiff
635