(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.
This commit is contained in:
Ron Koenderink 2005-03-02 23:53:10 +00:00
parent 55e6aca9e0
commit 3d3d6755aa
4 changed files with 80 additions and 79 deletions

View file

@ -546,6 +546,8 @@ extern int natarg(s_char *, s_char *);
/* neigh.c */ /* neigh.c */
extern int neigh(coord, coord, natid); extern int neigh(coord, coord, natid);
/* nreport.c */ /* nreport.c */
extern void delete_old_news();
extern void init_nreport();
extern void nreport(natid, int, natid, int); extern void nreport(natid, int, natid, int);
/* nuke.c */ /* nuke.c */
extern int nuk_postread(int, s_char *); extern int nuk_postread(int, s_char *);

View file

@ -32,25 +32,35 @@
* Steve McClure, 1997 * Steve McClure, 1997
*/ */
#include "misc.h"
#include "news.h"
#include "nat.h"
#include "file.h"
#include "empio.h"
#include <fcntl.h>
#include "optlist.h"
#include "prototypes.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 void
nreport(natid actor, int event, natid victim, int times) nreport(natid actor, int event, natid victim, int times)
{ {
int nice; int nice;
int rel; 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 * this is probably pretty expensive, but hopefully we
* don't fire zillions of these things off every second. * don't fire zillions of these things off every second.
@ -65,9 +75,9 @@ nreport(natid actor, int event, natid victim, int times)
return; return;
if (!chance((double)-nice * times / 20.0)) if (!chance((double)-nice * times / 20.0))
return; return;
if ((np = getnatp(victim)) == 0) if ((natp = getnatp(victim)) == 0)
return; return;
if ((rel = getrel(np, actor)) < HOSTILE) if ((rel = getrel(natp, actor)) < HOSTILE)
return; return;
rel = HOSTILE; rel = HOSTILE;
@ -80,79 +90,76 @@ nreport(natid actor, int event, natid victim, int times)
setrel(victim, actor, rel); setrel(victim, actor, rel);
} }
struct free { /*
struct free *next; * Delete news articles that have expired.
int id; */
}; void
delete_old_news(void)
struct free *freelist;
static void
addfree(int n)
{ {
struct free *fp; time_t expiry_time;
int i, j, k;
struct nwsstr news;
fp = (struct free *)malloc(sizeof(*fp)); /* skip over expired news */
fp->next = freelist; expiry_time = time(NULL) - days(news_keep_days);
fp->id = n; for (i = 0; getnews(i, &news); i++) {
freelist = fp; 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 * Initialize news reporting.
* for articles which have timed out. Only * Must run between open of file EF_NEWS and first nreport().
* called when no free items left.
*/ */
static void void
findfree(void) init_nreport(void)
{ {
time_t oldnewstime; int newest_item;
int n;
struct nwsstr news; struct nwsstr news;
oldnewstime = time(NULL) - days(news_keep_days); for (newest_item = 0; getnews(newest_item, &news); newest_item++) {
for (n = 0; getnews(n, &news); n++) { if (news.nws_when == 0)
if (news.nws_when < oldnewstime) break;
addfree(n);
}
if (freelist == 0) {
if (!ef_extend(EF_NEWS, 100))
return;
findfree();
} }
news_tail = newest_item;
} }
static int /*
nextfree(void) * Look to see if the same message has been generated
{ * in the last 5 minutes, if so just increment the times
struct free *fp; * field instead of creating a new message.
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;
};
static struct newscache * 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; register struct newscache *np;
int i; int i;
int oldslot; int oldslot;
time_t oldtime; time_t oldtime;
time_t now = time(NULL);
oldslot = -1; oldslot = -1;
oldtime = 0x7fffffff; 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_when = now;
np->news.nws_vrb = event; np->news.nws_vrb = event;
np->news.nws_ntm = times; np->news.nws_ntm = times;
np->id = nextfree(); ef_ensure_space(EF_NEWS, news_tail, 100);
np->id = news_tail++;
return np; 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);
}

View file

@ -201,6 +201,7 @@ update_main(void *unused)
ef_flush(EF_PLANE); ef_flush(EF_PLANE);
ef_flush(EF_LAND); ef_flush(EF_LAND);
delete_old_announcements(); delete_old_announcements();
delete_old_news();
/* Clear all the telegram flags */ /* Clear all the telegram flags */
for (cn = 0; cn < MAXNOC; cn++) for (cn = 0; cn < MAXNOC; cn++)
clear_telegram_is_new(cn); clear_telegram_is_new(cn);

View file

@ -309,6 +309,7 @@ start_server(int flags, char *config_file)
ef_init(); ef_init();
init_files(); init_files();
io_init(); io_init();
init_nreport();
if (opt_MOB_ACCESS) { if (opt_MOB_ACCESS) {
/* This fixes up mobility upon restart */ /* This fixes up mobility upon restart */