| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 "server/hashkey_transform.h" |
| |
| #include <gtest/gtest.h> |
| #include <rocksdb/comparator.h> |
| |
| #include "base/pegasus_key_schema.h" |
| |
| // User define SliceTransform must obey the 4 rules of ColumnFamilyOptions.prefix_extractor: |
| // 1) key.starts_with(prefix(key)) |
| // 2) Compare(prefix(key), key) <= 0. |
| // 3) If Compare(k1, k2) <= 0, then Compare(prefix(k1), prefix(k2)) <= 0 |
| // 4) prefix(prefix(key)) == prefix(key) |
| TEST(HashkeyTransformTest, Basic) |
| { |
| pegasus::server::HashkeyTransform prefix_extractor; |
| const rocksdb::Comparator *comp = rocksdb::BytewiseComparator(); |
| |
| dsn::blob bkey1, bkey2, bkey3, bkey4; |
| pegasus::pegasus_generate_key(bkey1, std::string("h1"), std::string("s1")); |
| pegasus::pegasus_generate_key(bkey2, std::string("h2"), std::string("s1")); |
| pegasus::pegasus_generate_key(bkey3, std::string("h1"), std::string("s2")); |
| pegasus::pegasus_generate_key(bkey4, std::string("h1"), std::string("")); |
| rocksdb::Slice skey1(bkey1.data(), bkey1.size()); |
| rocksdb::Slice skey2(bkey2.data(), bkey2.size()); |
| rocksdb::Slice skey3(bkey3.data(), bkey3.size()); |
| rocksdb::Slice skey4(bkey4.data(), bkey4.size()); |
| |
| // 1) key.starts_with(prefix(key)) |
| ASSERT_TRUE(skey1.starts_with(prefix_extractor.Transform(skey1))); |
| ASSERT_TRUE(skey2.starts_with(prefix_extractor.Transform(skey2))); |
| ASSERT_TRUE(skey3.starts_with(prefix_extractor.Transform(skey3))); |
| ASSERT_TRUE(skey4.starts_with(prefix_extractor.Transform(skey4))); |
| |
| // 2) Compare(prefix(key), key) <= 0. |
| ASSERT_LT(comp->Compare(prefix_extractor.Transform(skey1), skey1), 0); // h1 < h1s1 |
| ASSERT_LT(comp->Compare(prefix_extractor.Transform(skey2), skey2), 0); // h2 < h2s1 |
| ASSERT_LT(comp->Compare(prefix_extractor.Transform(skey3), skey3), 0); // h1 < h1s2 |
| ASSERT_EQ(comp->Compare(prefix_extractor.Transform(skey4), skey4), 0); // h1 == h1 |
| |
| // 3) If Compare(k1, k2) <= 0, then Compare(prefix(k1), prefix(k2)) <= 0 |
| ASSERT_LT(comp->Compare(skey1, skey2), 0); // h1s1 < h2s1 |
| ASSERT_LT(comp->Compare(prefix_extractor.Transform(skey1), prefix_extractor.Transform(skey2)), |
| 0); // h1 < h2 |
| ASSERT_LT(comp->Compare(skey1, skey3), 0); // h1s1 < h1s2 |
| ASSERT_EQ(comp->Compare(prefix_extractor.Transform(skey1), prefix_extractor.Transform(skey3)), |
| 0); // h1 == h1 |
| ASSERT_GT(comp->Compare(skey1, skey4), 0); // h1s1 > h1 |
| ASSERT_EQ(comp->Compare(prefix_extractor.Transform(skey1), prefix_extractor.Transform(skey4)), |
| 0); // h1 == h1 |
| |
| // 4) prefix(prefix(key)) == prefix(key) |
| ASSERT_EQ(prefix_extractor.Transform(prefix_extractor.Transform(skey1)), |
| prefix_extractor.Transform(skey1)); |
| ASSERT_EQ(prefix_extractor.Transform(prefix_extractor.Transform(skey2)), |
| prefix_extractor.Transform(skey2)); |
| ASSERT_EQ(prefix_extractor.Transform(prefix_extractor.Transform(skey3)), |
| prefix_extractor.Transform(skey3)); |
| ASSERT_EQ(prefix_extractor.Transform(prefix_extractor.Transform(skey4)), |
| prefix_extractor.Transform(skey4)); |
| } |