| 233 | } |
| 234 | |
| 235 | inline HashTable::DuplicateNode* HashTable::InsertDuplicateNode( |
| 236 | int64_t bucket_idx, Status* status, BucketData* bucket_data) { |
| 237 | DCHECK_GE(bucket_idx, 0); |
| 238 | DCHECK_LT(bucket_idx, num_buckets_); |
| 239 | Bucket* bucket = &buckets_[bucket_idx]; |
| 240 | DCHECK(bucket->IsFilled()); |
| 241 | DCHECK(stores_duplicates()); |
| 242 | bool has_duplicates = bucket->HasDuplicates(); |
| 243 | // Allocate one duplicate node for the new data and one for the preexisting data, |
| 244 | // if needed. |
| 245 | while (node_remaining_current_page_ < 1 + !has_duplicates) { |
| 246 | if (UNLIKELY(!GrowNodeArray(status))) return NULL; |
| 247 | } |
| 248 | if (!has_duplicates) { |
| 249 | // This is the first duplicate in this bucket. It means that we need to convert |
| 250 | // the current entry in the bucket to a node and link it from the bucket. |
| 251 | next_node_->htdata.flat_row = bucket_data->htdata.flat_row; |
| 252 | DCHECK(!bucket->IsMatched()); |
| 253 | next_node_->SetNextUnMatched(nullptr); |
| 254 | AppendNextNode(bucket); |
| 255 | bucket->SetHasDuplicates(); |
| 256 | ++num_buckets_with_duplicates_; |
| 257 | } |
| 258 | // Link a new node and UnsetMatched |
| 259 | next_node_->SetNextUnMatched(bucket->GetDuplicate()); |
| 260 | return AppendNextNode(bucket); |
| 261 | } |
| 262 | |
| 263 | inline TupleRow* IR_ALWAYS_INLINE HashTable::GetRow(HtData& htdata, TupleRow* row) const { |
| 264 | if (stores_tuples()) { |
nothing calls this directly
no test coverage detected