sctpErrorCode sctpCommand::processCreateNode(quint32 cmdFlags, quint32 cmdId, QDataStream *params, QIODevice *outDevice) { Q_UNUSED(cmdFlags); Q_ASSERT(params != 0); sc_type type; // read type of node READ_PARAM(type); sc_addr addr = sc_memory_node_new(type); // send result sctpErrorCode result; if (SC_ADDR_IS_NOT_EMPTY(addr)) { writeResultHeader(SCTP_CMD_CREATE_NODE, cmdId, SCTP_RESULT_OK, sizeof(addr), outDevice); outDevice->write((const char*)&addr, sizeof(addr)); result = SCTP_ERROR_NO; }else { writeResultHeader(SCTP_CMD_CREATE_NODE, cmdId, SCTP_RESULT_FAIL, 0, outDevice); result = SCTP_ERROR; } return result; }
sctpErrorCode sctpCommand::processCreateArc(quint32 cmdFlags, quint32 cmdId, QDataStream *params, QIODevice *outDevice) { Q_UNUSED(cmdFlags); Q_ASSERT(params != 0); sc_type type; sc_addr begin_addr, end_addr; // read type of sc-arc READ_PARAM(type); // read sc-addr of begin and end elements READ_PARAM(begin_addr); READ_PARAM(end_addr); sc_addr addr = sc_memory_arc_new(type, begin_addr, end_addr); sctpErrorCode result; if (SC_ADDR_IS_NOT_EMPTY(addr)) { writeResultHeader(SCTP_CMD_CREATE_ARC, cmdId, SCTP_RESULT_OK, 0, outDevice); outDevice->write((const char*)&addr, sizeof(addr)); result = SCTP_ERROR_NO; }else { writeResultHeader(SCTP_CMD_CREAET_LINK, cmdId, SCTP_RESULT_FAIL, 0, outDevice); result = SCTP_ERROR; } return result; }
bool TestGraphModify::check_arc_creation() { assert(SC_ADDR_IS_NOT_EMPTY(mGraphAddr)); sc_addr arc, v1, v2; // create if (sc_graph_create_vertex(mGraphAddr, &v1) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v2) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mGraphAddr, v1, v2, &arc) != SC_RESULT_OK) return false; // check if (sc_graph_check_arc(mGraphAddr, arc) != SC_RESULT_OK) return false; sc_iterator5 *it5 = sc_iterator5_f_a_f_a_f_new(v1, sc_type_arc_common | sc_type_const, v2, sc_type_arc_pos_const_perm, mGraphAddr); int count = 0; while (sc_iterator5_next(it5) == SC_TRUE) count++; sc_iterator5_free(it5); return count == 1; }
void sc_iterator3_free(sc_iterator3 *it) { if (it == null_ptr) return; if ((it->finished == SC_FALSE) && SC_ADDR_IS_NOT_EMPTY(it->results[1])) { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->results[1], &el)); g_assert(el != null_ptr); sc_element_itref_dec(sc_storage_get_element_meta(it->ctx, it->results[1])); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->results[1])); } switch (it->type) { case sc_iterator3_f_a_a: _sc_iterator_unref_element_addr(it->ctx, it->params[0].addr); break; case sc_iterator3_a_a_f: _sc_iterator_unref_element_addr(it->ctx, it->params[2].addr); break; case sc_iterator3_f_a_f: _sc_iterator_unref_element_addr(it->ctx, it->params[0].addr); _sc_iterator_unref_element_addr(it->ctx, it->params[2].addr); break; } g_free(it); }
bool TestGraphModify::check_adjacency() { assert(SC_ADDR_IS_NOT_EMPTY(mGraphAddr)); sc_addr v1, v2, v3, arc; if (sc_graph_create_vertex(mGraphAddr, &v1) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v2) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v3) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mGraphAddr, v1, v2, &arc) != SC_RESULT_OK) return false; if (sc_graph_check_elements_adjacency(mGraphAddr, v1, v2) != SC_RESULT_OK) return false; if (sc_graph_check_elements_adjacency(mGraphAddr, v1, v3) == SC_RESULT_OK) return false; if (sc_graph_check_elements_adjacency(mGraphAddr, v2, v3) == SC_RESULT_OK) return false; return true; }
bool TestGraphModify::check_vertex_creation() { assert(SC_ADDR_IS_NOT_EMPTY(mGraphAddr)); sc_addr vertex; if (sc_graph_create_vertex(mGraphAddr, &vertex) != SC_RESULT_OK) return false; // check if vertex created correctly return sc_graph_check_vertex(mGraphAddr, vertex) == SC_RESULT_OK; }
bool TestSearchIncidentArcs::check_search_incident_arcs() { assert(SC_ADDR_IS_NOT_EMPTY(mOrGraphAddr)); sc_addr arc1, arc2, arc3,v1,v2, v3, v4; sc_memory_arc_new(sc_type_arc_pos_const_perm, sc_graph_keynode_oriented_graph, mOrGraphAddr); // create if (sc_graph_create_vertex(mOrGraphAddr, &v1) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mOrGraphAddr, &v2) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mOrGraphAddr, &v3) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mOrGraphAddr, &v4) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mOrGraphAddr, v1, v2, &arc1) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mOrGraphAddr, v1, v3, &arc2) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mOrGraphAddr, v1, v4, &arc3) != SC_RESULT_OK) return false; if(sc_graph_check_arc(mOrGraphAddr,arc1) != SC_RESULT_OK) return false; sc_addr_list *arcc = (sc_addr_list*)nullptr; if (search_incident_vertex_arc(mOrGraphAddr, v1, &arcc) != SC_RESULT_OK) return false; if(!SC_ADDR_IS_EQUAL(arcc->value, arc1)) return false; arcc = sc_addr_list_next(arcc); if(!SC_ADDR_IS_EQUAL(arcc->value, arc2)) return false; arcc = sc_addr_list_next(arcc); if(!SC_ADDR_IS_EQUAL(arcc->value, arc3)) return false; return true; }
bool TestCheckGraphIsDisconnectedGraph::check_graph_is_disconnected_not_or() { assert(SC_ADDR_IS_NOT_EMPTY(mGraphAddrNotOrient)); sc_memory_arc_new(sc_type_arc_pos_const_perm, sc_graph_keynode_not_oriented_graph, mGraphAddrNotOrient); sc_addr vertex1, vertex2, vertex3, vertex4, vertex5; if (sc_graph_create_vertex(mGraphAddrNotOrient, &vertex1) != SC_RESULT_OK) return false; if ( sc_graph_check_vertex(mGraphAddrNotOrient, vertex1) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddrNotOrient, &vertex2) != SC_RESULT_OK) return false; if ( sc_graph_check_vertex(mGraphAddrNotOrient, vertex2) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddrNotOrient, &vertex3) != SC_RESULT_OK) return false; if ( sc_graph_check_vertex(mGraphAddrNotOrient, vertex3) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddrNotOrient, &vertex4) != SC_RESULT_OK) return false; if ( sc_graph_check_vertex(mGraphAddrNotOrient, vertex4) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddrNotOrient, &vertex5) != SC_RESULT_OK) return false; if ( sc_graph_check_vertex(mGraphAddrNotOrient, vertex5) != SC_RESULT_OK) return false; sc_bool check; if(sc_graph_is_disconnected(mGraphAddrNotOrient, &check) != SC_RESULT_OK) return false; else if(check != SC_TRUE) return false; return true; }
void test_save() { // create nodes s_default_ctx = sc_memory_initialize(¶ms); sc_memory_context *ctx = sc_memory_context_new(sc_access_lvl_make(8, 8)); int const count = 1000000; for (int i = 0; i < count; ++i) { g_assert(SC_ADDR_IS_NOT_EMPTY(sc_memory_node_new(ctx, 0))); } sc_memory_context_free(ctx); GThread * thread = g_thread_try_new(0, start_save_threaded, 0, 0); test_creation(create_arc_thread, g_task_count, g_thread_count); g_thread_join(thread); sc_memory_shutdown(SC_FALSE); }
sc_addr SCsTranslator::resolveScAddr(sElement *el) { assert(SC_ADDR_IS_EMPTY(el->addr)); sc_addr addr; SC_ADDR_MAKE_EMPTY(addr); if (!el->idtf.empty()) { // try to find in system identifiers tStringAddrMap::iterator it = mSysIdtfAddrs.find(el->idtf); if (it != mSysIdtfAddrs.end()) { addr = it->second; } else { // try to find in global identifiers it = msGlobalIdtfAddrs.find(el->idtf); if (it != msGlobalIdtfAddrs.end()) addr = it->second; else { // try to find in local identifiers it = mLocalIdtfAddrs.find(el->idtf); if (it != mLocalIdtfAddrs.end()) addr = it->second; else { // resolve system identifier sc_result res = sc_helper_find_element_by_system_identifier(mContext, el->idtf.c_str(), (sc_uint32)el->idtf.size(), &addr); if (res == SC_RESULT_OK) mSysIdtfAddrs[el->idtf] = addr; } } } } if (SC_ADDR_IS_NOT_EMPTY(addr)) { sc_type t = 0; if (sc_memory_get_element_type(mContext, addr, &t) == SC_RESULT_OK) sc_memory_change_element_subtype(mContext, addr, ~sc_type_element_mask & (el->type | t)); el->addr = addr; return addr; } // generate addr addr = createScAddr(el); // store in addrs map if (!el->idtf.empty()) { switch (_getIdentifierVisibility(el->idtf)) { case IdtfSystem: sc_helper_set_system_identifier(mContext, addr, el->idtf.c_str(), (sc_uint32)el->idtf.size()); mSysIdtfAddrs[el->idtf] = addr; break; case IdtfLocal: mLocalIdtfAddrs[el->idtf] = addr; break; case IdtfGlobal: msGlobalIdtfAddrs[el->idtf] = addr; break; } } return addr; }
sc_addr sc_storage_arc_new(sc_type type, sc_addr beg, sc_addr end) { sc_addr addr; sc_element el, *beg_el, *end_el, *tmp_el; #if USE_TWO_ORIENTED_ARC_LIST sc_element *tmp_arc; #endif memset(&el, 0, sizeof(el)); g_assert( !(sc_type_node & type) ); el.type = (type & sc_type_arc_mask) ? type : (sc_type_arc_common | type); el.arc.begin = beg; el.arc.end = end; // get new element tmp_el = sc_storage_append_el_into_segments(&el, &addr); g_assert(tmp_el != 0); // get begin and end elements beg_el = sc_storage_get_element(beg, SC_TRUE); end_el = sc_storage_get_element(end, SC_TRUE); // emit events sc_event_emit(beg, SC_EVENT_ADD_OUTPUT_ARC, addr); sc_event_emit(end, SC_EVENT_ADD_INPUT_ARC, addr); // if (type & sc_type_edge_common) // { // sc_event_emit(end, SC_EVENT_ADD_OUTPUT_ARC, addr); // sc_event_emit(beg, SC_EVENT_ADD_INPUT_ARC, addr); // } // check values g_assert(beg_el != nullptr && end_el != nullptr); g_assert(beg_el->type != 0 && end_el->type != 0); // set next output arc for our created arc tmp_el->arc.next_out_arc = beg_el->first_out_arc; tmp_el->arc.next_in_arc = end_el->first_in_arc; #if USE_TWO_ORIENTED_ARC_LIST if (SC_ADDR_IS_NOT_EMPTY(beg_el->first_out_arc)) { tmp_arc = sc_storage_get_element(beg_el->first_out_arc, SC_TRUE); tmp_arc->arc.prev_out_arc = addr; } if (SC_ADDR_IS_NOT_EMPTY(end_el->first_in_arc)) { tmp_arc = sc_storage_get_element(end_el->first_in_arc, SC_TRUE); tmp_arc->arc.prev_in_arc = addr; } #endif // set our arc as first output/input at begin/end elements beg_el->first_out_arc = addr; end_el->first_in_arc = addr; return addr; }
sc_result sc_storage_element_free(sc_addr addr) { sc_element *el, *el2; sc_addr _addr; sc_uint addr_int; GSList *remove_list = 0; el = el2 = 0; if (sc_storage_is_element(addr) == SC_FALSE) return SC_RESULT_ERROR; if (sc_iterator_has_any_timestamp()) storage_time_stamp++; remove_list = g_slist_append(remove_list, GUINT_TO_POINTER(SC_ADDR_LOCAL_TO_INT(addr))); while (remove_list != 0) { // get sc-addr for removing addr_int = GPOINTER_TO_UINT(remove_list->data); _addr.seg = SC_ADDR_LOCAL_SEG_FROM_INT(addr_int); _addr.offset = SC_ADDR_LOCAL_OFFSET_FROM_INT(addr_int); // go to next sc-addr in list remove_list = g_slist_delete_link(remove_list, remove_list); el = sc_storage_get_element(_addr, SC_TRUE); g_assert(el != 0 && el->type != 0); // remove registered events before deletion sc_event_notify_element_deleted(_addr); el->delete_time_stamp = storage_time_stamp; if (el->type & sc_type_arc_mask) { sc_event_emit(el->arc.begin, SC_EVENT_REMOVE_OUTPUT_ARC, _addr); sc_event_emit(el->arc.end, SC_EVENT_REMOVE_INPUT_ARC, _addr); } // Iterate all connectors for deleted element and append them into remove_list _addr = el->first_out_arc; while (SC_ADDR_IS_NOT_EMPTY(_addr)) { el2 = sc_storage_get_element(_addr, SC_TRUE); // do not append elements, that have delete_time_stamp != 0 if (el2->delete_time_stamp == 0) remove_list = g_slist_append(remove_list, GUINT_TO_POINTER(SC_ADDR_LOCAL_TO_INT(_addr))); _addr = el2->arc.next_out_arc; } _addr = el->first_in_arc; while (SC_ADDR_IS_NOT_EMPTY(_addr)) { el2 = sc_storage_get_element(_addr, SC_TRUE); // do not append elements, that have delete_time_stamp != 0 if (el2->delete_time_stamp == 0) remove_list = g_slist_append(remove_list, GUINT_TO_POINTER(SC_ADDR_LOCAL_TO_INT(_addr))); _addr = el2->arc.next_in_arc; } // clean temp addr SC_ADDR_MAKE_EMPTY(_addr); } return SC_RESULT_OK; }
sc_bool _sc_iterator3_a_a_f_next(sc_iterator3 *it) { sc_addr arc_addr; SC_ADDR_MAKE_EMPTY(arc_addr) it->results[2] = it->params[2].addr; // try to find first input arc if (SC_ADDR_IS_EMPTY(it->results[1])) { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->params[2].addr, &el)); g_assert(el != null_ptr); arc_addr = el->first_in_arc; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->params[2].addr)); }else { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->results[1], &el)); g_assert(el != null_ptr); arc_addr = el->arc.next_in_arc; _sc_iterator_unref_element(it->ctx, el, it->results[1]); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->results[1])); } // trying to find input arc, that created before iterator, and wasn't deleted while (SC_ADDR_IS_NOT_EMPTY(arc_addr)) { sc_element *el = 0; while (el == null_ptr) STORAGE_CHECK_CALL(sc_storage_element_lock_try(it->ctx, arc_addr, s_max_iterator_lock_attempts, &el)); if (!sc_element_itref_add(sc_storage_get_element_meta(it->ctx, arc_addr))) { STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); continue; } sc_addr next_in_arc = el->arc.next_in_arc; if (sc_element_is_request_deletion(el) == SC_FALSE) { sc_type arc_type = el->flags.type; sc_addr arc_begin = el->arc.begin; sc_access_levels arc_access = el->flags.access_levels; sc_access_levels begin_access; if (sc_storage_get_access_levels(it->ctx, arc_begin, &begin_access) != SC_RESULT_OK) begin_access = sc_access_lvl_make_max; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); sc_type el_type = 0; sc_storage_get_element_type(it->ctx, arc_begin, &el_type); if (sc_iterator_compare_type(arc_type, it->params[1].type) && sc_iterator_compare_type(el_type, it->params[0].type) && sc_access_lvl_check_read(it->ctx->access_levels, arc_access) && sc_access_lvl_check_read(it->ctx->access_levels, begin_access) ) { // store found result it->results[1] = arc_addr; it->results[0] = arc_begin; return SC_TRUE; } } else { _sc_iterator_unref_element(it->ctx, el, arc_addr); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); } // go to next arc arc_addr = next_in_arc; } it->finished = SC_TRUE; return SC_FALSE; }
sc_bool _sc_iterator3_f_a_a_next(sc_iterator3 *it) { sc_addr arc_addr; SC_ADDR_MAKE_EMPTY(arc_addr); if (it->finished == SC_TRUE) return SC_FALSE; it->results[0] = it->params[0].addr; // try to find first output arc if (SC_ADDR_IS_EMPTY(it->results[1])) { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->params[0].addr, &el)); g_assert(el != null_ptr); arc_addr = el->first_out_arc; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->params[0].addr)); }else { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->results[1], &el)); g_assert(el != null_ptr); arc_addr = el->arc.next_out_arc; _sc_iterator_unref_element(it->ctx, el, it->results[1]); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->results[1])); } // iterate throught output arcs while (SC_ADDR_IS_NOT_EMPTY(arc_addr)) { sc_element *el = 0; // lock required elements to prevent deadlock with deletion while (el == null_ptr) STORAGE_CHECK_CALL(sc_storage_element_lock_try(it->ctx, arc_addr, s_max_iterator_lock_attempts, &el)); if (!sc_element_itref_add(sc_storage_get_element_meta(it->ctx, arc_addr))) { STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); continue; } sc_addr next_out_arc = el->arc.next_out_arc; if (sc_element_is_request_deletion(el) == SC_FALSE) { sc_addr arc_end = el->arc.end; sc_type arc_type = el->flags.type; sc_access_levels arc_access = el->flags.access_levels; sc_access_levels end_access; if (sc_storage_get_access_levels(it->ctx, arc_end, &end_access) != SC_RESULT_OK) end_access = sc_access_lvl_make_max; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); sc_type el_type; sc_storage_get_element_type(it->ctx, arc_end, &el_type); if (sc_iterator_compare_type(arc_type, it->params[1].type) && sc_iterator_compare_type(el_type, it->params[2].type) && sc_access_lvl_check_read(it->ctx->access_levels, arc_access) && sc_access_lvl_check_read(it->ctx->access_levels, end_access) ) { // store found result it->results[1] = arc_addr; it->results[2] = arc_end; return SC_TRUE; } } else { _sc_iterator_unref_element(it->ctx, el, arc_addr); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); } // go to next arc arc_addr = next_out_arc; } it->finished = SC_TRUE; return SC_FALSE; }
bool TestFindConnComp::check_find_conn_comp() { assert(SC_ADDR_IS_NOT_EMPTY(mGraphAddr)); sc_memory_arc_new(sc_type_arc_pos_const_perm, sc_graph_keynode_not_oriented_graph, mGraphAddr); sc_addr v1, v2, v3, v4, arc1, arc2, conn_comp_set; sc_iterator3 *it3; bool res = false; if (sc_graph_create_vertex(mGraphAddr, &v1) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v2) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v3) != SC_RESULT_OK) return false; if (sc_graph_create_vertex(mGraphAddr, &v4) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mGraphAddr, v1, v2, &arc1) != SC_RESULT_OK) return false; if (sc_graph_create_arc(mGraphAddr, v2, v3, &arc2) != SC_RESULT_OK) return false; if (sc_graph_find_conn_comp(mGraphAddr, &conn_comp_set) != SC_RESULT_OK) return false; it3 = sc_iterator3_f_a_a_new(conn_comp_set, sc_type_arc_pos_const_perm, sc_type_node); while (sc_iterator3_next(it3) == SC_TRUE) { sc_iterator3 *vert_it3 = sc_iterator3_f_a_a_new(it3->results[2], sc_type_arc_pos_const_perm, sc_type_node); int count = 0; res = true; while (sc_iterator3_next(vert_it3) == SC_TRUE) count++; sc_iterator3_free(vert_it3); vert_it3 = sc_iterator3_f_a_a_new(it3->results[2], sc_type_arc_pos_const_perm, sc_type_node); if (count == 3) { sc_addr vert1, vert2, vert3; sc_iterator3_next(vert_it3); vert1 = vert_it3->results[2]; sc_iterator3_next(vert_it3); vert2 = vert_it3->results[2]; sc_iterator3_next(vert_it3); vert3 = vert_it3->results[2]; if (sc_iterator3_next(vert_it3) == SC_TRUE) return false; if (!SC_ADDR_IS_EQUAL(vert1, v1) && !SC_ADDR_IS_EQUAL(vert1, v2) && !SC_ADDR_IS_EQUAL(vert1, v3) ) return false; if (!SC_ADDR_IS_EQUAL(vert2, v1) && !SC_ADDR_IS_EQUAL(vert2, v2) && !SC_ADDR_IS_EQUAL(vert2, v3) ) return false; if (!SC_ADDR_IS_EQUAL(vert3, v1) && !SC_ADDR_IS_EQUAL(vert3, v2) && !SC_ADDR_IS_EQUAL(vert3, v3) ) return false; if (SC_ADDR_IS_EQUAL(vert1, vert2) || SC_ADDR_IS_EQUAL(vert2, vert3) || SC_ADDR_IS_EQUAL(vert1, vert3) ) return false; } else if (count == 1) { sc_addr vert; sc_iterator3_next(vert_it3); vert = vert_it3->results[2]; if (sc_iterator3_next(vert_it3) == SC_TRUE) return false; if (!SC_ADDR_IS_EQUAL(vert, v4)) return false; } else return false; sc_iterator3_free(vert_it3); } sc_iterator3_free(it3); return res; }
sc_uint32 sc_segment_free_garbage(sc_segment *seg, sc_uint32 oldest_time_stamp) { sc_uint32 free_count = 0; sc_uint32 idx = 0; //sc_uint32 newest_time_stamp = sc_storage_get_time_stamp(); #if USE_TWO_ORIENTED_ARC_LIST sc_element *el = 0, *el2 = 0, *el_arc = 0, *next_el_arc = 0, *prev_el_arc = 0; sc_addr prev_arc, next_arc; sc_addr self_addr; #else sc_element *el = 0, *el2 = 0, *el_arc = 0, *prev_el_arc = 0; sc_addr prev_arc, current_arc; sc_addr self_addr; #endif #if USE_SEGMENT_EMPTY_SLOT_BUFFER seg->empty_slot_buff_head = 0; #endif self_addr.seg = seg->num; for (idx = 0; idx < SEGMENT_SIZE; ++idx) { el = &(seg->elements[idx]); self_addr.offset = idx; // skip element that wasn't deleted if (el->delete_time_stamp <= oldest_time_stamp && el->delete_time_stamp != 0) { // delete arcs from output and intpu lists // @todo two oriented lists support if (el->type & sc_type_arc_mask) { #if USE_TWO_ORIENTED_ARC_LIST prev_arc = el->arc.prev_out_arc; next_arc = el->arc.next_out_arc; if (SC_ADDR_IS_NOT_EMPTY(prev_arc)) { prev_el_arc = sc_storage_get_element(prev_arc, SC_TRUE); prev_el_arc->arc.next_out_arc = next_arc; } if (SC_ADDR_IS_NOT_EMPTY(next_arc)) { next_el_arc = sc_storage_get_element(next_arc, SC_TRUE); next_el_arc->arc.prev_out_arc = prev_arc; } #else SC_ADDR_MAKE_EMPTY(prev_arc); // output list el2 = sc_storage_get_element(el->arc.begin, SC_TRUE); current_arc = el2->first_out_arc; while (SC_ADDR_IS_NOT_EMPTY(current_arc) && SC_ADDR_IS_NOT_EQUAL(self_addr, current_arc)) { prev_arc = current_arc; prev_el_arc = el_arc; el_arc = sc_storage_get_element(current_arc, SC_TRUE); current_arc = el->arc.next_out_arc; } if (SC_ADDR_IS_NOT_EMPTY(prev_arc) && SC_ADDR_IS_NOT_EMPTY(current_arc)) prev_el_arc->arc.next_out_arc = el_arc->arc.next_out_arc; prev_el_arc = 0; el_arc = 0; SC_ADDR_MAKE_EMPTY(prev_arc); // input list el2 = sc_storage_get_element(el->arc.end, SC_TRUE); current_arc = el2->first_in_arc; while (SC_ADDR_IS_NOT_EMPTY(current_arc) && SC_ADDR_IS_NOT_EQUAL(self_addr, current_arc)) { prev_arc = current_arc; prev_el_arc = el_arc; el_arc = sc_storage_get_element(current_arc, SC_TRUE); current_arc = el->arc.next_in_arc; } if (SC_ADDR_IS_NOT_EMPTY(prev_arc) && SC_ADDR_IS_NOT_EMPTY(current_arc)) prev_el_arc->arc.next_in_arc = el_arc->arc.next_in_arc; #endif } el->type = 0; free_count ++; } // collect empty cells if (el->type == 0 && !(idx == 0 && seg->num == 0)) { #if USE_SEGMENT_EMPTY_SLOT_BUFFER if (seg->empty_slot_buff_head < SEGMENT_EMPTY_BUFFER_SIZE) seg->empty_slot_buff[seg->empty_slot_buff_head++] = idx; #else seg->empty_slot = idx; #endif } } return free_count; }