From 7a75415a619bd6698f45ec24f696f7b9dbb3752c Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Wed, 27 Jun 2012 11:31:08 +0200 Subject: Implement a cache for the monthly view Add a very simple cache, which is used to store the days that contain an event or an appointment. This makes redrawing and browsing the calendar panel much faster. The cache has a size of 31 integers (which is equivalent to 124 bytes on a 32 bit system and 248 bytes on a 64 bit system) and invalidates itself if the current month has changed. If an item is added/changed/removed, the cache needs to be invalidated manually by calling calendar_monthly_view_cache_set_invalid(). Note that this will always invalidate the whole cache, even if only one item at the last day of the month was removed. This is a trade-off between simplicity and efficiency. Signed-off-by: Lukas Fleischer --- src/calcurse.c | 1 + src/calcurse.h | 3 +++ src/calendar.c | 25 ++++++++++++++++++++++++- src/interaction.c | 13 +++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/calcurse.c b/src/calcurse.c index b868877..ba0f11e 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -369,6 +369,7 @@ int main(int argc, char **argv) case KEY_GENERIC_IMPORT: wins_erase_status_bar(); io_import_data(IO_IMPORT_ICAL, NULL); + calendar_monthly_view_cache_set_invalid(); inday = do_storage(0); wins_update(FLAG_ALL); break; diff --git a/src/calcurse.h b/src/calcurse.h index b21cd95..25bb780 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -144,6 +144,8 @@ #define DAYINSEC (DAYINMIN * MININSEC) #define HOURINSEC (HOURINMIN * MININSEC) +#define MAXDAYSPERMONTH 31 + /* Calendar window. */ #define CALHEIGHT 12 @@ -629,6 +631,7 @@ void calendar_store_current_date(struct date *); void calendar_init_slctd_day(void); struct date *calendar_get_slctd_day(void); long calendar_get_slctd_day_sec(void); +void calendar_monthly_view_cache_set_invalid(void); void calendar_update_panel(struct window *); void calendar_goto_today(void); void calendar_change_day(int); diff --git a/src/calendar.c b/src/calendar.c index a157caa..61e758b 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -77,6 +77,10 @@ static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *, unsigned) = { draw_monthly_view, draw_weekly_view}; +static int monthly_view_cache[MAXDAYSPERMONTH]; +static int monthly_view_cache_valid = 0; +static int monthly_view_cache_month = 0; + /* Switch between calendar views (monthly view is selected by default). */ void calendar_view_next(void) { @@ -264,6 +268,11 @@ static int date_change(struct tm *date, int delta_month, int delta_day) } } +void calendar_monthly_view_cache_set_invalid(void) +{ + monthly_view_cache_valid = 0; +} + /* Draw the monthly view inside calendar panel. */ static void draw_monthly_view(struct window *cwin, struct date *current_day, @@ -313,13 +322,25 @@ draw_monthly_view(struct window *cwin, struct date *current_day, day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; + /* invalidate cache if a new month is selected */ + if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { + monthly_view_cache_month = yr * YEARINMONTHS + mo; + monthly_view_cache_valid = 0; + } + for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { check_day.dd = c_day; check_day.mm = slctd_day.mm; check_day.yyyy = slctd_day.yyyy; /* check if the day contains an event or an appointment */ - item_this_day = day_check_if_item(check_day); + if (monthly_view_cache_valid) { + item_this_day = monthly_view_cache[c_day - 1]; + } + else { + item_this_day = monthly_view_cache[c_day - 1] = + day_check_if_item(check_day); + } /* Go to next line, the week is over. */ if (!c_day_1 && 1 != c_day) { @@ -352,6 +373,8 @@ draw_monthly_view(struct window *cwin, struct date *current_day, mvwprintw(cwin->p, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); } + + monthly_view_cache_valid = 1; } static int weeknum(const struct tm *t, int firstweekday) diff --git a/src/interaction.c b/src/interaction.c index 8f3ffdb..829e778 100644 --- a/src/interaction.c +++ b/src/interaction.c @@ -358,6 +358,8 @@ void interact_day_item_edit(void) break; } + calendar_monthly_view_cache_set_invalid(); + if (need_check_notify) notify_check_next_app(1); } @@ -571,6 +573,9 @@ void interact_day_item_add(void) if (apoint_hilt() == 0) apoint_hilt_increase(1); } + + calendar_monthly_view_cache_set_invalid(); + wins_erase_status_bar(); } @@ -613,6 +618,8 @@ void interact_day_item_delete(unsigned *nb_events, unsigned *nb_apoints) /* NOTREACHED */ } + calendar_monthly_view_cache_set_invalid(); + if (apoint_hilt() > 1) apoint_hilt_decrease(1); if (apad.first_onscreen >= to_be_removed) @@ -858,6 +865,8 @@ void interact_day_item_repeat(void) /* NOTREACHED */ } day_erase_item(date, item_nb, ERASE_FORCE); + + calendar_monthly_view_cache_set_invalid(); } /* Free the current cut item, if any. */ @@ -897,6 +906,8 @@ void interact_day_item_cut(unsigned *nb_events, unsigned *nb_apoints) day_cut.type = p->type; day_cut.item = p->item; + calendar_monthly_view_cache_set_invalid(); + if (p->type == EVNT || p->type == RECUR_EVNT) { (*nb_events)--; to_be_removed = 1; @@ -926,6 +937,8 @@ void interact_day_item_paste(unsigned *nb_events, unsigned *nb_apoints) item_type = day_paste_item(&day_cut, calendar_get_slctd_day_sec()); day_cut.type = 0; + calendar_monthly_view_cache_set_invalid(); + if (item_type == EVNT || item_type == RECUR_EVNT) (*nb_events)++; else if (item_type == APPT || item_type == RECUR_APPT) -- cgit v1.2.3-70-g09d2