| 116 | } |
| 117 | |
| 118 | void TableBuilder::Add(const StringPiece& key, const StringPiece& value) { |
| 119 | Rep* r = rep_; |
| 120 | assert(!r->closed); |
| 121 | if (!ok()) return; |
| 122 | if (r->num_entries > 0) { |
| 123 | assert(key.compare(StringPiece(r->last_key)) > 0); |
| 124 | // See if this key+value would make our current block overly large. If |
| 125 | // so, emit the current block before adding this key/value |
| 126 | const int kOverlyLargeBlockRatio = 2; |
| 127 | const size_t this_entry_bytes = key.size() + value.size(); |
| 128 | if (this_entry_bytes >= kOverlyLargeBlockRatio * r->options.block_size) { |
| 129 | Flush(); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | if (r->pending_index_entry) { |
| 134 | assert(r->data_block.empty()); |
| 135 | FindShortestSeparator(&r->last_key, key); |
| 136 | string handle_encoding; |
| 137 | r->pending_handle.EncodeTo(&handle_encoding); |
| 138 | r->index_block.Add(r->last_key, StringPiece(handle_encoding)); |
| 139 | r->pending_index_entry = false; |
| 140 | } |
| 141 | |
| 142 | r->last_key.assign(key.data(), key.size()); |
| 143 | r->num_entries++; |
| 144 | r->data_block.Add(key, value); |
| 145 | |
| 146 | const size_t estimated_block_size = r->data_block.CurrentSizeEstimate(); |
| 147 | if (estimated_block_size >= r->options.block_size) { |
| 148 | Flush(); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | void TableBuilder::Flush() { |
| 153 | Rep* r = rep_; |
no test coverage detected