コード例 #1
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
sc_result sc_storage_set_link_content(sc_addr addr, const sc_stream *stream)
{
    sc_element *el = sc_storage_get_element(addr, SC_TRUE);
    sc_check_sum check_sum;
    sc_result result = SC_RESULT_ERROR;

    g_assert(stream != nullptr);

    if (el == nullptr)
        return SC_RESULT_ERROR_INVALID_PARAMS;

    if (!(el->type & sc_type_link))
        return SC_RESULT_ERROR_INVALID_TYPE;

    // calculate checksum for data
    if (sc_link_calculate_checksum(stream, &check_sum) == SC_TRUE)
    {
        result = sc_fs_storage_write_content(addr, &check_sum, stream);
        memcpy(el->content.data, check_sum.data, check_sum.len);
        el->content.len = check_sum.len;

        g_assert(check_sum.len > 0);

        sc_event_emit(addr, SC_EVENT_CHANGE_LINK_CONTENT, addr);
        result = SC_RESULT_OK;
    }

    g_assert(result == SC_RESULT_OK);

    return result;
}
コード例 #2
0
ファイル: test.cpp プロジェクト: drax08/sc-machine
sc_element* get_random_element(sc_type type)
{
    sc_addr id;

    id.seg = g_random_int() % sc_storage_get_segments_count();
    id.offset = g_random_int() % SEGMENT_SIZE;
    return sc_storage_get_element(id, SC_FALSE);
}
コード例 #3
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
sc_bool sc_storage_is_element(sc_addr addr)
{
    sc_element *el = sc_storage_get_element(addr, SC_TRUE);
    if (el == 0) return SC_FALSE;
    if (el->type == 0) return SC_FALSE;
    if (el->delete_time_stamp > 0) return SC_FALSE;

    return SC_TRUE;
}
コード例 #4
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
sc_result sc_storage_get_element_type(sc_addr addr, sc_type *result)
{
    sc_element *el = sc_storage_get_element(addr, SC_TRUE);
    if (el == 0)
        return SC_RESULT_ERROR;

    *result = el->type;

    return SC_RESULT_OK;
}
コード例 #5
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
sc_result sc_storage_get_arc_end(sc_addr addr, sc_addr *result)
{
    sc_element *el = sc_storage_get_element(addr, SC_TRUE);
    if (el->type & sc_type_arc_mask)
    {
        *result = el->arc.end;
        return SC_RESULT_OK;
    }

    return SC_RESULT_ERROR_INVALID_TYPE;
}
コード例 #6
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
sc_result sc_storage_get_link_content(sc_addr addr, sc_stream **stream)
{
    sc_element *el = sc_storage_get_element(addr, SC_TRUE);
    sc_check_sum checksum;

    if (el == nullptr)
        return SC_RESULT_ERROR_INVALID_PARAMS;

    if (!(el->type & sc_type_link))
        return SC_RESULT_ERROR_INVALID_TYPE;


    // prepare checksum
    checksum.len = el->content.len;
    memcpy(checksum.data, el->content.data, checksum.len);

    return sc_fs_storage_get_checksum_content(&checksum, stream);
}
コード例 #7
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
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;
}
コード例 #8
0
ファイル: sc_storage.c プロジェクト: pivovarchyk/sc-machine
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;
}
コード例 #9
0
ファイル: sc_segment.c プロジェクト: pivovarchyk/sc-machine
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;
}