mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-11 07:56:08 -06:00
#4028 Fix performance issues
This commit is contained in:
parent
55b215e66b
commit
dfac372a9c
233
ThirdParty/Ert/lib/ecl/fortio.c
vendored
233
ThirdParty/Ert/lib/ecl/fortio.c
vendored
@ -23,7 +23,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/type_macros.hpp>
|
||||
#include <ert/util/type_macros.h>
|
||||
#include <ert/ecl/fortio.h>
|
||||
|
||||
#include <ecl/fortio.h>
|
||||
@ -119,9 +119,13 @@ static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool
|
||||
*/
|
||||
|
||||
static bool __read_int(FILE * stream , int * value, bool endian_flip) {
|
||||
int ok = eclfio_sizeof( stream, endian_flip ? "c" : "ce", value );
|
||||
fseek( stream, sizeof( int32_t ), SEEK_CUR );
|
||||
return !ok;
|
||||
/* This fread() can legitemately fail - can not use util_fread() here. */
|
||||
if (fread(value , sizeof * value , 1 , stream) == 1) {
|
||||
if (endian_flip)
|
||||
util_endian_flip_vector(value , sizeof * value , 1);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -415,14 +419,30 @@ void fortio_fclose(fortio_type *fortio) {
|
||||
|
||||
|
||||
bool fortio_is_fortio_file(fortio_type * fortio) {
|
||||
fpos_t init_pos;
|
||||
fgetpos( fortio->stream, &init_pos );
|
||||
offset_type init_pos = fortio_ftell(fortio);
|
||||
int elm_read;
|
||||
bool is_fortio_file = false;
|
||||
int record_size;
|
||||
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
|
||||
if (elm_read == 1) {
|
||||
int trailer;
|
||||
|
||||
int err = eclfio_get( fortio->stream, fortio->opts, NULL, NULL );
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&record_size , sizeof record_size , 1);
|
||||
|
||||
fsetpos( fortio->stream, &init_pos );
|
||||
if (fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR) == 0) {
|
||||
if (fread(&trailer , sizeof(record_size) , 1 , fortio->stream) == 1) {
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&trailer , sizeof trailer , 1);
|
||||
|
||||
return err == ECL_OK;
|
||||
if (trailer == record_size)
|
||||
is_fortio_file = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fortio_fseek(fortio , init_pos , SEEK_SET);
|
||||
return is_fortio_file;
|
||||
}
|
||||
|
||||
|
||||
@ -434,17 +454,26 @@ bool fortio_is_fortio_file(fortio_type * fortio) {
|
||||
*/
|
||||
|
||||
int fortio_init_read(fortio_type *fortio) {
|
||||
int32_t record_size;
|
||||
int err = eclfio_sizeof( fortio->stream, fortio->opts, &record_size );
|
||||
// this function exposes successful reads as advanced file pointers
|
||||
if( err == 0 ) fseek( fortio->stream, 4, SEEK_CUR );
|
||||
return err ? -1 : record_size;
|
||||
int elm_read;
|
||||
int record_size;
|
||||
|
||||
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
|
||||
if (elm_read == 1) {
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&record_size , sizeof record_size , 1);
|
||||
|
||||
return record_size;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) {
|
||||
return !eclfio_skip( fortio->stream, fortio->opts, block_count );
|
||||
int headers = block_count * 4;
|
||||
int trailers = block_count * 4;
|
||||
int bytes_to_skip = headers + trailers + (element_size * element_count);
|
||||
|
||||
return fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
@ -456,9 +485,9 @@ void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data
|
||||
int block_index = data_element / block_size;
|
||||
int headers = (block_index + 1) * 4;
|
||||
int trailers = block_index * 4;
|
||||
offset_type offset = data_offset + headers + trailers + (data_element * element_size);
|
||||
offset_type bytes_to_skip = data_offset + headers + trailers + (data_element * element_size);
|
||||
|
||||
fortio_fseek(fortio, offset, SEEK_SET);
|
||||
fortio_fseek(fortio, bytes_to_skip, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
@ -489,6 +518,28 @@ bool fortio_complete_read(fortio_type *fortio , int record_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function reads one record from the fortio stream, and fills
|
||||
the buffer with the content. The return value is the number of
|
||||
bytes read; the function will return -1 on failure.
|
||||
*/
|
||||
|
||||
static int fortio_fread_record(fortio_type *fortio , char *buffer) {
|
||||
int record_size = fortio_init_read(fortio);
|
||||
if (record_size >= 0) {
|
||||
size_t items_read = fread(buffer , 1 , record_size , fortio->stream);
|
||||
if (items_read == record_size) {
|
||||
bool complete_ok = fortio_complete_read(fortio , record_size);
|
||||
if (!complete_ok)
|
||||
record_size = -1;
|
||||
} else
|
||||
record_size = -1; /* Failure */
|
||||
}
|
||||
return record_size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function fills the buffer with 'buffer_size' bytes from the
|
||||
fortio stream. The function works by repeated calls to
|
||||
@ -499,107 +550,75 @@ bool fortio_complete_read(fortio_type *fortio , int record_size) {
|
||||
*/
|
||||
|
||||
bool fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) {
|
||||
int total_bytes_read = 0;
|
||||
int total_bytes_read = 0;
|
||||
|
||||
while( true ) {
|
||||
int32_t record_size = buffer_size - total_bytes_read;
|
||||
int err = eclfio_get( fortio->stream,
|
||||
fortio->opts,
|
||||
&record_size,
|
||||
buffer );
|
||||
while (true) {
|
||||
char * buffer_ptr = &buffer[total_bytes_read];
|
||||
int bytes_read = fortio_fread_record(fortio , buffer_ptr);
|
||||
|
||||
if( err == ECL_EINVAL ) {
|
||||
err = eclfio_sizeof( fortio->stream, fortio->opts, &record_size );
|
||||
if( err ) util_abort("%s: unable to determine size of record, "
|
||||
"%d bytes read\n",
|
||||
__func__,
|
||||
total_bytes_read );
|
||||
|
||||
if( total_bytes_read + record_size > buffer_size )
|
||||
util_abort("%s: internal inconsistency: "
|
||||
"buffer_size:%d, would read %d bytes\n",
|
||||
__func__,
|
||||
buffer_size,
|
||||
total_bytes_read + record_size );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( err ) return false;
|
||||
|
||||
buffer += record_size;
|
||||
total_bytes_read += record_size;
|
||||
|
||||
if( total_bytes_read == buffer_size )
|
||||
return true;
|
||||
if (bytes_read < 0)
|
||||
break;
|
||||
else {
|
||||
total_bytes_read += bytes_read;
|
||||
if (total_bytes_read >= buffer_size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_bytes_read == buffer_size)
|
||||
return true;
|
||||
|
||||
if (total_bytes_read < buffer_size)
|
||||
return false;
|
||||
|
||||
util_abort("%s: internal inconsistency: buffer_size:%d read %d bytes \n",__func__ , buffer_size , total_bytes_read);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int fortio_fskip_record(fortio_type *fortio) {
|
||||
int32_t size = 0;
|
||||
const int err = eclfio_get( fortio->stream, fortio->opts, &size, NULL );
|
||||
if( err ) return -1;
|
||||
return size;
|
||||
int record_size = fortio_init_read(fortio);
|
||||
fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR);
|
||||
fortio_complete_read(fortio , record_size);
|
||||
return record_size;
|
||||
}
|
||||
|
||||
void fortio_fskip_buffer(fortio_type * fortio, int buffer_size) {
|
||||
int bytes_skipped = 0;
|
||||
while (bytes_skipped < buffer_size) {
|
||||
int size = fortio_fskip_record(fortio);
|
||||
|
||||
if( size < 0 ) util_abort( "%s: broken record in %s. "
|
||||
"%d bytes skipped so far\n",
|
||||
__func__,
|
||||
fortio->filename,
|
||||
bytes_skipped );
|
||||
|
||||
bytes_skipped += fortio_fskip_record(fortio);
|
||||
}
|
||||
while (bytes_skipped < buffer_size)
|
||||
bytes_skipped += fortio_fskip_record(fortio);
|
||||
|
||||
if (bytes_skipped > buffer_size)
|
||||
util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename);
|
||||
}
|
||||
|
||||
|
||||
void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * ext_buffer, bool *at_eof) {
|
||||
int bytes_read = 0;
|
||||
void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * buffer , bool *at_eof) {
|
||||
int bytes_read;
|
||||
int record_size = fortio_init_read(src_stream);
|
||||
fortio_init_write(target_stream , record_size);
|
||||
|
||||
bytes_read = 0;
|
||||
while (bytes_read < record_size) {
|
||||
int bytes;
|
||||
if (record_size > buffer_size)
|
||||
bytes = buffer_size;
|
||||
else
|
||||
bytes = record_size - bytes_read;
|
||||
|
||||
int32_t size = 0;
|
||||
int err = eclfio_sizeof( src_stream->stream, src_stream->opts, &size );
|
||||
if( err ) {
|
||||
util_abort( "%s: could not peek record size after %d bytes\n",
|
||||
__func__,
|
||||
bytes_read );
|
||||
}
|
||||
util_fread(buffer , 1 , bytes , src_stream->stream , __func__);
|
||||
util_fwrite(buffer , 1 , bytes , target_stream->stream , __func__);
|
||||
|
||||
void* buffer = ext_buffer;
|
||||
if( buffer_size < size ) {
|
||||
buffer = malloc( size );
|
||||
ext_buffer = NULL;
|
||||
}
|
||||
bytes_read += bytes;
|
||||
}
|
||||
|
||||
err = eclfio_get( src_stream->stream, src_stream->opts, &size, buffer );
|
||||
if( err ) {
|
||||
util_abort( "%s: could not read record after %d bytes\n",
|
||||
__func__,
|
||||
bytes_read );
|
||||
}
|
||||
fortio_complete_read(src_stream , record_size);
|
||||
fortio_complete_write(target_stream , record_size);
|
||||
|
||||
err = eclfio_put( target_stream->stream,
|
||||
target_stream->opts,
|
||||
size,
|
||||
buffer );
|
||||
if( err ) {
|
||||
util_abort( "%s: could not write record after %d bytes\n",
|
||||
__func__,
|
||||
bytes_read );
|
||||
}
|
||||
|
||||
if( !ext_buffer ) free( buffer );
|
||||
|
||||
*at_eof = feof( src_stream->stream );
|
||||
if (feof(src_stream->stream))
|
||||
*at_eof = true;
|
||||
else
|
||||
*at_eof = false;
|
||||
}
|
||||
|
||||
|
||||
@ -624,23 +643,19 @@ void fortio_complete_write(fortio_type *fortio , int record_size) {
|
||||
|
||||
|
||||
void fortio_fwrite_record(fortio_type *fortio, const char *buffer , int record_size) {
|
||||
int err = eclfio_put( fortio->stream,
|
||||
fortio->opts,
|
||||
record_size,
|
||||
buffer );
|
||||
|
||||
if( err ) util_abort( "%s: unable to write %d byte record\n",
|
||||
__func__,
|
||||
record_size );
|
||||
fortio_init_write(fortio , record_size);
|
||||
util_fwrite( buffer , 1 , record_size , fortio->stream , __func__);
|
||||
fortio_complete_write(fortio , record_size);
|
||||
}
|
||||
|
||||
|
||||
void * fortio_fread_alloc_record(fortio_type * fortio) {
|
||||
int32_t record_size = 0;
|
||||
eclfio_sizeof( fortio->stream, fortio->opts, &record_size );
|
||||
void* buffer = calloc( 1, record_size );
|
||||
eclfio_get( fortio->stream, fortio->opts, &record_size, buffer );
|
||||
return buffer;
|
||||
void * buffer;
|
||||
int record_size = fortio_init_read(fortio);
|
||||
buffer = util_malloc( record_size );
|
||||
util_fread(buffer , 1 , record_size , fortio->stream , __func__);
|
||||
fortio_complete_read(fortio , record_size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user