| 475 | } |
| 476 | |
| 477 | Status TupleCacheMgr::RequestWriteSize(UniqueHandle* handle, size_t new_size) { |
| 478 | // The handle better be from a writer |
| 479 | DCHECK((*handle)->is_writer); |
| 480 | |
| 481 | uint8_t* data = getHandleData(cache_.get(), handle->get()); |
| 482 | size_t cur_charge = reinterpret_cast<TupleCacheEntry*>(data)->charge; |
| 483 | if (new_size > cur_charge) { |
| 484 | // Need to increase the charge, which can fail |
| 485 | // 1. There is a maximum size for any given entry |
| 486 | // 2. There is a maximum amount of outstanding writes (i.e. dirty buffers) |
| 487 | // The chunk size limits the frequency of incrementing the counter in the cache |
| 488 | // itself. The chunk size is disabled for unit tests to have exact counter values. |
| 489 | // The chunk size does not impact enforcement of the maximum entry size. |
| 490 | |
| 491 | // An individual entry cannot exceed the MaxSize() |
| 492 | if (new_size > MaxSize()) { |
| 493 | tuple_cache_halted_->Increment(1); |
| 494 | return Status(TErrorCode::TUPLE_CACHE_ENTRY_SIZE_LIMIT_EXCEEDED, MaxSize()); |
| 495 | } |
| 496 | |
| 497 | size_t new_charge = new_size; |
| 498 | if (outstanding_write_chunk_bytes_ != 0) { |
| 499 | new_charge = ((new_size / outstanding_write_chunk_bytes_) + 1) * |
| 500 | outstanding_write_chunk_bytes_; |
| 501 | // The chunk size should not change the behavior of the MaxSize(), so limit the |
| 502 | // new_charge to MaxSize() if it would otherwise exceed it. |
| 503 | if (new_charge > MaxSize()) { |
| 504 | new_charge = MaxSize(); |
| 505 | } |
| 506 | } |
| 507 | int64_t diff = new_charge - cur_charge; |
| 508 | DCHECK_GT(new_charge, cur_charge); |
| 509 | DCHECK_GE(new_charge, new_size); |
| 510 | |
| 511 | // Limit the total outstanding writes to avoid excessive dirty buffers for the OS |
| 512 | if (tuple_cache_outstanding_writes_bytes_->GetValue() + diff > |
| 513 | outstanding_write_limit_) { |
| 514 | tuple_cache_backpressure_halted_->Increment(1); |
| 515 | return Status(TErrorCode::TUPLE_CACHE_OUTSTANDING_WRITE_LIMIT_EXCEEDED, |
| 516 | outstanding_write_limit_); |
| 517 | } |
| 518 | UpdateWriteSize(handle->get(), new_charge); |
| 519 | } |
| 520 | return Status::OK(); |
| 521 | } |
| 522 | |
| 523 | const char* TupleCacheMgr::GetPath(UniqueHandle& handle) const { |
| 524 | DCHECK(enabled_); |