Esempio n. 1
0
sc_element* sc_storage_append_el_into_segments(sc_element *element, sc_addr *addr)
{
    sc_segment *segment = 0;

    g_assert( addr != 0 );
    SC_ADDR_MAKE_EMPTY(*addr);

    if (sc_iterator_has_any_timestamp())
        storage_time_stamp++;

    // try to collect and delete garbage
    if (segments_num >= sc_config_get_max_loaded_segments())
        sc_storage_update_segments();

    if (_sc_storage_get_segment_from_queue(&addr->seg) == SC_TRUE)
    {
        segment = sc_storage_get_segment(addr->seg, SC_TRUE);
        return sc_segment_append_element(segment, element, &addr->offset);
    }

    //! @todo maximum segments reached
    if (segments_num >= sc_config_get_max_loaded_segments())
        return nullptr;

    // if element still not added, then create new segment and append element into it
    segment = sc_segment_new(segments_num);
    addr->seg = segments_num;
    segments[segments_num++] = segment;

    _sc_storage_append_segment_to_queue(addr->seg);

    return sc_segment_append_element(segment, element, &addr->offset);
}
Esempio n. 2
0
sc_segment* sc_fs_storage_load_segment(sc_uint id)
{
    sc_segment *segment = sc_segment_new(id);
    gchar file_name[MAX_PATH_LENGTH + 1];
    gboolean res;
    gsize length;

    _get_segment_path(segments_path, id, MAX_PATH_LENGTH, file_name);
    res = g_file_get_contents(file_name, (gchar**)(&segment), &length, 0);
    g_assert( res );
    g_assert( length == sizeof(sc_segment) );

    return segment;
}
Esempio n. 3
0
sc_bool sc_fs_storage_read_from_path(sc_segment **segments, sc_uint32 *segments_num)
{
    if (g_file_test(repo_path, G_FILE_TEST_IS_DIR) == FALSE)
    {
        g_error("%s isn't a directory.", repo_path);
        return SC_FALSE;
    }

    if (g_file_test(segments_path, G_FILE_TEST_IS_REGULAR) == FALSE)
    {
        g_message("There are no segments in %s", segments_path);
        return SC_FALSE;
    }

    // open segments
    {
        GIOChannel * in_file = g_io_channel_new_file(segments_path, "r", null_ptr);
        sc_fs_storage_segments_header header;
        gsize bytes_num = 0;
        sc_uint32 i = 0, header_size = 0;
        GChecksum * checksum = null_ptr;
        sc_segment * seg = null_ptr;
        sc_bool is_valid = SC_TRUE;
        sc_uint8 calculated_checksum[SC_STORAGE_SEG_CHECKSUM_SIZE];

        g_assert(_checksum_get_size() == SC_STORAGE_SEG_CHECKSUM_SIZE);
        if (!in_file)
        {
            g_critical("Can't open segments from: %s", segments_path);
            return SC_FALSE;
        }

        if (g_io_channel_set_encoding(in_file, null_ptr, null_ptr) != G_IO_STATUS_NORMAL)
        {
            g_critical("Can't setup encoding: %s", segments_path);
            return SC_FALSE;
        }

        if ((g_io_channel_read_chars(in_file, (gchar*)&header_size, sizeof(header_size), &bytes_num, null_ptr) != G_IO_STATUS_NORMAL) || (bytes_num != sizeof(header_size)))
        {
            g_critical("Can't read header size");
            return SC_FALSE;
        }

        if (header_size != sizeof(header))
        {
            g_critical("Invalid header size %d != %d", header_size, (int)sizeof(header));
            return SC_FALSE;
        }

        if ((g_io_channel_read_chars(in_file, (gchar*)&header, sizeof(header), &bytes_num, null_ptr) != G_IO_STATUS_NORMAL) || (bytes_num != sizeof(header)))
        {
            g_critical("Can't read header of segments: %s", segments_path);
            return SC_FALSE;
        }

        *segments_num = header.segments_num;

        /// TODO: Check version

        checksum = g_checksum_new(_checksum_type());
        g_assert(checksum);

        g_checksum_reset(checksum);

        // chek data
        for (i = 0; i < *segments_num; ++i)
        {
            seg = sc_segment_new(i);
            segments[i] = seg;

            g_io_channel_read_chars(in_file, (gchar*)seg->elements, SC_SEG_ELEMENTS_SIZE_BYTE, &bytes_num, null_ptr);
            sc_segment_loaded(seg);
            if (bytes_num != SC_SEG_ELEMENTS_SIZE_BYTE)
            {
                g_error("Error while read data for segment: %d", i);
                is_valid = SC_FALSE;
                break;
            }
            g_checksum_update(checksum, (guchar*)seg->elements, SC_SEG_ELEMENTS_SIZE_BYTE);
        }

        if (is_valid == SC_TRUE)
        {
            // compare checksum
            g_checksum_get_digest(checksum, calculated_checksum, &bytes_num);
            if (bytes_num != SC_STORAGE_SEG_CHECKSUM_SIZE)
                is_valid = SC_FALSE;
            else
                is_valid = (memcmp(calculated_checksum, header.checksum, SC_STORAGE_SEG_CHECKSUM_SIZE) == 0) ? SC_TRUE : SC_FALSE;
        }

        if (is_valid == SC_FALSE)
        {
            *segments_num = 0;
            for (i = 0; i < SC_SEGMENT_MAX; ++i)
            {
                if (segments[i])
                {
                    sc_segment_free(segments[i]);
                    segments[i] = null_ptr;
                }
            }
        }

        g_checksum_free(checksum);
        g_io_channel_shutdown(in_file, FALSE, null_ptr);

        if (is_valid == SC_FALSE)
            return SC_FALSE;
    }

    g_message("Segments loaded: %u", *segments_num);

    g_assert(fm_engine != null_ptr);
    g_message("Check file memory state");
    sc_bool r = sc_fm_clean_state(fm_engine) == SC_RESULT_OK;

    if (r == SC_FALSE)
        g_error("File memory wasn't check properly");

    return r;
}