/* * Returns true iff */ bool CacheStrategyUtility::isResponsibleForDataObject( DataObjectRef &dObj) { string id = string(dObj->getIdStr()); /* // THIS IS NOT THREAD SAFE!! added getOrigSize // to grab unaltered file size. if (utilMetadata.find(id) != utilMetadata.end()) { return true; } */ if (dObj->isDuplicate()) { return false; } // SW: TODO: NOTE: this might not be the best way to check if it's from // a local application, but it works for now... bool isLocal = dObj->getRemoteInterface() && dObj->getRemoteInterface()->isApplication(); bool notResponsible = dObj->isControlMessage() || dObj->isNodeDescription(); bool isResponsible = !notResponsible; if (!handle_zero_size) { isResponsible = isResponsible && (dObj->getOrigDataLen() > 0); } if (!manage_locally_sent_files) { isResponsible = isResponsible && dObj->isPersistent(); } if (stats_replacement_strat && stats_replacement_strat->isResponsibleForDataObject(dObj)) { isResponsible = true; } else if (manage_only_remote_files) { isResponsible = isResponsible && !isLocal; } return isResponsible; }
/* * Callback when a new data object is inserted. Updates the utility strategy * state and notifies the utility functions. */ void CacheStrategyUtility::_handleNewDataObject( DataObjectRef &dObj) { if (!isResponsibleForDataObject(dObj)) { //HAGGLE_DBG("Ignoring data object, in-eligible for caching\n"); return; } if (stats_replacement_strat && stats_replacement_strat->isResponsibleForDataObject(dObj)) { stats_replacement_strat->handleNewDataObject(dObj); return; } string id = string(dObj->getIdStr()); if (utilMetadata.find(id) != utilMetadata.end()) { // the DO is already in the cache! HAGGLE_DBG("Received data object already in the cache: %s\n", id.c_str()); current_dupe_do_recv++; return; } getUtilityFunction()->notifyInsertion(dObj); int cost = dObj->getOrigDataLen(); // NOTE: we handle zero sized data objects by "faking" // a size of 1. if (cost == 0) { cost = 1; } string strResults=""; if (Trace::trace.getTraceType() == TRACE_TYPE_DEBUG2) { strResults.append(id); strResults.append("[I]="); } double utiltiy = getUtilityFunction()->compute(id, strResults); HAGGLE_DBG2("%s --> %f\n", strResults.c_str(), utiltiy); Timeval now = Timeval::now(); bool purgeNow = false; if (utiltiy < getGlobalOptimizer()->getMinimumThreshold()) { HAGGLE_DBG("Minimum threshold for incoming data object %s is insufficient: %f < %f\n", id.c_str(), utiltiy, getGlobalOptimizer()->getMinimumThreshold()); current_drop_on_insert++; purgeNow = true; } if (!purgeOnInsert && ((current_size + cost) > max_capacity_kb*1024)) { HAGGLE_DBG("Cache is full and purge on insert is disabled, evicting new data object!\n"); purgeNow = true; total_do_hard_evicted++; total_do_hard_evicted_bytes += cost; } if (purgeNow) { // we need to properly remove from bloomfilter even when capacity is violated getUtilityFunction()->notifyDelete(dObj); // CBMEN, HL - Begin // Remove any pending send events for this data object HAGGLE_STAT("purging send events for dObj %s\n", dObj->getIdStr()); getManager()->getKernel()->cancelEvents(EVENT_TYPE_DATAOBJECT_SEND, dObj); // CBMEN, HL, End // delayed delete (although never inserted) if (!keep_in_bloomfilter) { int delay = (bloomfilter_remove_delay_ms <= 0) ? 1000 : bloomfilter_remove_delay_ms; DataObjectId_t *heapId = (DataObjectId_t *)malloc(sizeof(DataObjectId_t)); DataObject::idStrToId(id, *heapId); getManager()->getKernel()->addEvent(new Event(bloomfilterRemoveDelayEventType, heapId, delay/(double)1000)); } return; } DataObjectUtilityMetadata *do_metadata = new DataObjectUtilityMetadata( dObj, id, cost, utiltiy, now, dObj->getCreateTime()); if (purgeOnInsert) { do_metadata->setEnableDeletion(false); } if (false == utilMetadata.insert(make_pair(id, do_metadata)).second) { HAGGLE_ERR("Somehow data object already in cache\n"); delete do_metadata; return; } current_size += cost; current_num_do++; total_do_inserted++; total_do_inserted_bytes += cost; if (!purgeOnInsert) { getManager()->insertDataObjectIntoDataStore(dObj); return; } bool was_deleted = false; _purgeCache(id, &was_deleted); if (was_deleted) { HAGGLE_DBG("Purged incoming data object %s on insert.\n", id.c_str()); current_drop_on_insert++; return; } // DO still in cache, mark to allow deletion in future do_metadata->setEnableDeletion(true); getManager()->insertDataObjectIntoDataStore(dObj); }