עוגני-מילה לקישורים: טבלת link_anchor + מילוי בשני הגנרטורים#13
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for word-level link anchors (LinkAnchor) inside line text, adding a new database table, queries, and repository methods. It updates both the Otzaria and Sefaria SQLite generators to parse, convert, and import these anchors (using visible-character offsets) from inline commentary markers (itags) and char-level data, backed by comprehensive tests. The review feedback highlights two critical N+1 query performance bottlenecks in SefariaInlineAnchors and SefariaCharLevelAnchors due to repeated database calls inside loops, suggesting pre-fetching links into memory to optimize generation speed.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| var anchored = false | ||
| for (entry in entries) { | ||
| val tgtLineId = lineKeyToId[entry.path to (entry.lineIndex - 1)] ?: continue | ||
| for (linkId in repository.getLinkIdsBetweenLines(srcLineId, tgtLineId)) { |
There was a problem hiding this comment.
יש כאן בעיית ביצועים משמעותית של N+1 שאילתות. הקריאה ל-repository.getLinkIdsBetweenLines(srcLineId, tgtLineId) מתבצעת בתוך לולאה מקוננת עמוקה עבור כל itag בכל שורה של כל ספר. עבור ספרים גדולים עם הרבה הערות שוליים (כמו שולחן ערוך), זה יגרום לעשרות אלפי שאילתות בודדות ל-DB, מה שיאט מאוד את תהליך הגנרציה.\n\nהצעה לפתרון:\nניתן לייעל זאת משמעותית על ידי טעינה מראש (pre-fetching) של כל הקישורים עבור הספר הנוכחי לתוך Map בזיכרון בתחילת הלולאה של הספר:\n1. הוספת מתודה ב-SeforimRepository שטוענת את כל הקישורים עבור sourceBookId מסוים (השאילתה selectLinksBySourceBook כבר קיימת ב-LinkQueries.sq).\n2. בניית Map מקומי של Pair(sourceLineId, targetLineId) -> List<Long> בתחילת הלולאה של book.\n3. שימוש ב-Map המקומי במקום פנייה ל-DB בכל איטרציה.
| skip("offsets out of bounds") | ||
| continue | ||
| } | ||
| val linkIds = repository.getLinkIdsBetweenLines(entry.srcLineId, entry.tgtLineId) |
There was a problem hiding this comment.
גם כאן ישנה בעיית ביצועים של N+1 שאילתות: הקריאה ל-repository.getLinkIdsBetweenLines(entry.srcLineId, entry.tgtLineId) מתבצעת בתוך לולאה על כל ה-pending (שיכול להכיל מאות אלפי איברים בריצה מלאה). פנייה ל-DB עבור כל איבר בנפרד תאט מאוד את הגנרטור.\n\nהצעה לפתרון:\nניתן לקבץ (group) את ה-pending לפי הספר (או ה-path), ולטעון מראש את הקישורים הרלוונטיים עבור אותו ספר לתוך Map בזיכרון, בדומה להצעה ב-SefariaInlineAnchors.
ec095e4 to
8bbc270
Compare
8bbc270 to
2b36edc
Compare
עוגני-מילה לקישורים: טבלת
link_anchor+ מילוי בשני הגנרטורים.מה זה
עד היום קישור מעוגן לשורה שלמה. חלק מהמפרשים (למשל באר הגולה על שו"ע) מציבים כמה הערות על שורה אחת בלי דיבור-המתחיל, כך שאי אפשר לדעת על איזו מילה כל הערה. השינוי מוסיף עיגון ברמת המילה.
הטבלה
link_anchor(linkId, side, charStart, charEnd, label)— אופסטים במוסכמת תווים-גלויים (כמוline.charCount). מפתח ראשי מורכב על עמודות יציבות ⇒ אין שינוי ל-IdAllocator/buildstate ואין מיגרציה. נרשמה ל-PATCH_TABLES_IN_FK_ORDERול-LogicalContentHasherכך שה-delta הקיים נושא אותה אוטומטית ל-DB של לקוחות.מקורות העיגון
<i data-commentator … data-order/data-label>) המוטמעים בטקסטי הבסיס —SefariaInlineAnchors. הסמנטיקה אומתה מול קוד הקליינט של ספריא; עוגן נוצר רק כשכבר קיימת שורתlinkתואמת, כך ששגיאת רזולוציה לא ממציאה קישור. תגים ללאdata-labelשומריםtoGematria(order)כאות המודפסת.start/endבקבצי הקישורים של אוצריא (משפחת "אור הישר", ומשנה ברורה→שער הציון לאחר המרה) — נקראים ב-Generatorומומרים לאופסט תווים-גלויים; האות נגזרת מ-heRef_2העשיר.charLevelData(quotation finder) מעמודות ה-CSV החדשות —SefariaCharLevelAnchors, ייבוא מדויק-בלבד: שער גרסה-יחידה תואמת + שורה שלא שונתה ע"י cleanSefariaLine + גבולות. תאים מבוססי-מילים מדולגים. כל דילוג נספר ומדווח.אימות
🤖 Generated with Claude Code