From 3d3d6755aab5995e163ccd0cddaa9523b0b4c8a4 Mon Sep 17 00:00:00 2001 From: Ron Koenderink Date: Wed, 2 Mar 2005 23:53:10 +0000 Subject: [PATCH] (nreport, filereport, ncache, addfree, findfree, delete_old_news) (init_nreport, update_main, start_server): Switch news to be sorted list with all new news items added at the end of the list. The removal of expired news items is done at update time. Closes #766755. --- include/prototypes.h | 2 + src/lib/subs/nreport.c | 155 ++++++++++++++++++++--------------------- src/lib/update/main.c | 1 + src/server/main.c | 1 + 4 files changed, 80 insertions(+), 79 deletions(-) diff --git a/include/prototypes.h b/include/prototypes.h index e001a6c2..fd8f627e 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -546,6 +546,8 @@ extern int natarg(s_char *, s_char *); /* neigh.c */ extern int neigh(coord, coord, natid); /* nreport.c */ +extern void delete_old_news(); +extern void init_nreport(); extern void nreport(natid, int, natid, int); /* nuke.c */ extern int nuk_postread(int, s_char *); diff --git a/src/lib/subs/nreport.c b/src/lib/subs/nreport.c index e10415f5..e8b19ce8 100644 --- a/src/lib/subs/nreport.c +++ b/src/lib/subs/nreport.c @@ -32,25 +32,35 @@ * Steve McClure, 1997 */ -#include "misc.h" -#include "news.h" -#include "nat.h" -#include "file.h" -#include "empio.h" -#include -#include "optlist.h" #include "prototypes.h" +#include "news.h" +#include "file.h" +#include "optlist.h" -static void filereport(int, int, int, int); +#define SLOTS 5 + +struct newscache { + struct nwsstr news; + int id; +}; + +static struct newscache cache[MAXNOC][SLOTS]; +static int news_tail; + +static struct newscache * +ncache(int actor, int event, int victim, int times); void nreport(natid actor, int event, natid victim, int times) { int nice; int rel; - struct natstr *np; + struct natstr *natp; + struct newscache *ncp; + + ncp = ncache(actor, event, victim, times); + putnews(ncp->id, &ncp->news); - filereport(actor, event, victim, times); /* * this is probably pretty expensive, but hopefully we * don't fire zillions of these things off every second. @@ -65,9 +75,9 @@ nreport(natid actor, int event, natid victim, int times) return; if (!chance((double)-nice * times / 20.0)) return; - if ((np = getnatp(victim)) == 0) + if ((natp = getnatp(victim)) == 0) return; - if ((rel = getrel(np, actor)) < HOSTILE) + if ((rel = getrel(natp, actor)) < HOSTILE) return; rel = HOSTILE; @@ -80,79 +90,76 @@ nreport(natid actor, int event, natid victim, int times) setrel(victim, actor, rel); } -struct free { - struct free *next; - int id; -}; - -struct free *freelist; - -static void -addfree(int n) +/* + * Delete news articles that have expired. + */ +void +delete_old_news(void) { - struct free *fp; + time_t expiry_time; + int i, j, k; + struct nwsstr news; - fp = (struct free *)malloc(sizeof(*fp)); - fp->next = freelist; - fp->id = n; - freelist = fp; + /* skip over expired news */ + expiry_time = time(NULL) - days(news_keep_days); + for (i = 0; getnews(i, &news); i++) { + if (news.nws_when == 0 || news.nws_when >= expiry_time) + break; + } + /* news id 0..I-1 have expired */ + CANT_HAPPEN(i > news_tail); + /* no items to delete if I is equal zero */ + if (i == 0) + return; + + /* move unexpired news I.. to 0.., overwriting expired news */ + for (j = 0; getnews(i + j, &news); j++) { + if (news.nws_when == 0) + break; + putnews(j, &news); + } + CANT_HAPPEN(i + j != news_tail); + news_tail = j; + + /* mark slots no longer in use */ + memset(&news, 0, sizeof(news)); + for (k = 0; k < i; k++) + putnews(j + k, &news); + + /* clear cache because moving news invalidated it */ + memset(&cache, 0, sizeof(cache)); } /* - * snoop through the news articles looking - * for articles which have timed out. Only - * called when no free items left. + * Initialize news reporting. + * Must run between open of file EF_NEWS and first nreport(). */ -static void -findfree(void) +void +init_nreport(void) { - time_t oldnewstime; - int n; + int newest_item; struct nwsstr news; - oldnewstime = time(NULL) - days(news_keep_days); - for (n = 0; getnews(n, &news); n++) { - if (news.nws_when < oldnewstime) - addfree(n); - } - if (freelist == 0) { - if (!ef_extend(EF_NEWS, 100)) - return; - findfree(); + for (newest_item = 0; getnews(newest_item, &news); newest_item++) { + if (news.nws_when == 0) + break; } + news_tail = newest_item; } -static int -nextfree(void) -{ - struct free *fp; - int id; - - if (freelist == 0) - findfree(); - if ((fp = freelist) == 0) - return 0; - freelist = fp->next; - id = fp->id; - free(fp); - return id; -} - -#define SLOTS 5 - -struct newscache { - struct nwsstr news; - int id; -}; - +/* + * Look to see if the same message has been generated + * in the last 5 minutes, if so just increment the times + * field instead of creating a new message. + */ static struct newscache * -ncache(time_t now, int actor, int event, int victim, int times) +ncache(int actor, int event, int victim, int times) { - static struct newscache cache[MAXNOC][SLOTS]; register struct newscache *np; int i; int oldslot; time_t oldtime; + time_t now = time(NULL); oldslot = -1; oldtime = 0x7fffffff; @@ -182,17 +189,7 @@ ncache(time_t now, int actor, int event, int victim, int times) np->news.nws_when = now; np->news.nws_vrb = event; np->news.nws_ntm = times; - np->id = nextfree(); + ef_ensure_space(EF_NEWS, news_tail, 100); + np->id = news_tail++; return np; } - -static void -filereport(int actor, int event, int victim, int times) -{ - struct newscache *np; - time_t now; - - time(&now); - np = ncache(now, actor, event, victim, times); - ef_write(EF_NEWS, np->id, (s_char *)&np->news); -} diff --git a/src/lib/update/main.c b/src/lib/update/main.c index a05b3cf3..bfda5a49 100644 --- a/src/lib/update/main.c +++ b/src/lib/update/main.c @@ -201,6 +201,7 @@ update_main(void *unused) ef_flush(EF_PLANE); ef_flush(EF_LAND); delete_old_announcements(); + delete_old_news(); /* Clear all the telegram flags */ for (cn = 0; cn < MAXNOC; cn++) clear_telegram_is_new(cn); diff --git a/src/server/main.c b/src/server/main.c index 51b1c577..f7b511e6 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -309,6 +309,7 @@ start_server(int flags, char *config_file) ef_init(); init_files(); io_init(); + init_nreport(); if (opt_MOB_ACCESS) { /* This fixes up mobility upon restart */