MCPcopy Create free account
hub / github.com/apache/impala / FindChunk

Method FindChunk

be/src/runtime/mem-pool.cc:96–160  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

94}
95
96bool MemPool::FindChunk(int64_t min_size, bool check_limits) noexcept {
97 // Try to allocate from a free chunk. We may have free chunks after the current chunk
98 // if Clear() was called. The current chunk may be free if ReturnPartialAllocation()
99 // was called. The first free chunk (if there is one) can therefore be either the
100 // current chunk or the chunk immediately after the current chunk.
101 int first_free_idx;
102 if (current_chunk_idx_ == -1) {
103 first_free_idx = 0;
104 } else {
105 DCHECK_GE(current_chunk_idx_, 0);
106 first_free_idx = current_chunk_idx_ +
107 (chunks_[current_chunk_idx_].allocated_bytes > 0);
108 }
109 for (int idx = current_chunk_idx_ + 1; idx < chunks_.size(); ++idx) {
110 // All chunks after 'current_chunk_idx_' should be free.
111 DCHECK_EQ(chunks_[idx].allocated_bytes, 0);
112 if (chunks_[idx].size >= min_size) {
113 // This chunk is big enough. Move it before the other free chunks.
114 if (idx != first_free_idx) std::swap(chunks_[idx], chunks_[first_free_idx]);
115 current_chunk_idx_ = first_free_idx;
116 DCHECK(CheckIntegrity(true));
117 return true;
118 }
119 }
120
121 // Didn't find a big enough free chunk - need to allocate new chunk.
122 int64_t chunk_size;
123 DCHECK_LE(next_chunk_size_, MAX_CHUNK_SIZE);
124 DCHECK_GE(next_chunk_size_, INITIAL_CHUNK_SIZE);
125 chunk_size = max<int64_t>(min_size, next_chunk_size_);
126 if (enforce_binary_chunk_sizes_) chunk_size = BitUtil::RoundUpToPowerOfTwo(chunk_size);
127 if (check_limits) {
128 if (!mem_tracker_->TryConsume(chunk_size)) return false;
129 } else {
130 mem_tracker_->Consume(chunk_size);
131 }
132
133 MonotonicStopWatch sys_alloc_sw;
134 sys_alloc_sw.Start();
135 // Allocate a new chunk. Return early if malloc fails.
136 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(chunk_size));
137 uint64_t duration = sys_alloc_sw.ElapsedTime();
138 counters_.sys_alloc_duration.UpdateCounter(duration);
139 if (UNLIKELY(buf == NULL)) {
140 mem_tracker_->Release(chunk_size);
141 return false;
142 }
143 counters_.allocated_bytes.UpdateCounter(chunk_size);
144 ASAN_POISON_MEMORY_REGION(buf, chunk_size);
145
146 // Put it before the first free chunk. If no free chunks, it goes at the end.
147 if (first_free_idx == static_cast<int>(chunks_.size())) {
148 chunks_.push_back(ChunkInfo(chunk_size, buf));
149 } else {
150 chunks_.insert(chunks_.begin() + first_free_idx, ChunkInfo(chunk_size, buf));
151 }
152 current_chunk_idx_ = first_free_idx;
153 total_reserved_bytes_ += chunk_size;

Callers

nothing calls this directly

Calls 11

ChunkInfoClass · 0.85
push_backMethod · 0.80
sizeMethod · 0.45
TryConsumeMethod · 0.45
ConsumeMethod · 0.45
StartMethod · 0.45
ElapsedTimeMethod · 0.45
UpdateCounterMethod · 0.45
ReleaseMethod · 0.45
insertMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected