|
|
1.1 root 1: #include <pads.pri>
2: SRCFILE("cache.c")
3:
4: static CartesMade, CarteBytes, ItemsMade, ItemBytes;
5:
6: char *CacheStats()
7: {
8: static char report[128];
9:
10: sprintf( report, "terminal: %d Cartes in %d bytes; %d Items in %d bytes",
11: CartesMade, CarteBytes, ItemsMade, ItemBytes );
12: return report;
13: }
14:
15: short Index::sht() { return (major<<8) | minor; }
16:
17: Item::Item(char* t,Action a,long o) { text = t; action = a; opand = o; }
18: Item::Item() { text = "error"; action = 0; opand = 0; }
19:
20: int Cache::ok() { return this!=0; }
21:
22: Cache::Cache( unsigned char maj, unsigned char min )
23: {
24: trace( "%d.Cache(%d,%d)", this, maj, min ); VOK;
25: SIZE = Index(maj,min);
26: current = Index(0,1);
27: }
28:
29: ItemCache::ItemCache():(250,250) /* (250,250) for megabyte term */
30: {
31: trace( "%d.ItemCache()", this ); VOK;
32: cache = new Item** [SIZE.major];
33: ItemBytes += SIZE.major*4; /* term */
34: R->pktstart( P_I_DEFINE );
35: R->sendshort(SIZE.sht());
36: R->pktend();
37: };
38:
39: CarteCache::CarteCache():(250,250) /* (250,250) for megabyte term */
40: {
41: trace( "%d.CarteCache()", this ); VOK;
42: cache = new Carte** [SIZE.major];
43: CarteBytes += SIZE.major*4; /* term */
44: R->pktstart( P_C_DEFINE );
45: R->sendshort(SIZE.sht());
46: R->pktend();
47: };
48:
49: int ItemCmp( Item *a, Item *b )
50: {
51: int cmp = strcmp(a->text,b->text);
52: if( cmp ) return cmp;
53: if( a->action == b->action ) return a->opand - b->opand;
54: return (long)a->action - (long)b->action;
55: }
56:
57: Index ItemCache::place( Item i )
58: {
59: Binary *b, *above;
60: int cmp, size;
61: Item copy;
62:
63: trace( "%d.index(%s,%d,%d)", this, i.text, i.action, i.opand );OK(0);
64: for( b = root; b; above = b, b = cmp < 0 ? b->left : b->right ){
65: cmp = ItemCmp( &i, cache[b->index.major][b->index.minor] );
66: if( cmp == 0 ){
67: trace( "%d:%d", b->index.major, b->index.minor );
68: return b->index;
69: }
70: }
71: b = new Binary;
72: if( !root ) root = b;
73: else if( cmp < 0 ) above->left = b;
74: else above->right = b;
75: if( (size = strlen(i.text)+1) >= SIZE.minor ) abort();
76: trace( "%d %d %d", size, current.minor, size+current.minor );
77: if( size+current.minor >= SIZE.minor ){
78: if( ++current.major >= SIZE.major )
79: abort();
80: current.minor = 0;
81: }
82: if( !cache[current.major] ){
83: trace( "Item alloc %d", current.major );
84: cache[current.major] = new Item* [SIZE.minor];
85: ItemBytes += SIZE.minor; // term
86: }
87: b->index = current;
88: copy = i;
89: copy.text = sf( "%s", i.text);
90: cache[current.major][current.minor] = new Item; // ccom bug
91: *(cache[current.major][current.minor]) = copy; // 860224
92: trace( "%s:%d:%d", copy.text, copy.action, copy.opand );
93: R->pktstart( P_I_CACHE );
94: R->sendshort(current.sht());
95: R->sendstring( sf("%0.64s", copy.text) );
96: R->pktend();
97: ++ItemsMade;
98: current.minor += size;
99: trace( "%s", CacheStats() );
100: trace( "%d:%d", b->index.major, b->index.minor );
101: return b->index;
102: }
103:
104: Item *ItemCache::take(Index i)
105: {
106: trace( "%d.take(%d:%d)", this, i.major, i.minor ); OK(0);
107: if( (i.major&CARTE) || i.major>=SIZE.major
108: || !cache[i.major] || !cache[i.major][i.minor] ) abort();
109: return cache[i.major][i.minor];
110: }
111:
112: int CarteCmp( Carte *a, Carte *b )
113: {
114: int i;
115: IF_LIVE( !a || !b || a->size<=0 || b->size<=0 ) return 0;
116: if( a->size != b->size ) return a->size - b->size;
117: for( i = 0; i <= a->size; ++i )
118: if( a->bin[i].sht() != b->bin[i].sht() )
119: return a->bin[i].sht() - b->bin[i].sht();
120: return 0;
121: }
122:
123: Index CarteCache::place( Carte *c )
124: {
125: Binary *b, *above;
126: int cmp, i;
127: Carte *copy;
128:
129: trace( "%d.place(%d)", this, c ); OK(0);
130: for( b = root; b; above = b, b = cmp < 0 ? b->left : b->right ){
131: cmp = CarteCmp( c, cache[b->index.major][b->index.minor] );
132: if( cmp == 0 ){
133: trace( "%d:%d", b->index.major, b->index.minor );
134: { Index ix = b->index; ix.major|=CARTE; return ix; }
135: }
136: }
137: b = new Binary;
138: if( !root ) root = b;
139: else if( cmp < 0 ) above->left = b;
140: else above->right = b;
141: if( current.minor >= SIZE.minor ){
142: if( ++current.major >= SIZE.major )
143: abort();
144: current.minor = 0;
145: }
146: if( !cache[current.major] ){
147: trace( "Carte alloc %d", current.major );
148: cache[current.major] = new Carte* [SIZE.minor];
149: CarteBytes += SIZE.minor*4; /* term */
150: }
151: b->index = current;
152: cache[current.major][current.minor] = copy =
153: (Carte *) new char [CARTESIZE(c->size)];
154: CarteBytes += c->size*2+4; /* term */
155: *copy = *c;
156: for( i = 0; i <= copy->size; ++i ) copy->bin[i] = c->bin[i];
157: R->pktstart( P_C_CACHE );
158: R->sendshort(current.sht());
159: if( copy->attrib&NUMERIC ) {
160: R->senduchar( 1 );
161: R->senduchar( copy->attrib );
162: R->sendshort( copy->bin[0].sht() );
163: R->sendshort( copy->bin[1].sht() );
164: } else {
165: R->senduchar( copy->size );
166: R->senduchar( copy->attrib );
167: for( i = 0; i <= copy->size; ++i )
168: R->sendshort( copy->bin[i].sht() );
169: }
170: cartelimits(copy);
171: R->senduchar(copy->items);
172: R->senduchar(copy->width);
173: R->pktend();
174: ++CartesMade;
175: ++current.minor;
176: trace( "%s", CacheStats() );
177: trace( "%d:%d", b->index.major, b->index.minor );
178: { Index ix = b->index; ix.major|=CARTE; return ix; }
179: }
180:
181: Carte *CarteCache::take(Index i)
182: {
183: trace( "%d.take(0x%X)", i.sht() ); OK(0);
184: IF_LIVE( !(i.major&CARTE) ) return 0;
185: i.major &= ~CARTE;
186: IF_LIVE(i.major>=SIZE.major || !cache[i.major] || !cache[i.major][i.minor])
187: return 0;
188: return cache[i.major][i.minor];
189: }
190:
191: Index CarteCache::numeric(short lo, short hi)
192: {
193: Index ix;
194: Carte *c;
195:
196: trace( "%d.Carte(%d,%d)", this, lo, hi ); OK(0);
197: IF_LIVE( lo > hi ) return 0;
198: c = (Carte *) new char [CARTESIZE(2)];
199: if( hi > lo+255 ) hi = lo+255;
200: c->size = 2;
201: c->attrib = NUMERIC;
202: c->bin[1] = Index(lo);
203: c->bin[2] = Index(hi);
204: ix = place(c);
205: trace( "%u:%u", ix.major, ix.minor );
206: return ix;
207: }
208:
209: Index NumericRange(short lo, short hi) { return CCache->numeric(lo,hi); }
210:
211: void CarteCache::cartelimits(Carte *c)
212: {
213: trace( "%d.ItemCount(%d)", this, c ); VOK;
214: c->items = c->width = 0;
215: if( c->attrib&NUMERIC ){
216: c->items = c->bin[2].sht() - c->bin[1].sht() + 1;
217: c->width = 5; /* max log10 d ? */
218: return;
219: }
220: for( int j = 1; j <= c->size; ++j ){
221: if( c->bin[j].major&CARTE ){
222: Carte *t = take(c->bin[j]);
223: if( t->bin[0].null() ){
224: c->items += t->items;
225: if( t->width > c->width ) c->width = t->width;
226: } else {
227: ++c->items;
228: int l = strlen(ICache->take(t->bin[0])->text);
229: if( l > c->width ) c->width = l;
230: }
231: } else {
232: ++c->items;
233: int l = strlen(ICache->take(c->bin[j])->text);
234: if( l > c->width ) c->width = l;
235: }
236: }
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.