|
|
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.