wme *add_module_wme( agent *my_agent, Symbol *id, Symbol *attr, Symbol *value ) { slot *my_slot = make_slot( my_agent, id, attr ); wme *w = make_wme( my_agent, id, attr, value, false ); insert_at_head_of_dll( my_slot->wmes, w, next, prev ); add_wme_to_wm( my_agent, w ); return w; }
void pigeonhole::add_slot(boost::regex pt, slot::handler_type h) { _slots.insert(make_slot(pt, h)); }
bool add_preference_to_tm(agent* thisAgent, preference* pref) { slot* s = make_slot(thisAgent, pref->id, pref->attr); preference* p2; if (!thisAgent->Decider->settings[DECIDER_KEEP_TOP_OPREFS] && (pref->inst->match_goal == thisAgent->top_state) && pref->o_supported && !s->isa_context_slot && (pref->type == ACCEPTABLE_PREFERENCE_TYPE) ) { /* We could potentially cache a list of all o-supported values in the slot so that we don't have to iterate * through all of the preferences. We would need to maintain the list as we decide non-context slots */ bool already_top_o_supported = false; for (p2 = s->all_preferences; (p2 && !already_top_o_supported); p2 = p2->all_of_slot_next) { if ((p2->value == pref->value) && p2->o_supported && (p2->inst->match_goal == thisAgent->top_state)) { already_top_o_supported = true; } } if (already_top_o_supported) { if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { thisAgent->outputManager->printa_sf(thisAgent, "%e+ "); print_preference(thisAgent, pref, false); thisAgent->outputManager->printa_sf(thisAgent, " (%y) ALREADY SUPPORTED ON TOP LEVEL. IGNORING.\n", pref->inst->prod_name); } return false; } } pref->slot = s; insert_at_head_of_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev); /* add to preference list of slot (according to match goal level of the instantiations) */ if (!s->preferences[pref->type]) { /* this is the only pref. of its type, just put it at the head */ insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev); } else if (s->preferences[pref->type]->inst->match_goal_level >= pref->inst->match_goal_level) { /* it belongs at the head of the list, so put it there */ insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev); } else { /* scan through the pref. list, find the one to insert after */ for (p2 = s->preferences[pref->type]; p2->next != NIL; p2 = p2->next) { if (p2->next->inst->match_goal_level >= pref->inst->match_goal_level) { break; } } /* insert pref after p2 */ pref->next = p2->next; pref->prev = p2; p2->next = pref; if (pref->next) { pref->next->prev = pref; } } pref->in_tm = true; preference_add_ref(pref); /* If the slot is unchanged but has some references laying around, we clear them * This does not lead to immediate memory deallocate/allocate but once the WMEs are * resolved, this should free the memory. */ if (wma_enabled(thisAgent) && !s->isa_context_slot) { if (!s->changed) { if (s->wma_val_references != NIL) { s->wma_val_references->clear(); } } } mark_slot_as_changed(thisAgent, s); if (wma_enabled(thisAgent) && !s->isa_context_slot) { bool exists = false; wme* w = pref->slot->wmes; while (!exists && w) { if (w->value == pref->value) { exists = true; } w = w->next; } /* If wme exists, it should already have been updated during assertion of new preferences */ if (!exists) { if (s->wma_val_references == NIL) { thisAgent->memoryManager->allocate_with_pool(MP_wma_slot_refs, &(s->wma_val_references)); #ifdef USE_MEM_POOL_ALLOCATORS s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map(std::less< Symbol* >(), soar_module::soar_memory_pool_allocator< std::pair< Symbol*, uint64_t > >()); #else s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map(); #endif } (*s->wma_val_references)[ pref->value ]++; } } /* update identifier levels */ if (pref->value->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_addition(thisAgent, pref->id, pref->value); } if (preference_is_binary(pref->type)) { if (pref->referent->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_addition(thisAgent, pref->id, pref->referent); } } /* if acceptable/require pref for context slot, we may need to add a wme later */ if ((s->isa_context_slot) && ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE))) { mark_context_slot_as_acceptable_preference_changed(thisAgent, s); } if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { thisAgent->outputManager->printa_sf(thisAgent, "%e+ "); print_preference(thisAgent, pref, false); thisAgent->outputManager->printa_sf(thisAgent, " (%y)\n", pref->inst->prod_name); } return true; }
static inline zend_bool apc_cache_insert_internal(apc_cache_t* cache, apc_cache_key_t *key, apc_cache_entry_t* value, apc_context_t* ctxt, time_t t, zend_bool exclusive) { /* at least */ if (!value) { return 0; } /* check we are able to deal with this request */ if (!cache || apc_cache_busy(cache)) { return 0; } /* process deleted list */ apc_cache_gc(cache); /* make the insertion */ { apc_cache_slot_t** slot; /* * select appropriate slot ... */ slot = &cache->slots[ZSTR_HASH(key->str) % cache->nslots]; while (*slot) { /* check for a match by hash and string */ if ((ZSTR_HASH((*slot)->key.str) == ZSTR_HASH(key->str)) && memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key->str), ZSTR_LEN(key->str)) == SUCCESS) { /* * At this point we have found the user cache entry. If we are doing * an exclusive insert (apc_add) we are going to bail right away if * the user entry already exists and it has no ttl, or * there is a ttl and the entry has not timed out yet. */ if(exclusive) { if (!(*slot)->value->ttl || (time_t) ((*slot)->ctime + (*slot)->value->ttl) >= t) { return 0; } } apc_cache_remove_slot(cache, slot); break; } else /* * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of * slot entries so we don't always have to skip past a bunch of stale entries. We check * for staleness here and get rid of them by first checking to see if the cache has a global * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl */ if((cache->ttl && (time_t)(*slot)->atime < (t - (time_t)cache->ttl)) || ((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t)) { apc_cache_remove_slot(cache, slot); continue; } /* set next slot */ slot = &(*slot)->next; } if ((*slot = make_slot(cache, key, value, *slot, t)) != NULL) { /* set value size from pool size */ value->mem_size = ctxt->pool->size; cache->header->mem_size += ctxt->pool->size; cache->header->nentries++; cache->header->ninserts++; } else { return 0; } } return 1; }