Almacén direccionable por contenido
Cómo PCPM ahorra 70-90% de disco en soluciones multi-proyecto.
El almacén direccionable por contenido es la parte de PCPM que hace el trabajo pesado. Es la razón por la que un monorepo de 30 proyectos cabe en unos pocos cientos de megabytes en lugar de decenas de gigabytes.
Qué significa “direccionable por contenido”
Un almacén direccionable por contenido es una disposición de directorios donde la ruta de un fichero se deriva de su contenido. La receta habitual es:
- Calcular un hash de los bytes del fichero —
sha256, en el caso de PCPM. - Almacenar el fichero en
<raíz>/<2-primeros-chars>/<resto-chars>/<nombre-fichero>. - Para buscar un fichero, hasheas los bytes que tienes, derivas la ruta y lo lees.
La propiedad que obtienes gratis es la desduplicación: si dos ficheros tienen los mismos bytes, tienen el mismo hash, y tienen la misma ruta. El segundo no necesita una copia separada en disco.
PCPM lo usa para los ficheros .nupkg (archivos inmutables) y para
los contenidos extraídos del paquete (lib/, runtimes/, etc.). La
ruta del store en Windows es %LOCALAPPDATA%\pcpm\store; en Linux
y macOS es ~/.local/share/pcpm/store.
El layout en disco
%LOCALAPPDATA%\pcpm\store\
v1\
8f\ # 2 primeros chars del sha256
8f3a4b5c6d7e…\ # resto de chars del sha256
pkg.nupkg # el archivo inmutable
extracted\
newtonsoft.json\
13.0.3\
lib\
net6.0\… # contenidos lib/net6.0 del paquete
netstandard2.0\…
Cada .nupkg distinto de tu grafo de dependencias se almacena
exactamente una vez, sin importar cuántos proyectos dependan de él.
¿Por qué hardlinks NTFS?
Una vez que un paquete está en el store, pcpm install lo hace
visible para dotnet restore haciendo un hardlink del mismo en
~/.nuget/packages. Un hardlink es una entrada de directorio que
apunta al mismo inodo en disco que otra. Dos rutas, un fichero, cero
disco extra.
NTFS (Windows), APFS (macOS) y ext4 (Linux) soportan hardlinks, y PCPM los usa en los dos primeros. En Linux, donde la combinación estándar ext4 + libcs también se lleva bien con hardlinks, PCPM usa hardlinks. El fallback — cuando el origen y el destino están en volúmenes distintos, o cuando el sistema de ficheros no soporta hardlinks — es una copia de fichero normal.
El hardlink es invisible para la aplicación: dotnet restore ve un
árbol ~/.nuget/packages/<id>/<version>/ normal. No hay nada
personalizado en el lado del consumidor.
¿Cuánto disco ahorras?
Cifras aproximadas de un monorepo de 30 proyectos con 200 paquetes únicos:
| Layout | Disco usado |
|---|---|
~/.nuget/packages por defecto (sin PCPM) | 8.2 GB |
| PCPM, primera ejecución | 4.1 GB |
| PCPM, tras una restauración limpia | 4.1 GB |
| PCPM, tras añadir un proyecto que usa los mismos paquetes | 4.1 GB |
El número de PCPM no crece con el número de proyectos. Añadir un proyecto 30 que use los mismos 200 paquetes añade cero bytes al store.
Por qué importa
El disco es la ganancia obvia, pero el beneficio más profundo es la
velocidad de I/O. Restaurar un proyecto contra un store
caliente está limitado por operaciones de metadatos: dotnet restore
leyendo el lockfile, MSBuild recorriendo el grafo del proyecto, y el
runtime abriendo los metadatos del ensamblado. El paso de
copia-desde-red desaparece. En un runner de CI limpio con caché
caliente, el wall-clock de pcpm install más dotnet restore está
dominado por el segundo, no por el primero.
¿Qué hay en el lockfile?
pcpm.lock registra la versión resuelta y el hash de contenido
de cada paquete. Esto es lo que hace que el store sea un “store” y
no solo una caché: dado un lockfile, PCPM puede verificar que los
bytes de cada entrada están presentes en el store, o descargar
exactamente los que faltan.
El formato es un documento JSON estable:
{
"version": 1,
"packages": [
{
"id": "newtonsoft.json",
"version": "13.0.3",
"hash": "sha256:8f3a4b5c6d7e…",
"dependencies": { … }
}
]
}
pcpm ci valida los hashes contra el store y falla si falta algo.
pcpm install re-resuelve el grafo y actualiza el lockfile; los
hashes se reescriben solo si un bump transitivo cambió el contenido
de un paquete.
Véase también
- Resolución de dependencias — cómo PCPM elige la versión correcta de cada paquete.
- CLI:
pcpm store— subcomandos para inspeccionar el store.