Rev 11125 | Rev 15847 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 1 | /* Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
16 | */ |
||
17 | |||
8155 | bpr | 18 | /* Caches and its management */ |
10 | reyssat | 19 | |
8185 | bpr | 20 | #include "wimslogd.h" |
10 | reyssat | 21 | |
8185 | bpr | 22 | struct classdata classdata[MAX_CLASSCACHE]; |
10 | reyssat | 23 | |
24 | struct classcache { |
||
12474 | bpr | 25 | struct classdata *ptr; |
10 | reyssat | 26 | } classcache[MAX_CLASSCACHE]; |
27 | int classcaches; |
||
28 | |||
29 | struct sheetdata { |
||
12474 | bpr | 30 | char buffer[SHEETBUFLEN]; |
31 | int name,header,status,exocnt,exo[MAX_EXOS]; |
||
32 | time_t start, last; |
||
33 | int access; |
||
10 | reyssat | 34 | } sheetdata[MAX_SHEETCACHE]; |
35 | |||
36 | struct sheetcache { |
||
12474 | bpr | 37 | struct sheetdata *ptr; |
10 | reyssat | 38 | } sheetcache[MAX_SHEETCACHE]; |
39 | int sheetcaches; |
||
40 | |||
8155 | bpr | 41 | /* searches a list. Returns index if found, -1 if nomatch. |
42 | * Uses binary search, list must be sorted. |
||
43 | */ |
||
10 | reyssat | 44 | int search_data(void *list, int items, size_t item_size, unsigned short int t) |
45 | { |
||
12474 | bpr | 46 | int i1,i2,j,k; |
47 | unsigned short int *p; |
||
8155 | bpr | 48 | |
12474 | bpr | 49 | if(items<=0) return -1; |
50 | j=0; p=list; k=*p-t; |
||
51 | if(k==0) return k; |
||
52 | if(k>0) return -1; |
||
53 | p=list+(items-1)*item_size; |
||
54 | k=*p-t; if(k==0) return items-1; if(k<0) return ~items; |
||
55 | for(i1=0,i2=items-1;i2>i1+1;) { |
||
56 | j=(i2+i1)/2; |
||
57 | p=list+(j*item_size); |
||
58 | k=*p-t; |
||
59 | if(k==0) return j; |
||
60 | if(k>0) {i2=j; continue;} |
||
61 | if(k<0) {i1=j; continue;} |
||
62 | } |
||
63 | return ~i2; |
||
10 | reyssat | 64 | } |
65 | |||
8155 | bpr | 66 | /* remove old cache items */ |
10 | reyssat | 67 | void cleancache(void) |
68 | { |
||
12474 | bpr | 69 | int i; |
70 | time_t now; |
||
71 | struct classdata *cd; |
||
72 | struct sheetdata *sd; |
||
73 | now=time(NULL); |
||
74 | for(i=0;i<classcaches;i++) { |
||
75 | cd=classcache[i].ptr; |
||
76 | if(now<cd->start+CLASSCACHE_DELAY) continue; |
||
77 | cd->access=0; |
||
78 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
||
79 | classcaches--; |
||
80 | } |
||
81 | for(i=0;i<sheetcaches;i++) { |
||
82 | sd=sheetcache[i].ptr; |
||
83 | if(now<sd->start+SHEETCACHE_DELAY) continue; |
||
84 | sd->access=0; |
||
85 | memmove(sheetcache+i,sheetcache+i+1,(sheetcaches-i-1)*sizeof(sheetcache[0])); |
||
86 | sheetcaches--; |
||
87 | } |
||
10 | reyssat | 88 | } |
89 | |||
8155 | bpr | 90 | /* Locate the cache number of a class */ |
10 | reyssat | 91 | struct classdata *getclasscache(char *cl) |
92 | { |
||
12474 | bpr | 93 | int i,j,k,l,m,n, oldest; |
94 | struct stat st; |
||
95 | struct classdata *cd; |
||
96 | char buf[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
||
97 | char *p1, *p2, *q1, *q2; |
||
98 | time_t tt; |
||
99 | tt=0, oldest=0; |
||
100 | for(i=0;i<classcaches;i++) { |
||
101 | cd=classcache[i].ptr; |
||
102 | if(tt>cd->start) {tt=cd->start; oldest=i;} |
||
103 | if(strcmp(cd->name,cl)==0) { |
||
104 | cd->access++; |
||
105 | return cd; |
||
10 | reyssat | 106 | } |
12474 | bpr | 107 | } |
108 | if(classcaches>=MAX_CLASSCACHE) { |
||
109 | i=oldest;cd=classcache[i].ptr; |
||
110 | cd->access=0; |
||
111 | memmove(classcache+i,classcache+i+1,(classcaches-i-1)*sizeof(classcache[0])); |
||
112 | classcaches--; |
||
113 | } |
||
114 | for(i=0;i<MAX_CLASSCACHE && classdata[i].access>0; i++); |
||
115 | if(i>classcaches) return NULL; |
||
116 | cd=classdata+i; cd->access=1; |
||
117 | classcache[classcaches++].ptr=cd; |
||
118 | snprintf(cd->name,sizeof(cd->name),"%s",cl); |
||
119 | cd->start=time(NULL); cd->exocnt=0; |
||
120 | /* Now get the exo data */ |
||
121 | wlogdaccessfile(buf,"r","sheets/.require"); |
||
122 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
||
123 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
124 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
||
125 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
126 | cd->exos[k].num=(i<<8)+j;cd->exos[k].require=atof(q1); |
||
127 | cd->exos[k].weight=0; |
||
128 | k++; |
||
10 | reyssat | 129 | } |
12474 | bpr | 130 | } |
131 | if(k>=MAX_CLASSEXOS) return NULL; |
||
132 | cd->exocnt=k; cd->examstart=k; cd->modif=0; |
||
133 | wlogdaccessfile(buf,"r","sheets/.weight"); |
||
134 | for(i=k=0,p1=buf; *p1; i++,p1=p2) { |
||
135 | p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1); |
||
136 | for(j=0,q1=find_word_start(p1); *q1 && k<MAX_CLASSEXOS; j++,q1=find_word_start(q2)) { |
||
137 | q2=find_word_end(q1); if(*q2) *q2++=0; |
||
138 | if(cd->exos[k].num==(i<<8)+j) { |
||
139 | cd->exos[k].weight=atof(q1); |
||
140 | k++; |
||
8849 | bpr | 141 | } |
12474 | bpr | 142 | else while(k<cd->exocnt && cd->exos[k].num<(i<<8)+j) k++; |
10 | reyssat | 143 | } |
12474 | bpr | 144 | } |
145 | if(stat("exams/.exams",&st)==0) cd->modif=st.st_mtime; else return cd; |
||
146 | wlogdaccessfile(buf,"r","exams/.exams"); |
||
147 | if(buf[0]==0) return cd; |
||
148 | if(buf[0]==':') p1=buf-1; else p1=strstr(buf,"\n:"); |
||
149 | for(n=m=0,k=cd->exocnt; p1 && k<MAX_CLASSEXOS && m<MAX_EXOS; p1=p2,m++) { |
||
150 | p1+=2; |
||
151 | p2=strstr(p1,"\n:"); if(p2) *p2=0; |
||
152 | // if(*find_word_start(p1)<'1') continue; /* status */ |
||
153 | fnd_line(p1,3,buf2); if(buf2[0]==0) continue; |
||
154 | q1=find_word_start(buf2); q2=find_word_end(q1); |
||
155 | if(*q2) *q2++=0; |
||
156 | q2=find_word_start(q2); *find_word_end(q2)=0; |
||
157 | i=atoi(q1); j=atoi(q2); if(i<=0 || j<=0) continue; |
||
158 | cd->exos[k].num=0xFF00+m; |
||
159 | cd->exos[k].weight=i; cd->exos[k].require=j; /* weight: duration. require: retries */ |
||
160 | fnd_line(p1,6,buf2); q1=find_word_start(buf2); |
||
161 | singlespace(q1); strip_trailing_spaces(q1); |
||
162 | cd->ctptr[k-cd->exocnt]=n; cd->ctbuf[n]=0; |
||
163 | if(n+strlen(q1)>CTBUFLEN-MAX_EXOS-16) *q1=0; /* silent truncation */ |
||
164 | l=strlen(q1)+1; memmove(cd->ctbuf+n,q1,l); n+=l; |
||
165 | k++; |
||
166 | } |
||
167 | cd->examcnt=k-cd->exocnt; cd->exocnt=k; |
||
168 | return cd; |
||
10 | reyssat | 169 | } |
7363 | bpr | 170 | // misprint ?? sheetdata ?? does not seem to be used. |
8155 | bpr | 171 | /* prepare cache for a sheet */ |
10 | reyssat | 172 | struct sheetata *getsheetcache(char *cl, char *sh) |
173 | { |
||
12474 | bpr | 174 | return NULL; |
10 | reyssat | 175 | } |