Repository navigation
Commit 2bd51ec
authored
perf(storage/tigris): push any repository in bounded memory (#25)
* perf(storage/tigris): index pushed packs in bounded memory
A push decoded its pack through a scratch go-git filesystem.Storage.
That storage parses with no storage attached, so go-git's parser stays
out of low-memory mode and keeps every inflated base and resolved delta
until the parse ends. A push of golang/go (465 MiB pack) passed 21 GiB
of heap and did not complete.
Replace it with a small index-pack in indexpack.go. One pass stages,
checksums, and indexes the pack as it arrives, with no bodies kept. A
second pass resolves each delta tree depth first, so a body lives only
while a delta below it needs it. Bodies over 8 MiB, or past a 64 MiB
total, go to temp files. writePack hands the stream over through a new
optional ReadPack method, which also removes a go-git Scanner that
buffered every object body in full.
golang/go now peaks at about 521 MiB of heap and takes 23 s. Xe/x goes
from 516 MiB and 14.7 s to about 165 MiB and 1.3 s. Delta reuse is
unchanged.
This also fixes stored delta chains of exactly 50 links, which git
makes by default and which reads refused. Reads now accept a chain of
maxDeltaDepth links, and the writer stores an object whole rather than
extend a stored chain past that, since clients can send 4095.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* docs: plan bounded push memory and describe the new pack writer
Record the measurements behind the new pack writer, the delta chain
depth fault it found, and the next phase: a compact pack index to
replace the per-object entries map.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* perf(storage/tigris): replace the pack index map with sorted tables
The pack index kept a map[plumbing.Hash]packEntry, about 210 bytes for
each object. Every push held one entry for each object it wrote, and
every clone or fetch built one for each object in the repository.
Keep the entries in immutable tables instead: the hashes in one sorted
[]byte and a 40-byte record for each object, about 60 bytes with SHA-1.
A record names its pack by number and its delta base by record number.
Each registered container adds a table, and more than 16 tables merge
into one, so a lookup is at most 16 binary searches. deregister takes
only a pack id, so packJob no longer holds its cueRecords until the
upload ends.
The iterator walks 8-byte record references instead of a copy of every
entry, and yields a hash only from the record the lookup returns, which
removes its set of seen hashes. A snapshot shares the tables with the
index rather than copying them, because the index never edits them in
place.
For golang/go, a cold index build drops from 225 MiB to 113 MiB of live
heap (the index itself from about 180 MiB to 40 MiB). A push peaks at
364 MiB instead of 521 MiB.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* perf(storage/tigris): cut system calls on the push path
A CPU profile of a golang/go push spent about 80% of its time in system
calls. packSegment wrote each object to its file with no buffer, which
cost 14.7 s of a 26 s push. Write through a 1 MiB buffer and count the
bytes, so copyCompressed no longer seeks to measure a payload. The
unused segmentStore reads from an open segment, so it flushes first.
Each inflate also read its section through a 32 KiB buffer, so even a
tiny object read 32 KiB. Read a section of 64 KiB or less whole, with
one ReadAt of its own length.
Wall time did not move measurably on a laptop: one pread per inflate
now dominates. The plan records mmap of the staged pack as the next
step.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* docs: record the compact pack index and its measurements
Describe the table-based pack index in the storer architecture, and
add the phase 2 results and the remaining push-time work to the plan.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* style(storage/tigris): gofmt iter.go
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* test(storage/tigris): cover the pack reader with hand-built packs
The existing pack tests reach the new pack reader only through Write,
with packs from the git CLI, so they never send a REF-delta, a delta
whose base is already in the repository, a chain deeper than a read
walks, or a malformed pack.
Build packs by hand and push each one through both ReadPack and Write.
The round-trip cases read every object back through a new Storer and
check the stored delta count and the longest stored chain. The reject
cases check the error and that no PutObject call was made. One more
test pins that ReadPack leaves the bytes after the trailer unread,
which writePack depends on for git:// and SSH.
Removing the chain-depth cap or the delta source-size check makes
these tests fail.
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
* docs: format the push memory plan with prettier
Assisted-by: Claude Opus 5.5 via Claude Code
Signed-off-by: Xe Iaso <xe@tigrisdata.com>
---------
Signed-off-by: Xe Iaso <xe@tigrisdata.com>1 parent f4b0030 commit 2bd51ec
14 files changed
Lines changed: 2589 additions & 430 deletions
File tree
- cmd/objgitd
- docs
- architecture
- plans
- reference
- internal/storage/tigris
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
268 | 268 | | |
269 | 269 | | |
270 | 270 | | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
271 | 282 | | |
272 | 283 | | |
273 | 284 | | |
| |||
278 | 289 | | |
279 | 290 | | |
280 | 291 | | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
281 | 298 | | |
282 | 299 | | |
283 | 300 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
339 | 339 | | |
340 | 340 | | |
341 | 341 | | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
352 | | - | |
353 | | - | |
354 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
355 | 372 | | |
356 | 373 | | |
357 | 374 | | |
358 | 375 | | |
359 | 376 | | |
360 | 377 | | |
361 | 378 | | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
362 | 383 | | |
363 | 384 | | |
364 | 385 | | |
| |||
417 | 438 | | |
418 | 439 | | |
419 | 440 | | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
420 | 476 | | |
421 | 477 | | |
422 | 478 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
0 commit comments