86 #include "model_base.h"
89 using namespace std::chrono;
90 using namespace r_code;
94 uint32 ModelBase::MEntry::_ComputeHashCode(_Fact *component) {
97 if (component->is_fact())
98 hash_code = 0x00000000;
100 hash_code = 0x00002000;
101 Code *payload = component->get_reference(0);
102 Atom head = payload->code(0);
103 uint16 opcode = head.asOpcode();
104 switch (head.getDescriptor()) {
106 if (opcode == Opcodes::Cmd) {
108 hash_code |= 0x00000800;
109 hash_code |= (payload->code(CMD_FUNCTION).asOpcode() & 0x000003FF);
110 }
else if (opcode == Opcodes::IMdl) {
112 hash_code |= 0x00000C00;
113 hash_code |= (((uint32)payload->get_reference(0)) & 0x000003FF);
114 }
else if (opcode == Opcodes::ICst) {
116 hash_code |= 0x00001000;
117 hash_code |= (((uint32)payload->get_reference(0)) & 0x000003FF);
119 hash_code |= (opcode & 0x000003FF);
122 hash_code |= 0x00000400;
123 hash_code |= (opcode & 0x000003FF);
130 uint32 ModelBase::MEntry::ComputeHashCode(
Code *mdl,
bool packed) {
132 uint32 hash_code = (mdl->code(mdl->code(HLP_TPL_ARGS).asIndex()).getAtomCount() << 28);
137 Code *unpacked_mdl = mdl->get_reference(mdl->references_size() - MDL_HIDDEN_REFS);
138 lhs = (_Fact *)unpacked_mdl->get_reference(0);
139 rhs = (_Fact *)unpacked_mdl->get_reference(1);
142 lhs = (_Fact *)mdl->get_reference(0);
143 rhs = (_Fact *)mdl->get_reference(1);
145 hash_code |= (_ComputeHashCode(lhs) << 14);
146 hash_code |= _ComputeHashCode(rhs);
150 bool ModelBase::MEntry::Match(
Code *lhs,
Code *rhs) {
152 if (lhs->code(0).asOpcode() == Opcodes::Ent || rhs->code(0).asOpcode() == Opcodes::Ent)
154 if (lhs->code(0).asOpcode() == Opcodes::Ont || rhs->code(0).asOpcode() == Opcodes::Ont)
156 if (lhs->code_size() != rhs->code_size())
158 if (lhs->references_size() != rhs->references_size())
160 for (uint16 i = 0; i < lhs->code_size(); ++i) {
162 if (lhs->code(i) != rhs->code(i))
165 for (uint16 i = 0; i < lhs->references_size(); ++i) {
167 if (!Match(lhs->get_reference(i), rhs->get_reference(i)))
173 ModelBase::MEntry::MEntry() : mdl_(NULL), packed_(false), touch_time_(seconds(0)), hash_code_(0) {
176 ModelBase::MEntry::MEntry(
Code *mdl,
bool packed) : mdl_(mdl), packed_(packed), touch_time_(Now()), hash_code_(ComputeHashCode(mdl, packed)) {
179 bool ModelBase::MEntry::match(
const MEntry &e)
const {
185 Code* mdl_0 = (packed_ ? mdl_->get_reference(mdl_->references_size() - MDL_HIDDEN_REFS) : (
Code*)mdl_);
186 Code* mdl_1 = (e.packed_ ? e.mdl_->get_reference(e.mdl_->references_size() - MDL_HIDDEN_REFS) : (
Code*)e.mdl_);
188 if (mdl_0->code_size() != mdl_1->code_size())
190 for (uint16 i = 0; i < mdl_0->code_size(); ++i) {
192 if (i == MDL_STRENGTH || i == MDL_CNT || i == MDL_SR || i == MDL_DSR || i == MDL_ARITY)
195 if (mdl_0->code(i) != mdl_1->code(i))
199 Code* f_lhs_0 = mdl_0->get_reference(0);
200 Code* f_lhs_1 = mdl_1->get_reference(0);
201 if (f_lhs_0->references_size() < 1)
203 if (f_lhs_1->references_size() < 1)
206 if (f_lhs_0->code(0) != f_lhs_1->code(0))
209 if (!Match(f_lhs_0->get_reference(0), f_lhs_1->get_reference(0)))
212 Code* f_rhs_0 = mdl_0->get_reference(1);
213 Code* f_rhs_1 = mdl_1->get_reference(1);
215 if (f_rhs_0->code(0) != f_rhs_1->code(0))
218 if (!Match(f_rhs_0->get_reference(0), f_rhs_1->get_reference(0)))
226 ModelBase *ModelBase::singleton_ = NULL;
228 ModelBase *ModelBase::Get() {
233 ModelBase::ModelBase() {
238 void ModelBase::trim_objects() {
243 for (m = black_list_.begin(); m != black_list_.end();) {
245 if (now - (*m).touch_time_ >= thz_)
246 m = black_list_.erase(m);
253 void ModelBase::load(
Code *mdl) {
256 if (mdl->views_.size() > 0)
257 white_list_.insert(e);
259 black_list_.insert(e);
266 for (m = white_list_.begin(); m != white_list_.end(); ++m)
267 models.push_back((*m).mdl_);
268 for (m = black_list_.begin(); m != black_list_.end(); ++m)
269 models.push_back((*m).mdl_);
273 Code *ModelBase::check_existence(
Code *mdl) {
275 MEntry e(mdl,
false);
278 MdlSet::iterator m = black_list_.find(e);
282 if (m != black_list_.end()) {
285 copy.touch_time_ = Now();
286 black_list_.erase(*m);
287 black_list_.insert(copy);
293 m = white_list_.find(e);
294 if (m != white_list_.end())
297 copy.touch_time_ = Now();
298 white_list_.erase(*m);
299 white_list_.insert(copy);
305 _Mem::Get()->pack_hlp(e.mdl_);
307 white_list_.insert(e);
312 void ModelBase::check_existence(
Code *m0,
Code *m1,
Code *&_m0,
Code *&_m1) {
314 MEntry e_m0(m0,
false);
317 MdlSet::iterator m = black_list_.find(e_m0);
318 if (m != black_list_.end())
321 copy.touch_time_ = Now();
322 black_list_.erase(*m);
323 black_list_.insert(copy);
330 m = white_list_.find(e_m0);
331 if (m != white_list_.end()) {
334 copy.touch_time_ = Now();
335 white_list_.erase(*m);
336 white_list_.insert(copy);
340 Code *rhs = m1->get_reference(m1->code(m1->code(MDL_OBJS).asIndex() + 2).asIndex());
341 Code *im0 = rhs->get_reference(0);
342 im0->set_reference(0, _m0);
345 MEntry e_m1(m1,
false);
346 m = black_list_.find(e_m1);
347 if (m != black_list_.end()) {
349 copy.touch_time_ = Now();
350 black_list_.erase(*m);
351 black_list_.insert(copy);
358 m = white_list_.find(e_m1);
359 if (m != white_list_.end()) {
361 copy.touch_time_ = Now();
362 white_list_.erase(*m);
363 white_list_.insert(copy);
372 _Mem::Get()->pack_hlp(m0);
374 white_list_.insert(e_m0);
376 _Mem::Get()->pack_hlp(m1);
378 white_list_.insert(e_m1);
383 void ModelBase::register_mdl_failure(
Code *mdl) {
387 white_list_.erase(e);
388 black_list_.insert(e);
392 void ModelBase::register_mdl_timeout(
Code *mdl) {
396 white_list_.erase(e);