/* * store.c Copyright 1999 Christopher M Sedore. All Rights Reserved. * Please see the "COPYING" file for license information. * * Implement cyclical article stores. */ #include "main.h" #define MAX_ART_STORES 255 #define MAX_ART_STORE_SIZE 100*1024 struct artstore { int size; int metafd,storefd; int flags; off_t offset; unsigned char cycles; char *diststr; void *dist; }; struct artstore storeArray[MAX_ART_STORES]; extern time_t curtime; time_t lastsync=0; #define STORE_INUSE 0x01 #define IS_VALIDSTORE(num) ((num>-1) && (numMAX_ART_STORE_SIZE) { return -1; } sprintf(s,"%s/%u.meta",path,num); f=open(s,O_RDWR|O_CREAT,0700); if (f<0) { printf("Error opening %s/%u.meta",path,num); return -1; } bzero(&cb,sizeof(struct myaiocb)); cb.cb.aio_fildes=f; cb.cb.aio_buf=&storeArray[num]; cb.cb.aio_nbytes=sizeof(struct artstore); cb.cb.aio_offset=0; cb.callback=NULL; if (aio_read((struct aiocb *)&cb)<0) { perror("read"); exit(1); } if (aio_waitcomplete((struct aiocb **)&pcb,NULL)<0) { perror("susp"); exit(1); } storeArray[num].metafd=f; storeArray[num].size=size; sprintf(s,"%s/%u.data",path,num); f=open(s,O_RDWR|O_CREAT,0700); if (f<0) { close(storeArray[num].metafd); printf("Error opening %s/%u.data",path,num); return -1; } storeArray[num].storefd=f; storeArray[num].flags|=STORE_INUSE; if ((dist) && (strlen(dist))) { storeArray[num].dist=CompileMatchString(dist); } else { storeArray[num].dist=NULL; } return 0; } u_quad_t GetStoreKey(int store) { u_quad_t key; int base; if (!IS_STOREINUSE(store)) { return 0; } base=storeArray[store].cycles<<8; base|=store&0xFF; key=base; key=key<<40; key|=storeArray[store].offset; return key; } void StoreSync() { int x=0; while (xmax) { storeArray[store].offset=1; storeArray[store].cycles++; if (storeArray[store].cycles>255) storeArray[store].cycles=0; printf("store wrap\n"); } time(&curtime); if (curtime>lastsync+30) { StoreSync(); lastsync=curtime; } } int WriteToStore(int store,u_quad_t *key,struct myaiocb *cb) { u_quad_t mkey; mkey=GetStoreKey(store); if (!mkey) return -1; *key=mkey; cb->cb.aio_fildes=storeArray[store].storefd; cb->cb.aio_offset=storeArray[store].offset; storeArray[store].offset+=cb->cb.aio_nbytes; if (aio_write((struct aiocb *)cb)) { return -1; } return 0; } int DecipherKey(u_quad_t key, int *store, off_t *offset) { int cycles; *offset=key&0xFFFFFFFFFFLL; key=key>>40; cycles=key&0xFFFF; cycles=cycles>>8; *store=key&0xFF; if (IS_STOREINUSE(*store)) { if (storeArray[*store].cyclescycles+1) return -1; if ((storeArray[*store].cycles==((cycles+1)&0xFF)) && ((storeArray[*store].offset+50*1024*1024)>*offset)) return -1; if ((storeArray[*store].cycles==((cycles+1)&0xFF)) && ((storeArray[*store].offset+50*1024*1024)<*offset)) return 0; if (storeArray[*store].offset>*offset) return 0; } return -1; } int GetFromStore(u_quad_t key,struct myaiocb *cb) { int store; off_t off; if (DecipherKey(key,&store,&off)) { return -1; } cb->cb.aio_fildes=storeArray[store].storefd; cb->cb.aio_offset=off; if (aio_read((struct aiocb *)cb)) { perror("GetFromStore"); return -1; } return 0; } void * MapFromStore(u_quad_t key,int len) { int store; off_t off; void *addr; if (DecipherKey(key,&store,&off)) { return NULL; } addr=mmap(NULL,len,PROT_READ,0,storeArray[store].storefd,off); return addr; } int UnMapStore(void *addr, int len) { munmap(addr,len); } int FindStore(struct article *art) { int x; for (x=0;x