@startuml
scale 620 height
top to bottom direction
skinparam backgroundColor transparent
skinparam shadowing false
skinparam defaultFontName Monospace
skinparam defaultFontSize 10
skinparam classBorderColor #2c7794
skinparam classBackgroundColor #edf6fa
skinparam ArrowColor #8095a1
title A2 STRUCTURE — RV32 header, split and two-sided coalescing

class "01 Block header" as HEADER {
  next : BlockLink_t*
  size : size_t
  raw sizeof = 8 bytes on RV32
  aligned xHeapStructSize = 16
}
class "Allocated block" as ALLOC {
  02 A: header + 24 byte request
  aligned total = 48 bytes
  payload begins after header
}
class "03 Free remainder" as REM {
  own header
  free = 4032 bytes after A
}

HEADER *-- ALLOC : precedes payload
ALLOC -down-> REM : first-fit + split

class "04 Address-ordered free list" as LIST {
  previous < inserted < current
  A < B < C+tail
}
class "05 Previous / left neighbour" as LEFT {
  previous + previous.size == inserted
  merge previous first
}
class "06 Next / right neighbour" as RIGHT {
  merged + merged.size == current
  merge next second
}

REM -down-> LIST : insert by address
LIST -down-> LEFT : heap_4 tests first
LEFT -down-> RIGHT : then tests next

note right of LIST
Address order exposes both physical
neighbours without scanning the arena.
end note
@enduml
