void GC_Object::SetName(const char *name) { if( CheckFlags(GC_FLAG_OBJECT_NAMED) ) { // // remove old name // assert(g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].count(this)); const string_t &oldName = g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)][this]; assert(g_level->_nameToObjectMap.count(oldName)); g_level->_nameToObjectMap.erase(oldName); g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].erase(this); // this invalidates oldName ref SetFlags(GC_FLAG_OBJECT_NAMED, false); } if( name && *name ) { // // set new name // assert( 0 == g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].count(this) ); assert( 0 == g_level->_nameToObjectMap.count(name) ); g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)][this] = name; g_level->_nameToObjectMap[name] = this; SetFlags(GC_FLAG_OBJECT_NAMED, true); } }
const char* GC_Object::GetName() const { if( CheckFlags(GC_FLAG_OBJECT_NAMED) ) { assert( g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].count(this) ); return g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)][this].c_str(); } return NULL; }
void BrotliEstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask, const uint8_t *data, float *cost) { if (BrotliIsMostlyUTF8(data, pos, mask, len, kMinUTF8Ratio)) { EstimateBitCostsForLiteralsUTF8(pos, len, mask, data, cost); return; } else { size_t histogram[256] = { 0 }; size_t window_half = 2000; size_t in_window = BROTLI_MIN(size_t, window_half, len); /* Bootstrap histogram. */ size_t i; for (i = 0; i < in_window; ++i) { ++histogram[data[(pos + i) & mask]]; } /* Compute bit costs with sliding window. */ for (i = 0; i < len; ++i) { size_t histo; if (i >= window_half) { /* Remove a byte in the past. */ --histogram[data[(pos + i - window_half) & mask]]; --in_window; } if (i + window_half < len) { /* Add a byte in the future. */ ++histogram[data[(pos + i + window_half) & mask]]; ++in_window; } histo = histogram[data[(pos + i) & mask]]; if (histo == 0) { histo = 1; } { double lit_cost = FastLog2(in_window) - FastLog2(histo); lit_cost += 0.029; if (lit_cost < 1.0) { lit_cost *= 0.5; lit_cost += 0.5; } cost[i] = (float)lit_cost; } } } }
void GC_Object::Serialize(SaveFile &f) { assert(0 == _notifyProtectCount); f.Serialize(_flags); // // name // if( CheckFlags(GC_FLAG_OBJECT_NAMED) ) { if( f.loading() ) { string_t name; f.Serialize(name); assert( 0 == g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].count(this) ); assert( 0 == g_level->_nameToObjectMap.count(name) ); g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)][this] = name; g_level->_nameToObjectMap[name] = this; } else { string_t name = GetName(); f.Serialize(name); } } // // events // if( f.loading() ) { DWORD tmp = _flags & GC_FLAG_OBJECT_EVENTS_TS_FIXED; SetFlags(GC_FLAG_OBJECT_EVENTS_TS_FIXED, false); SetEvents(tmp); } // // notifications // size_t count = 0; if( const Notify *n = _firstNotify ) do { count += !n->IsRemoved(); } while( n = n->next ); f.Serialize(count); if( f.loading() ) { assert(NULL == _firstNotify); for( size_t i = 0; i < count; i++ ) { _firstNotify = new Notify(_firstNotify); _firstNotify->Serialize(f); } } else { for( Notify *n = _firstNotify; n; n = n->next ) { if( !n->IsRemoved() ) n->Serialize(f); } } }
static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, const uint8_t *data, float *cost) { /* max_utf8 is 0 (normal ASCII single byte modeling), 1 (for 2-byte UTF-8 modeling), or 2 (for 3-byte UTF-8 modeling). */ const size_t max_utf8 = DecideMultiByteStatsLevel(pos, len, mask, data); size_t histogram[3][256] = { { 0 } }; size_t window_half = 495; size_t in_window = BROTLI_MIN(size_t, window_half, len); size_t in_window_utf8[3] = { 0 }; size_t i; { /* Bootstrap histograms. */ size_t last_c = 0; size_t utf8_pos = 0; for (i = 0; i < in_window; ++i) { size_t c = data[(pos + i) & mask]; ++histogram[utf8_pos][c]; ++in_window_utf8[utf8_pos]; utf8_pos = UTF8Position(last_c, c, max_utf8); last_c = c; } } /* Compute bit costs with sliding window. */ for (i = 0; i < len; ++i) { if (i >= window_half) { /* Remove a byte in the past. */ size_t c = i < window_half + 1 ? 0 : data[(pos + i - window_half - 1) & mask]; size_t last_c = i < window_half + 2 ? 0 : data[(pos + i - window_half - 2) & mask]; size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); --histogram[utf8_pos2][data[(pos + i - window_half) & mask]]; --in_window_utf8[utf8_pos2]; } if (i + window_half < len) { /* Add a byte in the future. */ size_t c = data[(pos + i + window_half - 1) & mask]; size_t last_c = data[(pos + i + window_half - 2) & mask]; size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); ++histogram[utf8_pos2][data[(pos + i + window_half) & mask]]; ++in_window_utf8[utf8_pos2]; } { size_t c = i < 1 ? 0 : data[(pos + i - 1) & mask]; size_t last_c = i < 2 ? 0 : data[(pos + i - 2) & mask]; size_t utf8_pos = UTF8Position(last_c, c, max_utf8); size_t masked_pos = (pos + i) & mask; size_t histo = histogram[utf8_pos][data[masked_pos]]; double lit_cost; if (histo == 0) { histo = 1; } lit_cost = FastLog2(in_window_utf8[utf8_pos]) - FastLog2(histo); lit_cost += 0.02905; if (lit_cost < 1.0) { lit_cost *= 0.5; lit_cost += 0.5; } /* Make the first bytes more expensive -- seems to help, not sure why. Perhaps because the entropy source is changing its properties rapidly in the beginning of the file, perhaps because the beginning of the data is a statistical "anomaly". */ if (i < 2000) { lit_cost += 0.7 - ((double)(2000 - i) / 2000.0 * 0.35); } cost[i] = (float)lit_cost; } } }
static BROTLI_INLINE double BitCost(size_t count) { return count == 0 ? -2.0 : FastLog2(count); }
/* Returns entropy reduction of the context map when we combine two clusters. */ static BROTLI_INLINE double ClusterCostDiff(size_t size_a, size_t size_b) { size_t size_c = size_a + size_b; return (double)size_a * FastLog2(size_a) + (double)size_b * FastLog2(size_b) - (double)size_c * FastLog2(size_c); }