אוניברסיטת בן-גוריון מדור בחינות מספר נבחן: רשמו תשובותיכם בגיליון התשובות בלבד, תשובות מחוץ לגיליון לא יבדקו. בהצלחה! (25 נקודות) שאלה 1: זיכרון רוצי

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

אוניברסיטת בן גוריון בנגב תאריך המבחן: שקולניק אלכסנדר שם המרצה: מר בשפת JAVA מבוא לתכנות מבחן ב: מס' הקורס : הנדסת תעשיה וניהול מ

תרגול מס' 4: המתרגם שימוש במחלקות קיימות מחרוזות, קבצים, וקבלת קלט מהמשתמש

מהוא לתכנות ב- JAVA מעבדה 3

מבוא למדעי המחשב

Microsoft PowerPoint - 10_threads.ppt

מבוא למדעי המחשב

PowerPoint Presentation

Slide 1

PowerPoint Presentation

מבוא למדעי המחשב

מבוא לתכנות ב- JAVA תרגול 11

Slide 1

שאלהIgal : מערכים דו מימדיים רקורסיה:

מבוא למדעי המחשב

PowerPoint Presentation

PowerPoint Presentation

מבחן 7002 פרטים כלליים מועד הבחינה: בכל זמן מספר השאלון: 1 משך הבחינה: 3 שעות חומר עזר בשימוש: הכל )ספרים ומחברות( המלצות: קרא המלצות לפני הבחינה ובדי

תרגול 1

מבוא לתכנות ב- JAVA תרגול 7

משימה תכנית המתרגמת קטעי טקסט לשפה אחרת הקלט: קובץ המכיל את קטעי הטקסט וכן את השפה אליה רוצים לתרגם תרגול מס' 4: המתרגם שימוש במחלקות קיימות תכנות מתק

Slide 1

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

המשימה תרגול מס' 5: קלט-פלט במערכות הפעלה שונות יש סימונים שונים עבור ירידת שורה :)newline( ב- UNIX/Linux )Line Feed( \n ב- Windows )Carriage Return +

PowerPoint Presentation

תכנות מונחה עצמים א' – תש"ע

מבחן סוף סמסטר מועד א 15/02/08 מרצה אחראית: דר שירלי הלוי גינסברג מתרגלים: גלעד קותיאל, דניאל גנקין הוראות: א. בטופס המבחן 7 עמודים ו 4 דפי נוסחאות. ב

שאלהIgal : מערכים דו מימדיים רקורסיה:

לנץ קרן מרצה: תכנותמונחהעצמים) ( יוםשישי 15 אוקטובר 0202 ב מועד 0202, אביב סמסטר סמסטר סוף מבחן גוטמן אייל רביב, אריאל משנה, אלון מתרגלים: הנחי

PowerPoint Presentation

מבוא למדעי המחשב

מבוא למדעי המחשב

תרגול 1

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

PowerPoint Presentation

Slide 1

PowerPoint Presentation

Microsoft PowerPoint - lec10.ppt

תורת הקומפילציה

שאלהIgal : מערכים דו מימדיים רקורסיה:

תרגול 1

מקביליות

Microsoft PowerPoint - rec3.ppt

Microsoft Word - pitaron222Java_2007.doc

הטכניון - מכון טכנולוגי לישראל הפקולטה להנדסת חשמל המעבדה למערכות תכנה מרושתות ניסוי בתכנות מקבילי ב- Java המאחר ביותר מ 51 דקות לא יורשה לבצע את הניס

מספר זהות: סמסטר ב' מועד א' תאריך: 11102/4// שעה: 9:22 משך הבחינה: 3 שעות חומר עזר: אין מותר השימוש במחשבון פשוט בחינה בקורס: מבני נתונים מרצה: הדר בי

מבוא למדעי המחשב

PowerPoint Presentation

פתרון מוצע לבחינת מה"ט ב_שפת c מועד ב אביב תשע"ט, אפריל 2019 מחברת: גב' זהבה לביא, מכללת אורט רחובות שאלה מספר 1 מוגדרת מחרוזת המורכבת מהספרות 0 עד 9.

Slide 1

תרגול 1

הגשה תוך שבוע בשעת התרגול

סדנת תכנות ב C/C++

תרגול 3 - מערכים

Homework Dry 3

תשע"דד אביב תוכנה 1 תרגיל מספר 4 עיבוד מחרוזות וקריאה מקבצים הנחיות כלליות: קראו בעיון את קובץ נהלי הגשת התרגילים אשר נמצא באתר הקורס..(

תאריך פרסום: תאריך הגשה: מבנה נתונים תרגיל 5 )תיאורטי( מרצה ומתרגל אחראים: צחי רוזן, דינה סבטליצקי נהלי הגשת עבודה: -את העבודה יש לה

HTML - Hipper Text Makeup Language

PowerPoint Presentation

מצגת של PowerPoint

PowerPoint Presentation

יום שלישי, 14 ליולי 2015 מבחן סוף סמסטר - תכנות מונחה עצמים )236703( סמסטר אביב 2015, מועד א' מרצה: ערן גלעד מתרגלים: נורית מושקוביץ', הלאל עאסי, אליר

Slide 1

יוםראשון, 02 ליולי 2014 סמסטר סוף מבחן )236703( עצמים מונחה תכנות - א' מועד 2014, אביב סמסטר קמחי יחיאל ד"ר מרצה: מסינג מיטל עבדאלקאדר, כרם גלעד, ערן

שעור 6

ייבוא וייצוא של קבצי אקסל וטקסט

מבוא למדעי המחשב, סמסטר א', תשס"ח תרגול מס' 2

תוכנה 1 תרגול מספר 12: GUI כתיבת מחלקות גנריות בית הספר למדעי המחשב אוניברסיטת תל אביב 1

PowerPoint Presentation

1 תוכנה 1 תרגיל מספר 7 מנשקים Interfaces הנחיות כלליות: קראו בעיון את קובץ נהלי הגשת התרגילים אשר נמצא באתר הקורס. הגשת התרגיל תעשה במערכת ה- moodle ב

תוכן העניינים

Microsoft Word - c_SimA_MoedB2005.doc

Microsoft PowerPoint - lecture14_networking.ppt

שבוע 4 סינטקס של HACK ASSEMBLY ניתן להשתמש בשלושה אוגרים בלבד:,A,D,M כולם בעלי 16 ביטים. M אינו אוגר ישיר- הוא מסמן את האוגר של ה RAM שאנחנו מצביעים ע

Microsoft PowerPoint - lec 04 Gui Form_Item.pptx

תוכן העניינים

Slide 1

מדריך לחיפוש במאגר JCR Journal Citation Reports מעודכן לדצמבר 2015 כל הזכויות שמורות לתחום היעץ, אוניברסיטת חיפה, הספריה

PRESENTATION NAME

מספר מחברת: עמוד 1 מתוך 11 ת"ז: תשע"א מועד ב סמסטר א' תאריך: 00:11 שעה: 0 שעות הבחינה: משך כל חומר עזר אסור בשימוש בחינה בקורס: מבוא למדעי ה

Microsoft PowerPoint - rec1.ppt

תרגול מס' 7: תרגילים מתקדמים ברקורסיה

מבחן סוף סמסטר מועד ב 28/10/08 מרצה אחראית: דר שירלי הלוי גינסברג מתרגלים: גלעד קותיאל, גדי אלכסנדרוביץ הוראות: א. בטופס המבחן 6 עמודים (כולל דף זה) ו

PowerPoint Presentation

מקביליות

מקביליות

תוכן הגדרת שאלת רב-ברירה ]אמריקאית[...2 הגדרת שאלת נכון\לא נכון...8 שאלות אמריקאיות 1

מבוא למדעי המחשב - חובלים

Microsoft PowerPoint - lec9.ppt

תכנות דינמי פרק 6, סעיפים 1-6, ב- Kleinberg/Tardos סכום חלקי מרחק עריכה הרעיון: במקום להרחיב פתרון חלקי יחיד בכל צעד, נרחיב כמה פתרונות אפשריים וניקח

Microsoft PowerPoint - T-10.ppt [Compatibility Mode]

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

Microsoft Word B

Microsoft PowerPoint - lec2.ppt

תמליל:

אוניברסיטת בן-גוריון מדור בחינות מספר נבחן: רשמו תשובותיכם בגיליון התשובות בלבד, תשובות מחוץ לגיליון לא יבדקו. בהצלחה! (25 נקודות) שאלה 1: זיכרון רוצים לכתוב תוכנית ב C++ לאיחסון ועיבוד תמונות שחור-לבן משני סוגים שונים: תמונות דיוקן Portrait ותמונות נוף.Scenery כל פיקסל בתמונה מחזיק ערך בתחום 0-255 של דרגת אפור. על כן הוחלט לשמור תמונה במערך חד ממדי של BYTES (ע"י שרשור שורות הפיקסלים בתמונה לוקטור חד ממדי). על מנת לאפשר שמירה של תמונות שונות יחד, הוחלט לבנות מחלקה ImageRepository אשר תאחסן תמונות שונות במערך בשם _.images להלן המימוש החלקי הבא: class Image { public: virtual void Filter() = 0; private: byte *_data; ; class Portrait : public Image{ public: void Filter() { ; ; class Scenery : public Image{ public: void Filter() { ; ; class ImageRepository { 1

public: ImageRepository(int capacity); void Insert(Image *arr, int size); private: מערך// **_images; Image גודל מקסימלי של המערך//; capacity _ int מספר מקומות פנויים במערך// _free; int ; void main() { Scenery scenes[2]; Portrait portraits[3]; ImageRepository myrep(5); myrep.insert(scenes,2); myrep.insert(portraits,3); /*here*/ א. ממשו את הבנאי ופונקצית Insert של המחלקה ImageRepository (מסומנים בקו). הבנאי מקצה זיכרון למערך מצביעים בגודל capacity מקומות. Insert מקבל מערך תמונות ומעתיק אותו העתקה עמוקה למערך במקום הפנוי. יש להוסיף שדות ומתודות אם נדרש. [10 נקודות] ב. סטודנט כתב את קטע הקוד הבא: ImageRepository CreateEmptyRep() { ImageRepository rep; return rep; void main(){ ImageRepository myrep(5); myrep = CreateEmptyRep(); הוסיפו את הנדרש (ואך ורק את הנדרש) על מנת שהקוד הנוסף יעבוד בצורה יעילה ונכונה (יורדו נקודות על קוד מיותר). [10 נקודות] ג. ציירו את תמונת הזיכרון המתקבלת בסוף main של סעיף א בשורה:./*here*/ יש לפרט. [5 נקודות] 2

(30 נקודות) שאלה 2: מקביליות סעיף א [5 נקודות] נתון הקוד הבא. כתבו את כל הפלטים האפשריים של התוכנית הבאה. נמקו את תשובתכם. public class A { public int i; public A(int i) { this.i = i; public class Task implements runnable { public A a; public Task(A a) { this.a = a; public void run() { System.out.print(a.i); public static void main(string[] args) { A a = new A(2); Thread t1 = new Thread(new Task(a)); Thread t2 = new Thread(new Task(a)); t1.start(); t2.start(); a = new A(3); סעיף ב [10 נקודות] נתונה תוכנית המריצה שלושה ת'רדים. לרשותם של הת'רדים מאגר משאבים pool) (resource שבו נמצאים N אובייקטים (כל האובייקטים זהים אחד לשני). כאשר ת'רד מבקש אובייקט מהמאגר, ויש במאגר אובייקט פנוי (שאינו תפוס אחד הת'רדים האחרים בתוכנית), אז הת'רד תופס את 3

האובייקט, משתמש בו, ומשחרר אותו לאחר מכן. אם ת'רד מבקש אובייקט ואין אובייקטים פנויים כרגע במאגר, הת'רד עובר למצב BLOCKED עד שיהיה משאב פנוי במאגר. הניחו שהמאגר הינו מבנה נתונים מסונכרן. הניחו שבכל בקשה הת'רד תופס רק אובייקט אחד מהמאגר, אבל יכול לבצע כמה בקשות כאלו לפני שהוא מבצע את הפעולה שלו. כאשר ת'רד מסיים את הפעולה, הוא משחרר את כל האובייקטים שהוא תפס עבורה. ב. 1 מהו המספר המינימלי של האובייקטים במאגר (כלומר, מהו הערך המינימלי של N) כך שלעולם לא יקרה מצב של חבק,(deadlock) אם כל ת'רד בתוכנית צריך 2 אובייקטים כדי לבצע את פעולתו? ב. 2 מהו המספר המינימלי של האובייקטים במאגר (כלומר, מהו הערך המינימלי של N) כך שלעולם לא יקרה מצב של חבק (deadlock) בתוכנית, אם כל ת'רד בתוכנית צריך משאב אחד בלבד כדי לבצע את פעולתו? סעיף ג [15 נקודות] בן קיבל משימה לכתוב קוד שמריץ שלושה ת'רדים, כאשר הת'רדים בוחרים 'מנהיג' אחד מביניהם. הוא בחר בעיצוב הבא: interface Leadership { boolean isleader(); void setleader(boolean b); class LeadershipBasedTask implements Runnable, Leadership { private boolean bleader; private ConcurrentLinkedQueue<Thread> threads; LeadershipBasedTask(ConcurrentLinkedQueue<Thread> threads) { this.bleader = true; this.threads = threads; public boolean isleader() { return bleader; public void setleader(boolean b) { bleader = b; 4

public void run() { for(thread t : threads) { if(system.identityhashcode(thread.currentthread()) < System.identityHashCode(t)) { setleader(false); break; //do something class Test { public static void run3threadswithleader() { ConcurrentLinkedQueue<Thread> threads = new ConcurrentLinkedQueue<Thread>(); for(int i = 0; i < 3; i++) { LeadershipBasedTask task = new LeadershipBasedTask(threads); Thread thread = new Thread(task); threads.add(thread); thread.start(); public static void main(string[] args) { run3threadswithleader(); ג. 1 הגדירו תנאי סיום condition) (post עבור המתודה.run3ThreadsWithLeader ג. 2 האם תנאי הסיום מתקיימים במימוש הנוכחי? נמקו. (הניחו שהפונקציה מחזירה identityhashcode ערך שונה לכל אובייקט) ג. 3 עדכנו את הקוד כך שתנאי הסיום יתקיימו (אין לשנות את שיטת בחירת המנהיג) 5

(30 נקודות) שאלה 3: תקשורת בנספח (בסוף השאלון), מופיע לנוחיותכם קוד הריאקטור כפי שנלמד בכיתה. כדי לעקוב אחר עבודת השרת, הוחלט להוסיף לתבנית הריאקטור מנגנון,logging המדווח בקובץ reactor.log על פעולות שונות שהשרת ביצע. לשם כך הוגדרה המחלקה :Logger public class Logger { OutputStream out; Logger(String filename) throws IOException { out = new FileOutputStream(filename); public synchronized void log(byte[] msg) throws IOException { out.write(msg); out.flush(); א. עדכנו את קוד הריאקטור כך שידווחו בעזרת ה logger הפעולות הבאות: התחברות לקוח - שליחת בתים ללקוח - קריאת בתים מלקוח - ביצוע הודעה של לקוח - אין לכתוב מחדש קוד קיים בגיליון התשובות. יש לציין את המחלקה, המתודה, ולציין מה הקוד החדש והיכן הוא ממוקם. לדוגמא: Logger = new Logger( reactor.log ); מחלקה: Reactor שדה חדש: Logger logger מתודה: בנאי הוספת שורה עם האתחול של השדה החדש [12 נקודות] 6

ב. ציינו אילו ת'רדים עשויים להיתקע (לעבור למצב (blocked בעקבות השינויים בקוד, ומדוע (2 סיבות)? אין לחרוג מהמקום שהוקצה לכך בגיליון התשובות. [4 נקודות] ג. נתונה המחלקה המרחיבה FileChannel את המחלקה (בדומה SelectableChannel ל (SocketChannel עבור קריאה וכתיבה לערוצי קלט ופלט מסוג קובץ. בדומה למחלקה,SocketChannel המחלקה FileChannel כוללת את המתודות הבאות: static FileChannel open(string filename) Opens a file-channel for the given file-name (if the file does not exist, it will be created). void configureblocking(boolean block) Adjusts this channel's blocking mode. long read(bytebuffer[] dsts) Reads a sequence of bytes from this channel into the given buffers. long write(bytebuffer[] srcs) Writes a sequence of bytes to this channel from the given buffers. עדכנו את קוד הריאקטור כך שהת'רדים המדווחים על הפעולות לקובץ הלוג (=קוראים למתודה log של ה.blocked לא יעברו בשל כך למצב (Logger בדומה לסעיף א, אין לכתוב מחדש קוד קיים בגיליון התשובות. יש לציין את המחלקה, המתודה, ולציין מה הקוד החדש והיכן הוא ממוקם. [14 נקודות] 7

(15 נקודות) שאלה 4: בסיסי נתונים בחברת Netflix משכירים סרטים ללקוחות בביתם, והם זקוקים למעקב אחר משתמשים והזמנת הסרטים שלהם לצורך המלצות. נציגי החברה פנו אליכם בבקשה ליצירת layer persistence עבורם. צריך לתמוך במידע הבא: ישנם משתמשים (users) אשר שוכרים סרטים.(movies) לכל משתמש יש רק id ושם.(name) לכל סרט יש,id שם הסרט,(name) תיאור מילולי,(description) ואופציה להיות שייך לקטגוריות (תיתכן יותר מאחת): מתח/פעולה,(Action) דרמה,(Drama) רומנטיקה,(Romance) או ילדים.(num_scorers) וכמות מדרגים (score) כמו כן, לסרט יש דירוג: ציון ממוצע.(kids) צפייה בסרט (movie_watch) מוגדרת ע"י המשתמש הצופה בסרט, הסרט הנצפה, ותאריך הצפייה. בסיום כל צפייה הצופה יכול לדרג את הסרט (ציון מ- 1 עד 10) ולהוסיף דעה (review) במלל חופשי. לשם פשטות נניח שמשתמש אינו רואה את אותו הסרט יותר מפעם אחת באותו יום. סעיף א' (3 נק'): סטודנט בוגר הקורס כתב את השאילות הבאות ליצירת הטבלאות במסד הנתונים, אבל שכח את כל נושא המפתחות. השלימו את השאילתות כך שמסד הנתונים יוגדר בצורה יעילה. מלאו את הקוד בדף התשובות. CREATE TABLE Users ( id INT???????????, name TEXT NOT NULL ); CREATE TABLE Movies ( id INT??????????, name TEXT NOT NULL, description TEXT, isaction BOOL NOT NULL, isromance BOOL NOT NULL, isdrama BOOL NOT NULL, iskids BOOL NOT NULL, score FLOAT NOT NULL, num_scorers INT NOT NULL ); CREATE TABLE Movie_watches ( user_id INT NOT NULL, movie_id INT NOT NULL, date DATE NOT NULL, score INT, review TEXT, ); FOREIGN KEY(???????? ) REFERENCES???????? FOREIGN KEY(???????? ) REFERENCES???????? PRIMARY KEY(???????????????????? ) 8

סעיף ב' (6 נק'): ברגע שצופה בוחר סרט ומתחיל בצפייה, נוספת רשומה לטבלה.movie_watches בסוף הצפייה יש לצופה את האופציה לתת score לסרט, ולעדכן את הreview הכתוב. השלימו את מחלקות ה- DTO וה- DAO הבאות. ניתן להניח שscore הוא ציון חוקי. class Movie_watch (object): def init (self,?? Fill Answer Sheet?? ):?? Fill Answer Sheet???? Fill Answer Sheet???? Fill Answer Sheet?? class _ Movie_watches: def init (self, conn): self._conn = conn def insert(self, user_id, movie_id, date): self._conn.cursor().execute("""??????????????? Fill Answer Sheet??????????????????????????????? Fill Answer Sheet???????????????? """, [????????????? Fill Answer Sheet????????????????? ]) def update(self, user_id, movie_id, date, score, review): self._conn.cursor().execute("""??????????????? Fill Answer Sheet?????????????????????????????? Fill Answer Sheet??????????????? """, [????????????? Fill Answer Sheet???????????????? ]) לנוחיותכם, הקוד הבא מתוך מחלקת DAO של הטבלה Users מייצג עדכון שם: class _Users (object) def update_name(self, id, name): self._conn.cursor().execute(""" UPDATE Users SET name = (?) WHERE id= (?) """, [name, id]) סעיף ג' (6 נק'): רוצים כעת שאילתה שבהינתן מספר id של משתמש תוציא את רשימת הצפיות שלו בשנה מסוימת, הכוללת: תאריך, שם הסרט, ה- score וה- review עבור כל צפייה. רשמו את השאילתה המתאימה בשפת SQL כאשר ניתן להתייחס לשנה כמשתנה,year$ ולמשתנה ה- id בתור.id$ רשמו את השאילתה בדף התשובות. לנוחיותכם, בדוגמא הבאה "שולפים" שנה מתוך תאריך ומשווים את הערך שלה SELECT * FROM my_friends WHERE YEAR(birthday) = 2013 9

נספח : קוד הריאקטור, כפי שנלמד בכיתה public class Reactor <T> implements Server<T> { private final int port; private final Supplier<MessagingProtocol<T>> protocolfactory; private final Supplier<MessageEncoderDecoder<T>> readerfactory; private final ActorThreadPool<NonBlockingConnectionHandler> pool; private Selector selector; private Thread selectorthread; private final ConcurrentLinkedQueue<Runnable> selectortasks = new ConcurrentLinkedQueue<>(); public Reactor( int numthreads, int port, Supplier<MessagingProtocol<T>> protocolfactory, Supplier<MessageEncoderDecoder<T>> readerfactory) { this.pool = new ActorThreadPool<>(numThreads); this.port = port; this.protocolfactory = protocolfactory; this.readerfactory = readerfactory; public void serve() { selectorthread = Thread.currentThread(); try ( Selector selector = Selector. open (); ServerSocketChannel serversock = ServerSocketChannel. open ()) { this.selector = selector; //just to be able to close serversock.bind(new InetSocketAddress(port)); serversock.configureblocking(false); serversock.register(selector, SelectionKey.OP_ACCEPT); while (!Thread.currentThread().isInterrupted()) { selector.select(); runselectionthreadtasks(); for (SelectionKey key : selector.selectedkeys()) { 10

if (! key.isvalid()) { continue; else if ( key.isacceptable()) { handleaccept(serversock, selector); else { handlereadwrite( key ); selector.selectedkeys(). clear (); catch (ClosedSelectorException ex) { //do nothing - server was requested to be closed catch (IOException ex) { //this is an error ex.printstacktrace(); System.out. println ("server closed!!!"); pool.shutdown(); void updateinterestedops(socketchannel chan, int ops) { final SelectionKey key = chan.keyfor(selector); if (Thread.currentThread() == selectorthread) { key.interestops(ops); else { selectortasks. add (() -> { if( key.isvalid()) key.interestops(ops); ); selector.wakeup(); private void handleaccept(servrsocketchannel serverchan, Selector selector) throws IOException { SocketChannel clientchan = serverchan.accept(); clientchan.configureblocking(false); final NonBlockingConnectionHandler<T> handler = new 11

NonBlockingConnectionHandler<>( readerfactory. get (), protocolfactory. get (), clientchan, this); clientchan.register(selector, SelectionKey.OP_READ, handler); private void handlereadwrite(selectionkey key ) { @SuppressWarnings("unchecked") NonBlockingConnectionHandler<T> handler = (NonBlockingConnectionHandler<T>) key.attachment(); if ( key.isreadable()) { Runnable task = handler.continueread(); if (task!= null) { pool.submit(handler, task); else if (! key.isvalid()) { return; if ( key.iswritable()) { handler.continuewrite(); private void runselectionthreadtasks() { while (!selectortasks.isempty()) { selectortasks.remove().run(); public void close() throws IOException { selector.close(); public interface MessageEncoderDecoder<T> { T decodenextbyte (byte nextbyte); byte[] encode(t message); public class LineMessageEncoderDecoder implements MessageEncoderDecoder<String> { 12

private byte[] bytes = new byte[ 1 << 10 ]; //start with 1k private int len = 0 ; @Override public String decodenextbyte (byte nextbyte) { if (nextbyte == '\n') { return popstring (); pushbyte(nextbyte); return null; //not a line yet @Override public byte[] encode(string message) { return (message + "\n").getbytes(); //uses utf8 by default private void pushbyte (byte nextbyte) { if (len >= bytes.length) { bytes = Arrays.copyOf(bytes, len * 2 ); bytes[len++] = nextbyte; private String popstring () { String result = new String(bytes, 0, len, StandardCharsets.UTF_8); len = 0 ; return result; public class EchoProtocol implements MessagingProtocol< String > { private boolean shouldterminate = false ; @Override public String process( String msg) { shouldterminate = "bye".equals(msg); System.out.println("[" + LocalDateTime.now() + "]: " + msg); return createecho(msg); 13

private String createecho( String message) { String echopart = message.substring( Math.max(message.length() - 2, 0 ), message.length()); return message + ".. " + echopart + ".. " + echopart + ".."; @Override public boolean shouldterminate() { return shouldterminate; public class NonBlockingConnectionHandler <T> implements ConnectionHandler<T> { private static final int BUFFER_ALLOCATION_SIZE = 1 << 13 ; //8k private static final ConcurrentLinkedQueue<ByteBuffer> BUFFER_POOL = new ConcurrentLinkedQueue<>(); private final MessagingProtocol<T> protocol; private final MessageEncoderDecoder<T> encdec; private final Queue<ByteBuffer> writequeue = new ConcurrentLinkedQueue<>(); private final SocketChannel chan; private final Reactor reactor; public NonBlockingConnectionHandler ( MessageEncoderDecoder<T> reader, MessagingProtocol<T> protocol, SocketChannel chan, Reactor reactor) { this.chan = chan; this.encdec = reader; this.protocol = protocol; this.reactor = reactor; public Runnable continueread () { ByteBuffer buf = leasebuffer(); boolean success = false; try { success = chan.read(buf)!= -1 ; catch (IOException ex) { 14

ex.printstacktrace(); if (success) { buf.flip(); return () -> { try { while (buf.hasremaining()) { T nextmessage = encdec.decodenextbyte(buf.get()); if (nextmessage!= null) { T response = protocol.process(nextmessage); if (response!= null) { writequeue.add(bytebuffer.wrap( encdec.encode(response))); reactor.updateinterestedops(chan, SelectionKey.OP_READ SelectionKey.OP_WRITE); finally { releasebuffer(buf); ; else { releasebuffer(buf); close(); return null; public void close () { try { chan.close(); catch (IOException ex) { ex.printstacktrace(); public void continuewrite () { while (!writequeue.isempty()) { try { ByteBuffer top = writequeue.peek(); chan.write(top); if (top.hasremaining()) { return; else { writequeue.remove(); 15

catch (IOException ex) { ex.printstacktrace(); close(); if (writequeue.isempty()) { if (protocol.shouldterminate()) close(); else reactor. updateinterestedops (chan, SelectionKey.OP_READ); private static ByteBuffer leasebuffer () { ByteBuffer buff = BUFFER_POOL.poll(); if (buff == null) { return ByteBuffer. allocatedirect (BUFFER_ALLOCATION_SIZE); buff.clear(); return buff; private static void releasebuffer (ByteBuffer buff) { BUFFER_POOL.add(buff); public class ActorThreadPool <T> { private final Map<T, Queue<Runnable>> actors; private final ReadWriteLock actorsreadwritelock; private final Set<T> playingnow; private final ExecutorService threads; public ActorThreadPool (int threads) { this.threads = Executors.newFixedThreadPool(threads); actors = new WeakHashMap<>(); playingnow = ConcurrentHashMap.newKeySet(); actorsreadwritelock = new ReentrantReadWriteLock(); public void shutdown () { threads.shutdownnow(); public void submit (T actor, Runnable r) { synchronized (actor) { 16

if (!playingnow.contains(actor)) { playingnow.add(actor); execute(r, actor); else { pendingrunnablesof(actor).add(r); private Queue<Runnable> pendingrunnablesof (T actors) { actorsreadwritelock.readlock().lock(); Queue<Runnable> pendingrunnables = actors.get(actors); actorsreadwritelock.readlock().unlock(); if (pendingrunnables == null) { actorsreadwritelock.writelock().lock(); actors.put(actor, pendingrunnables = new LinkedList<>()); actorsreadwritelock.writelock().unlock(); return pendingrunnables; private void execute (Runnable r, T actor) { threads.submit(() -> { try { r.run(); finally { complete(actor); ); private void complete (T actor) { synchronized (actor) { Queue<Runnable> pending = pendingrunnablesof(actor); if (pending.isempty()) { playingnow.remove(actor); else { execute(pending.poll(), actor); 17