From 5e669ac3ed87457b3b48a1441dfb5848f967a742 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 6 Jun 2017 14:16:01 -0700 Subject: [PATCH] add delta update class. (#74) --- mixerclient/BUILD | 13 +++++ mixerclient/src/delta_update.cc | 81 ++++++++++++++++++++++++++++ mixerclient/src/delta_update.h | 57 ++++++++++++++++++++ mixerclient/src/delta_update_test.cc | 77 ++++++++++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 mixerclient/src/delta_update.cc create mode 100644 mixerclient/src/delta_update.h create mode 100644 mixerclient/src/delta_update_test.cc diff --git a/mixerclient/BUILD b/mixerclient/BUILD index cab781e4e0fe..bf2a809ac9d7 100644 --- a/mixerclient/BUILD +++ b/mixerclient/BUILD @@ -28,6 +28,8 @@ cc_library( "src/cache_key_set.h", "src/client_impl.cc", "src/client_impl.h", + "src/delta_update.cc", + "src/delta_update.h", "src/signature.cc", "src/signature.h", "src/quota_cache.cc", @@ -122,6 +124,17 @@ cc_test( ], ) +cc_test( + name = "delta_update_test", + size = "small", + srcs = ["src/delta_update_test.cc"], + linkstatic = 1, + deps = [ + ":mixer_client_lib", + "//external:googletest_main", + ], +) + cc_test( name = "quota_cache_test", size = "small", diff --git a/mixerclient/src/delta_update.cc b/mixerclient/src/delta_update.cc new file mode 100644 index 000000000000..9f84129f02a2 --- /dev/null +++ b/mixerclient/src/delta_update.cc @@ -0,0 +1,81 @@ +/* Copyright 2017 Istio Authors. All Rights Reserved. + * + * 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 + * + * http://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. + */ +#include "src/delta_update.h" + +#include + +namespace istio { +namespace mixer_client { +namespace { + +class DeltaUpdateImpl : public DeltaUpdate { + public: + // Start a update for a request. + void Start() override { + prev_set_.clear(); + for (const auto& it : prev_map_) { + prev_set_.insert(it.first); + } + } + + bool Check(int index, const Attributes::Value& value) override { + bool same = false; + const auto& it = prev_map_.find(index); + if (it != prev_map_.end()) { + if (it->second.type == value.type && it->second == value) { + same = true; + } + } + if (!same) { + prev_map_[index] = value; + } + prev_set_.erase(index); + return same; + } + + // "deleted" is not supported for now. If some attributes are missing, + // return false to indicate delta update is not supported. + bool Finish() override { return prev_set_.empty(); } + + private: + // The remaining attributes from previous. + std::set prev_set_; + + // The attribute map from previous. + std::map prev_map_; +}; + +// An optimization for non-delta update case. +class DeltaUpdateNoOpImpl : public DeltaUpdate { + public: + void Start() override {} + bool Check(int index, const Attributes::Value& value) override { + return false; + } + bool Finish() override { return true; } +}; + +} // namespace + +std::unique_ptr DeltaUpdate::Create() { + return std::unique_ptr(new DeltaUpdateImpl); +} + +std::unique_ptr DeltaUpdate::CreateNoOp() { + return std::unique_ptr(new DeltaUpdateNoOpImpl); +} + +} // namespace mixer_client +} // namespace istio diff --git a/mixerclient/src/delta_update.h b/mixerclient/src/delta_update.h new file mode 100644 index 000000000000..5acb38702cfb --- /dev/null +++ b/mixerclient/src/delta_update.h @@ -0,0 +1,57 @@ +/* Copyright 2017 Istio Authors. All Rights Reserved. + * + * 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 + * + * http://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 MIXERCLIENT_DELTA_UPDATE_H +#define MIXERCLIENT_DELTA_UPDATE_H + +#include "include/attribute.h" + +#include + +namespace istio { +namespace mixer_client { + +// A class to support attribute delta update. +// It has previous attribute values and check +// for the current one. +class DeltaUpdate { + public: + virtual ~DeltaUpdate() {} + + // Start a new delta update + virtual void Start() = 0; + + // Check an attribute, return true if it is in the previous + // set with same value, so no need to send it again. + // Each attribute in the current set needs to call this method. + virtual bool Check(int index, const Attributes::Value& value) = 0; + + // Finish a delta update. + // Return false if delta update is not supported. + // For example, "deleted" is not supported, if some attributes are + // missing, delta update will not be supported. + virtual bool Finish() = 0; + + // Create an instance. + static std::unique_ptr Create(); + + // Create an no-op instance; an optimization for no delta update cases. + static std::unique_ptr CreateNoOp(); +}; + +} // namespace mixer_client +} // namespace istio + +#endif // MIXERCLIENT_DELTA_UPDATE_H diff --git a/mixerclient/src/delta_update_test.cc b/mixerclient/src/delta_update_test.cc new file mode 100644 index 000000000000..5a261bfdf1ce --- /dev/null +++ b/mixerclient/src/delta_update_test.cc @@ -0,0 +1,77 @@ +/* Copyright 2017 Istio Authors. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +#include "src/delta_update.h" +#include "gtest/gtest.h" + +namespace istio { +namespace mixer_client { + +class DeltaUpdateTest : public ::testing::Test { + public: + void SetUp() { + string_map_value_ = Attributes::StringMapValue({{"foo", "bar"}}); + update_ = DeltaUpdate::Create(); + + update_->Start(); + EXPECT_FALSE(update_->Check(1, Attributes::Int64Value(1))); + EXPECT_FALSE(update_->Check(2, Attributes::Int64Value(2))); + EXPECT_FALSE(update_->Check(3, string_map_value_)); + EXPECT_TRUE(update_->Finish()); + } + + std::unique_ptr update_; + Attributes::Value string_map_value_; +}; + +TEST_F(DeltaUpdateTest, TestUpdateNoDelete) { + update_->Start(); + // 1: value is the same. + EXPECT_TRUE(update_->Check(1, Attributes::Int64Value(1))); + // 2: value is different. + EXPECT_FALSE(update_->Check(2, Attributes::Int64Value(3))); + // 3: compare string map. + EXPECT_TRUE(update_->Check(3, string_map_value_)); + // 4: an new attribute. + EXPECT_FALSE(update_->Check(4, Attributes::Int64Value(4))); + // No missing item + EXPECT_TRUE(update_->Finish()); +} + +TEST_F(DeltaUpdateTest, TestUpdateWithDelete) { + update_->Start(); + // 1: value is the same. + EXPECT_TRUE(update_->Check(1, Attributes::Int64Value(1))); + + // 2: is missing + + // 3: compare string map + EXPECT_FALSE(update_->Check(3, Attributes::StringMapValue({}))); + + // 4: an new attribute. + EXPECT_FALSE(update_->Check(4, Attributes::Int64Value(4))); + + // There is a missing item + EXPECT_FALSE(update_->Finish()); +} + +TEST_F(DeltaUpdateTest, TestDifferentType) { + update_->Start(); + // 1 is differnt type. + EXPECT_FALSE(update_->Check(1, Attributes::StringValue(""))); +} + +} // namespace mixer_client +} // namespace istio