static int lru_ass_sub(LRU *self, PyObject *key, PyObject *value) { int res = 0; Node *node = GET_NODE(self->dict, key); PyErr_Clear(); /* GET_NODE sets an exception on miss. Shut it up. */ if (value) { if (node) { Py_INCREF(value); Py_DECREF(node->value); node->value = value; lru_remove_node(self, node); lru_add_node_at_head(self, node); res = 0; } else { node = PyObject_NEW(Node, &NodeType); node->key = key; node->value = value; node->next = node->prev = NULL; Py_INCREF(key); Py_INCREF(value); res = PUT_NODE(self->dict, key, node); if (res == 0) { if (lru_length(self) > self->size) { lru_delete_last(self); } lru_add_node_at_head(self, node); } } } else { res = PUT_NODE(self->dict, key, NULL); if (res == 0) { assert(node && PyObject_TypeCheck(node, &NodeType)); lru_remove_node(self, node); } } Py_XDECREF(node); return res; }
static void lru_delete_last(LRU *self) { Node* n = self->last; if (!self->last) return; lru_remove_node(self, n); PUT_NODE(self->dict, n->key, NULL); }
sc_addr gen_undirected_graph(sc_session *s, sc_segment *seg, const sc_string &str) { assert(s); assert(seg); // // Разбор входной строки str, описывающей создаваемый граф. // enum {FIRST, RNODES, RNODE, RARCS, RARC} state = FIRST; sc_string buf; typedef std::set<sc_string> vertex_set; vertex_set vertexes; typedef std::set<std::pair<sc_string, sc_string> > edge_set; edge_set edges; std::pair<sc_string, sc_string> edge; #define PUT_NODE() {vertexes.insert(buf); buf.erase();} #define PUT_ARC() {edge.second = buf; buf.erase(); edges.insert(edge);} #define PUT_ARC_BEG() {edge.first = buf; buf.erase();} for (size_t i = 1; i < str.size() - 1; i++) { switch (str[i]) { case '{': if (state == FIRST) { state = RNODE; break; } if(state == RNODES) { state = RARCS; break; } if(state == RARCS) { state = RARC; break; } break; case '}': if(state == RNODE) { PUT_NODE(); state = RNODES; break; } if(state == RARC) { PUT_ARC(); state = RARCS; break; } break; case ',': if(state == RNODE) { PUT_NODE(); break; } if(state == RARC) { PUT_ARC_BEG(); break; } break; default: buf += str[i]; } } #undef PUT_NODE #undef PUT_ARC_BEG #undef PUT_ARC // // Начинаем генерацию графа в sc-памяти // // Отображение, которое позволяет переходить быстро от имени вершины к sc-адресу, // который обозначает данную вершину графа в sc-памяти std::map<sc_string, sc_addr> vertexes_map; sc_addr graph = s->create_el(seg, SC_N_CONST); // Переменная будет хранить sc-адрес знака сгенерированного графа s->gen3_f_a_f(graph_theory::undirected_graph, 0, seg, SC_A_CONST|SC_POS, graph); // Генерация всех узлов графа в sc-памяти. // Пробегаем по всем вершинам графа из STL-множества vertexes // и добавляем их в генерируемый граф с атрибутом "vertex_". for(vertex_set::iterator it = vertexes.begin(); it != vertexes.end(); ++it) { sc_addr vertex = s->create_el(seg, SC_N_CONST); s->set_idtf(vertex, *it); s->gen5_f_a_f_a_f(graph, 0, seg, SC_A_CONST|SC_POS, vertex, 0, seg, SC_A_CONST|SC_POS, graph_theory::vertex_); vertexes_map[*it] = vertex; } // Генерация всех дуг графа в sc-памяти. // Пробегаем по всем ребрам графа из STL-множества edges // и добавляем их в генерируемый граф с атрибутом "edge_". for(edge_set::iterator it = edges.begin(); it != edges.end(); ++it) { sc_addr edge = s->create_el(seg, SC_N_CONST); s->gen5_f_a_f_a_f(graph, 0, seg, SC_A_CONST|SC_POS, edge, 0, seg, SC_A_CONST|SC_POS, graph_theory::edge_); s->gen3_f_a_f(edge, 0, seg, SC_A_CONST|SC_POS, vertexes_map[it->first]); s->gen3_f_a_f(edge, 0, seg, SC_A_CONST|SC_POS, vertexes_map[it->second]); } // Возвращаем из функции sc-адрес сгенерированного графа return graph; }