לדלג לתוכן

פרויקט ספריית רשומות בינאריות

נבנה רכיב שמקבל קובץ קטן בזיכרון ומחליף אוסף רשומות קיים. הקלט אינו מהימן: מספר הרשומות יכול להיות שגוי, הקובץ יכול להיחתך בכל בית והקצאה יכולה להיכשל בדיוק אחרי שהתחלנו לעבוד. הפרויקט מחבר תבניות, בעלות, טווחים, משאבי זיכרון וערבויות פעולה.

החוזה שנממש

הפורמט מתחיל במספר רשומות בן ארבעה בתים ב־little endian. אחריו מופיעים ערכי הרשומות, כל אחד בן ארבעה בתים באותו סדר בתים. הקובץ חייב להכיל בדיוק את מספר הבתים הדרוש, בלי זנב נוסף. המספר המרבי המותר הוא 4096 רשומות.

המכולה הציבורית נקראת RecordStore. היא מחזיקה את הרשומות בבעלותה, ומקבלת std::pmr::memory_resource* שאינו בבעלותה. המשאב חייב לחיות יותר מהמכולה. הפעולה replace מקבלת std::span<const std::byte>, ומבטיחה שכשל בפענוח או בהקצאה משאיר את התוכן הקודם ללא שינוי.

פונקציית קריאת מספר unsigned תהיה גנרית לפי רוחב הטיפוס. ה־constraint צריך לדחות טיפוס signed, ואת תנאי האורך צריך לבדוק לפני כל גישה. אין להשתמש ב־cast של תחילת הקלט ל־uint32_t*, מפני שהקלט אינו מתחייב ליישור או לקיום אובייקטים מהטיפוס הזה.

סדר העבודה

התחילו מקריאת ערך בודד ובדיקות של סוף קלט. המשיכו לבדיקת כותרת והגבלת מספר הרשומות. רק אחרי שהקלט עבר בדיקות מבניות הקצו מכולה מועמדת, מלאו אותה ובצעו commit.

בנו משאב זיכרון שעוטף new_delete_resource, סופר הקצאות חיות ומסוגל להיכשל אחרי מספר הקצאות מוגדר. הכשל צריך להתרחש לפני הקצאה אמיתית, והמונה צריך להשתנות רק אחרי הצלחה. המשאב אינו צריך להיות בטוח לשימוש מקביל בפרויקט הזה.

כתבו בדיקות לקלט תקין וריק, לכותרת קטועה, לספירה גדולה מדי, לזנב עודף ולכשל הקצאה. הוסיפו בדיקת compile-fail לטיפוס signed. אחרי כל כשל השוו את התוכן הקיים לערכו לפני הקריאה.

מה מגישים

ההגשה כוללת קוד מלא והוראות בנייה ב־C++20, מפרט פורמט קצר וטבלת בעלות. צרפו את כל הקלטים המכשילים ואת התוצאה הצפויה שלהם. מדדו בנפרד מספר הקצאות ונפח חי מרבי בשתי מדיניות הקצאה, והסבירו אילו הקצאות אינן נראות למונה.

הרחבה נדרשת היא מתאם לממשק C אטום מהשיעור 2.9. אין צורך ב־DLL עדיין, אך אין להעביר מכולה תקנית או חריגה דרך הגבול. יש להגדיר כיצד הלקוח מקבל את מספר הרשומות וכיצד הוא מעתיק טווח ערכים אל buffer שבבעלותו.

הקבלה מותנית בכך שקלט פגום אינו מוביל לגישה מחוץ לתחום, שכשל משמר את המצב הקודם ושסיום החיים מחזיר את מספר ההקצאות החיות לאפס. הדוח צריך להסביר למה ה־swap בטוח עם המשאב שבחרתם, ואילו תנאים הופכים את הפתרון לבלתי חוקי.