/* * feeddb.c Copyright 1999 Christopher M Sedore. All Rights Reserved. * Please see the "COPYING" file for license details. * * Implements a simple mmapped circular feed database. */ #include "main.h" struct feeddbheader { int cycles; int curoffset; int feedOffset[MAX_FEEDS]; int feedCycle[MAX_FEEDS]; unsigned int serial; int unused[13]; }; #define curFeedOffset feedDBHeader->curoffset int feedDataSize=0; char *feedDB; struct feeddbheader *feedDBHeader; int ffeeddb; int FeedDBInit() { char datapath[MAX_PATH]; sprintf(datapath,"%s/feed.dat",GetConfigString("FeedDataPath")); GetConfigInt("FeedDataSize",&feedDataSize); ffeeddb=open(datapath,O_RDWR|O_CREAT); if (ffeeddb<0) { printf("could not open feed data file %s\n",datapath); exit(1); } feedDB=mmap(NULL,feedDataSize, PROT_READ|PROT_WRITE,MAP_SHARED,ffeeddb,0); if (feedDB==NULL) { printf("could not map table file\n"); exit(1); } feedDBHeader=(struct feeddbheader *)feedDB; feedDB+=sizeof(struct feeddbheader); } int FeedDBShutdown() { munmap(feedDBHeader,feedDataSize); close(ffeeddb); } int FeedDBRecord(struct article *art,u_quad_t key) { struct artent *ae; int x=MAX_FEEDS / 32; ae=(struct artent *) &feedDB[curFeedOffset]; // printf("offset=%u,ae=%p\n",curFeedOffset,ae); bzero(ae,sizeof(struct artent)); assert((void *) ae< (void *)feedDB+(feedDataSize-(sizeof(struct feeddbheader) + 255 + 50))); assert(*art->mid=='<'); ae->magic=ARTENTRY_MAGIC; ae->artlen=art->len; ae->key=key; strcpy(&ae->mid[0],art->mid); ae->length=strlen(ae->mid); ae->serial=feedDBHeader->serial++; while (x--) { ae->siteflags[x]=art->distflags[x]; } assert(*ae->mid=='<'); curFeedOffset+=(ae->length+sizeof(struct artent)); if (curFeedOffset>=feedDataSize-(sizeof(struct feeddbheader) + MAX_ARTICLEID+50)) { curFeedOffset=0; feedDBHeader->cycles++; printf("feed db wrap\n"); } } #define myoffset(x) feedDBHeader->feedOffset[x] #define mycycles(x) feedDBHeader->feedCycle[x] void FeedFlagSite(unsigned int num,unsigned int *fl) { int x,y; assert(numfeedDB); assert((char *)aefeedDataSize-(sizeof(struct feeddbheader) + 50 + MAX_ARTICLEID)) { mycycles(num)=feedDBHeader->cycles; myoffset(num)=0; printf("adjust wrap\n"); } if (myoffset(num)>curFeedOffset) { if (mycycles(num)!=feedDBHeader->cycles-1) { mycycles(num)=feedDBHeader->cycles-1; myoffset(num)=curFeedOffset+(1024*300); printf("adjust gtfo/cyc!=\n"); } } if ((mycycles(num)>feedDBHeader->cycles) || (mycycles(num)cycles-1)) { mycycles(num)=feedDBHeader->cycles; myoffset(num)=curFeedOffset; printf("adjust cyc oor\n"); } p=&feedDB[myoffset(num)]; if (mycycles(num)==feedDBHeader->cycles) { if (curFeedOffset<=myoffset(num)) { myoffset(num)=curFeedOffset; // printf("feed caught up\n"); return x; } } while (1) { ae=(struct artent *) p; if (ae->magic==ARTENTRY_MAGIC) { if (feedDBHeader->serial-ae->serialsiteflags)) { pae[x++]=ae; // printf("found %s\n",ae->mid); if (x==numarticles) { p+=ae->length + sizeof(struct artent); myoffset(num)=p-feedDB; return x; } } else { // putchar('!'); } } p+=ae->length + sizeof(struct artent); } else { p++; putchar('.'); } if (p-feedDB> feedDataSize-(MAX_ARTICLEID+50+sizeof(struct feeddbheader))) { p=feedDB; mycycles(num)=feedDBHeader->cycles; printf("feed wrap\n"); myoffset(num)=0; continue; } if (mycycles(num)==feedDBHeader->cycles) { if (curFeedOffset<=p-feedDB) { myoffset(num)=curFeedOffset; // printf("feed caught up\n"); return x; } } } } #ifdef STDEBUG static int y=500; int GetEm() { char buf[300]; u_quad_t key; struct artent *ae; while (y<50000) { if (!FeedDBGetArticles(10,1,&ae)) { printf("none to get (y=%u)\n",y); return; } sprintf(buf,"",y,y%123); key=0xFEFE1BAD; key=key<<32; key|=y; if (strcmp(buf,ae->mid)) { printf("mismatch %s should be %s\n",ae->mid,buf); } if (key!=ae->key) { printf("key mismatch\n"); } if (ae->artlen!=y) { printf("length mismatch\n"); } y++; } } int main(int argc, char **argv) { char buf[1024]; struct article art; int x=500; u_quad_t key; read_config("config"); FeedDBInit(); while (x<50000) { art.len=x; sprintf(art.mid,"",x,x%123); FeedFlagSite(10,art.distflags); key=0xFEFE1BAD; key=key<<32; key|=x; FeedDBRecord(&art,key); x++; if (!(x%50)) GetEm(); } } #endif