codex/external-memory-fragmentation.py

external-memory-fragmentation.py
"""Show a fixed, nonmoving allocation pool with 80 free bytes but no 48-byte hole.

Tested with Python 3.14.4 and Matplotlib as declared in pyproject.toml.
Writes external-memory-fragmentation.png to the current output directory.
"""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

fig, ax = plt.subplots(figsize=(7.2, 2.6), dpi=100)
fig.patch.set_facecolor('white')
segments = [(0,24,True),(24,16,False),(40,40,True),(80,8,False),(88,16,True)]
for start, size, free in segments:
    color = '#d9f1eb' if free else '#d3d9e1'
    ax.add_patch(Rectangle((start,0),size,1,facecolor=color,edgecolor='#445260',lw=1.2))
    label = f'Free\n{size} B' if free else f'{size} B\nused'
    ax.text(start+size/2,.5,label,ha='center',va='center',fontsize=9)
for boundary in [0,24,40,80,88,104]:
    ax.text(boundary,-.16,str(boundary),ha='center',va='top',fontsize=8.5)
ax.annotate('',xy=(0,1.58),xytext=(48,1.58),arrowprops=dict(arrowstyle='<->',color='#b24c35',lw=1.7))
ax.text(24,1.68,'One contiguous 48-byte request',ha='center',va='bottom',fontsize=10,color='#a23f29')
ax.set_xlim(-3,107)
ax.set_ylim(-.6,2.05)
ax.axis('off')
fig.suptitle('80 bytes free; largest available block is 40 bytes',fontsize=12,y=.98)
fig.text(.5,.04,'Fixed pool; occupied blocks cannot move. Offsets and sizes are in bytes; metadata is omitted.',
         ha='center',fontsize=8.5)
fig.subplots_adjust(left=.03,right=.98,bottom=.15,top=.82)
fig.savefig(Path.cwd()/'external-memory-fragmentation.png',facecolor='white')
plt.close(fig)