دنبال فرمانی برای اجرا بگردید…
فایلهای بزرگ ناهمگون تغییر میکنند: ویرایشی کوچک و محلی نزدیک ابتدای فایل نباید انتقال دوبارهٔ کل فایل را لازم کند. zev این مشکل را با قطعهبندی بر پایهٔ محتوا حل میکند که روی یک پنجرهٔ غلتان با هش Gear ساخته شده است؛ همان خانوادهٔ الگوریتمی که ابزارهایی مثل restic و borg به کار میبرند، و بهطور مستقل در Zig و فقط با کتابخانهٔ استاندارد پیاده شده است.
یک قطعهبند مبتنی بر محتوا فایل را بر پایهٔ محتوای خود فایل، نه فاصلههای ثابت بایتی، به تکههایی با طول متغیر تقسیم میکند. وقتی ویرایشی کوچک انجام میشود، فقط قطعههایی که با آن ویرایش تماس دارند تغییر میکنند؛ هر مرز قطعه در جاهای دیگر فایل دقیقاً سر جایش میماند، چون مرز تابعی از بایتهای نزدیک است، نه یک شمارندهٔ بایت.
این ویژگی پیش از هر کار یکپارچهسازی، مستقل اثبات شد: قطعهبندی یک فایل واقعی ۱٫۷ مگابایتی و درج ویرایشی ۹۳ بایتی نزدیک ابتدایش، ۹۶٫۵٪ بایتهای فایل را (به حساب قطعه) بایتبهبایت بدون تغییر گذاشت. یک مدل ذخیرهسازی فایلکامل برای همین ویرایش یکخطی باید ۱۰۰٪ فایل را دوباره ذخیره میکرد.
هر قطعه با BLAKE3 هش میشود (مطابق شیوهٔ هویت اشیای خود سرور؛ نگاه کنید به ذخیرهسازی با نشانیدهی محتوایی) و بهصورت یک شیء معمولی با همان هش ذخیره میشود. یک مانیفست (فهرست مرتب هش قطعههایی که فایل اصلی را بازمیسازند) هم کنارش با کلید هش کل فایل ذخیره میشود.
این طراحی عمداً افزایشی است: فایل قطعهبندیشده همچنان بهصورت یک شیء کامل و معمولی هم ذخیره میشود. هر مسیر خواندن موجود که یک شیء، یک هش و یک فایل کامل انتظار دارد بدون تغییر کار میکند. قطعهبندی صرفاً بهینهسازیای است که زیر کار قرار گرفته و برای هر چیزی که صراحتاً آن را نخواهد نامرئی است.
POST .../objects/have).POST .../objects/reconstruct)؛ سرور خودش هش فایل را از قطعهها دوباره به دست میآورد و اگر با ادعا یکی نباشد چیزی ذخیره نمیکند.اندازهگیریشده روی یک فایل واقعی حدود ۱٫۷ مگابایتی با ۹۲ قطعه پس از یک ویرایش یکخطی واقعی: ۱ قطعهٔ تازه بارگذاری شد، ۹۱ قطعه از قبل موجود بود.
همان ایده، برعکس و دستهای. کلاینت هر چه را ندارد با چند درخواست میخواهد (POST .../objects/batch، هر بار تا ۲۵۶ شیء، چهار درخواست همزمان). شیءهای کوچک کامل میآیند. فایلی که قطعهقطعه ذخیره شده به شکل فهرست قطعههایش میآید: کلاینت هر قطعه را در حافظهٔ محلی قطعهها (که ارسالها و دریافتهای پیشین پرش کردهاند) جستوجو میکند، فقط قطعههای ناموجود را میخواهد (آن هم دستهای، و قطعهای که در چند فایل مشترک است فقط یک بار)، فایل را میسازد و پیش از نوشتن روی دیسک بررسی میکند که هش نتیجه درست باشد. هر شیء و هر قطعه با نامش، یعنی هش بایتهایش، سنجیده میشود.
اندازهگیریشده روی همان فایل واقعی، با دریافت همان ویرایش یکخطی در مخزنی که نسخهٔ قبلی را داشت: ۱ قطعه از شبکه دریافت شد، ۹۱ قطعه از حافظهٔ محلی. zev پس از دریافت این را نشان میدهد:
Fetched: 3 (3 in 2 request(s)), already had: 4 Large files: 1 chunk(s) downloaded, 91 reused from earlier pullsقطعهبندی پهنای باند را با تعداد درخواست معاوضه میکند. یک ارسال تنهای فایلی ۹۲ قطعهای میتواند بیش از ۹۰ درخواست HTTP جدا باشد (دریافتها با خواستن دستهای قطعهها از این پرهیز میکنند). این واقعاً با محدودیت نرخ درخواستی که برای ترافیک معمول API طراحی شده تداخل دارد؛ محدودیتی که برای الگوهای مصرف معمول اندازه شده با یک ارسال بزرگ قطعهبندیشده تمام میشود. سرور zev دقیقاً به همین دلیل به نقطههای پایانی مربوط به قطعهها (/have، /reconstruct، بارگذاری و دریافت تکقطعهها) سهمیهٔ نرخ جداگانه و بسیار بالاتری میدهد، تا همگامسازی انبوه قطعهها هرگز با سهمیهای که بقیهٔ API را محافظت میکند رقابت نکند یا آن را تمام نکند.