Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
chunked-vector.hh
Go to the documentation of this file.
1#pragma once
3
4#include <cstdint>
5#include <cstdlib>
6#include <vector>
7#include <limits>
8
9namespace nix {
10
20template<typename T, size_t ChunkSize>
21class ChunkedVector {
22private:
23 uint32_t size_ = 0;
24 std::vector<std::vector<T>> chunks;
25
29 [[gnu::noinline]]
30 auto & addChunk()
31 {
32 if (size_ >= std::numeric_limits<uint32_t>::max() - ChunkSize)
33 abort();
34 chunks.emplace_back();
35 chunks.back().reserve(ChunkSize);
36 return chunks.back();
37 }
38
39public:
40 ChunkedVector(uint32_t reserve)
41 {
42 chunks.reserve(reserve);
43 addChunk();
44 }
45
46 uint32_t size() const { return size_; }
47
48 std::pair<T &, uint32_t> add(T value)
49 {
50 const auto idx = size_++;
51 auto & chunk = [&] () -> auto & {
52 if (auto & back = chunks.back(); back.size() < ChunkSize)
53 return back;
54 return addChunk();
55 }();
56 auto & result = chunk.emplace_back(std::move(value));
57 return {result, idx};
58 }
59
60 const T & operator[](uint32_t idx) const
61 {
62 return chunks[idx / ChunkSize][idx % ChunkSize];
63 }
64
65 template<typename Fn>
66 void forEach(Fn fn) const
67 {
68 for (const auto & c : chunks)
69 for (const auto & e : c)
70 fn(e);
71 }
72};
73}