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); }
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; }
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; }