1 // Copyright 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_CELL_H 16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_CELL_H 17 18 #include "google/cloud/bigtable/internal/google_bytes_traits.h" 19 #include "google/cloud/bigtable/row_key.h" 20 #include "google/cloud/bigtable/version.h" 21 #include "google/cloud/status_or.h" 22 #include <chrono> 23 #include <type_traits> 24 #include <vector> 25 26 namespace google { 27 namespace cloud { 28 namespace bigtable { 29 inline namespace BIGTABLE_CLIENT_NS { 30 class Cell; 31 struct Mutation; 32 Mutation SetCell(Cell); 33 34 /** 35 * Defines the type for column qualifiers. 36 * 37 * Inside Google some protobuf fields of type `bytes` are mapped to a different 38 * type than `std::string`. This is the case for column qualifiers. We use this 39 * type to automatically detect what is the representation for this field and 40 * use the correct mapping. 41 * 42 * External users of the Cloud Bigtable C++ client library should treat this as 43 * a complicated `typedef` for `std::string`. We have no plans to change the 44 * type in the external version of the C++ client library for the foreseeable 45 * future. In the eventuality that we do decide to change the type, this would 46 * be a reason update the library major version number, and we would give users 47 * time to migrate. 48 * 49 * In other words, external users of the Cloud Bigtable C++ client should simply 50 * write `std::string` where this type appears. For Google projects that must 51 * compile both inside and outside Google, this alias may be convenient. 52 */ 53 using ColumnQualifierType = std::decay<decltype( 54 std::declval<google::bigtable::v2::Column>().qualifier())>::type; 55 56 /** 57 * Defines the type for cell values. 58 * 59 * Inside Google some protobuf fields of type `bytes` are mapped to a different 60 * type than `std::string`. This is the case for column qualifiers. We use this 61 * type to automatically detect what is the representation for this field and 62 * use the correct mapping. 63 * 64 * External users of the Cloud Bigtable C++ client library should treat this as 65 * a complicated `typedef` for `std::string`. We have no plans to change the 66 * type in the external version of the C++ client library for the foreseeable 67 * future. In the eventuality that we do decide to change the type, this would 68 * be a reason update the library major version number, and we would give users 69 * time to migrate. 70 * 71 * In other words, external users of the Cloud Bigtable C++ client should simply 72 * write `std::string` where this type appears. For Google projects that must 73 * compile both inside and outside Google, this alias may be convenient. 74 */ 75 using CellValueType = std::decay<decltype( 76 std::declval<google::bigtable::v2::Cell>().value())>::type; 77 78 /** 79 * The in-memory representation of a Bigtable cell. 80 * 81 * Bigtable stores data in rows, indexes by row keys. Each row may contain 82 * multiple column families, each column family might contain multiple columns, 83 * and each column has multiple cells indexed by timestamp. Notice that the 84 * storage is sparse, column families, columns, and timestamps might contain 85 * zero cells. 86 * 87 * The Cell class owns all its data. 88 */ 89 class Cell { 90 public: 91 /// Create a Cell and fill it with data. 92 template <typename KeyType, typename ColumnType, typename ValueType, 93 // This function does not participate in overload resolution if 94 // ValueType is not an integral type. The case for integral types is 95 // handled by the next overload, where the value is stored as a Big 96 // Endian number. 97 typename std::enable_if<!std::is_integral<ValueType>::value, 98 int>::type = 0> Cell(KeyType && row_key,std::string family_name,ColumnType && column_qualifier,std::int64_t timestamp,ValueType && value,std::vector<std::string> labels)99 Cell(KeyType&& row_key, std::string family_name, 100 ColumnType&& column_qualifier, std::int64_t timestamp, ValueType&& value, 101 std::vector<std::string> labels) 102 : row_key_(std::forward<KeyType>(row_key)), 103 family_name_(std::move(family_name)), 104 column_qualifier_(std::forward<ColumnType>(column_qualifier)), 105 timestamp_(timestamp), 106 value_(std::forward<ValueType>(value)), 107 labels_(std::move(labels)) {} 108 109 /// Create a Cell and fill it with a 64-bit value encoded as big endian. 110 template <typename KeyType, typename ColumnType> 111 // NOLINTNEXTLINE(performance-unnecessary-value-param) TODO(#4112) Cell(KeyType && row_key,std::string family_name,ColumnType && column_qualifier,std::int64_t timestamp,std::int64_t value,std::vector<std::string> labels)112 Cell(KeyType&& row_key, std::string family_name, 113 ColumnType&& column_qualifier, std::int64_t timestamp, 114 // NOLINTNEXTLINE(performance-unnecessary-value-param) TODO(#4112) 115 std::int64_t value, std::vector<std::string> labels) 116 : Cell(std::forward<KeyType>(row_key), std::move(family_name), 117 std::forward<ColumnType>(column_qualifier), timestamp, 118 google::cloud::internal::EncodeBigEndian(value), 119 std::move(labels)) {} 120 121 /// Create a cell and fill it with data, but with empty labels. 122 template <typename KeyType, typename ColumnType, typename ValueType> 123 // NOLINTNEXTLINE(performance-unnecessary-value-param) TODO(#4112) Cell(KeyType && row_key,std::string family_name,ColumnType && column_qualifier,std::int64_t timestamp,ValueType && value)124 Cell(KeyType&& row_key, std::string family_name, 125 ColumnType&& column_qualifier, std::int64_t timestamp, ValueType&& value) 126 : Cell(std::forward<KeyType>(row_key), std::move(family_name), 127 std::forward<ColumnType>(column_qualifier), timestamp, 128 std::forward<ValueType>(value), std::vector<std::string>{}) {} 129 130 /// Return the row key this cell belongs to. The returned value is not valid 131 /// after this object is deleted. row_key()132 RowKeyType const& row_key() const { return row_key_; } 133 134 /// Return the family this cell belongs to. The returned value is not valid 135 /// after this object is deleted. family_name()136 std::string const& family_name() const { return family_name_; } 137 138 /// Return the column this cell belongs to. The returned value is not valid 139 /// after this object is deleted. column_qualifier()140 ColumnQualifierType const& column_qualifier() const { 141 return column_qualifier_; 142 } 143 144 /// Return the timestamp of this cell. timestamp()145 std::chrono::microseconds timestamp() const { 146 return std::chrono::microseconds(timestamp_); 147 } 148 149 /// Return the contents of this cell. The returned value is not valid after 150 /// this object is deleted. value()151 CellValueType const& value() const& { return value_; } 152 /// Return the contents of this cell. value()153 CellValueType&& value() && { return std::move(value_); } 154 155 /** 156 * Interpret the value as a big-endian encoded `T` and return it. 157 * 158 * Google Cloud Bigtable stores arbitrary blobs in each cell. Some 159 * applications interpret these blobs as strings, other as encoded protos, 160 * and sometimes as big-endian integers. This is a helper function to convert 161 * the blob into a T value. 162 */ 163 template <typename T> decode_big_endian_integer()164 StatusOr<T> decode_big_endian_integer() const { 165 return internal::DecodeBigEndianCellValue<T>(value_); 166 } 167 168 /// Return the labels applied to this cell by label transformer read filters. labels()169 std::vector<std::string> const& labels() const { return labels_; } 170 171 private: 172 RowKeyType row_key_; 173 std::string family_name_; 174 ColumnQualifierType column_qualifier_; 175 std::int64_t timestamp_; 176 CellValueType value_; 177 std::vector<std::string> labels_; 178 179 friend Mutation SetCell(Cell); 180 }; 181 182 } // namespace BIGTABLE_CLIENT_NS 183 } // namespace bigtable 184 } // namespace cloud 185 } // namespace google 186 187 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_CELL_H 188