MIDAS
Loading...
Searching...
No Matches
HsFileSchema Struct Reference
Inheritance diagram for HsFileSchema:
Collaboration diagram for HsFileSchema:

Public Member Functions

 HsFileSchema ()
 
 ~HsFileSchema ()
 
void print (bool print_tags=true) const
 
int flush_buffers ()
 
int close ()
 
int write_event (const time_t t, const char *data, const int data_size)
 
int read_last_written (const time_t timestamp, const int debug, time_t *last_written)
 
int read_data (const time_t start_time, const time_t end_time, const int num_var, const std::vector< int > &var_schema_index, const int var_index[], const int debug, std::vector< time_t > &last_time, MidasHistoryBufferInterface *buffer[])
 
- Public Member Functions inherited from HsSchema
 HsSchema ()
 
virtual ~HsSchema ()
 
virtual int match_event_var (const char *event_name, const char *var_name, const int var_index)
 

Public Attributes

std::string file_name
 
int record_size = 0
 
int data_offset = 0
 
int last_size = 0
 
int writer_fd = -1
 
int record_buffer_size = 0
 
charrecord_buffer = NULL
 
- Public Attributes inherited from HsSchema
std::string event_name
 
time_t time_from = 0
 
time_t time_to = 0
 
std::vector< HsSchemaEntryvariables
 
std::vector< intoffsets
 
int n_bytes = 0
 
int count_write_undersize = 0
 
int count_write_oversize = 0
 
int write_max_size = 0
 
int write_min_size = 0
 
bool disabled = true
 

Detailed Description

Definition at line 741 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ HsFileSchema()

HsFileSchema::HsFileSchema ( )
inline

Definition at line 750 of file history_schema.cxx.

751 {
752 // empty
753 }

◆ ~HsFileSchema()

HsFileSchema::~HsFileSchema ( )
inline

Definition at line 755 of file history_schema.cxx.

756 {
757 close();
758 record_size = 0;
759 data_offset = 0;
760 last_size = 0;
761 writer_fd = -1;
762 if (record_buffer) {
763 free(record_buffer);
765 }
767 }
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:

Member Function Documentation

◆ close()

int HsFileSchema::close ( )
virtual

Implements HsSchema.

Definition at line 2550 of file history_schema.cxx.

2551{
2552 if (writer_fd >= 0) {
2554 writer_fd = -1;
2555 }
2556 return HS_SUCCESS;
2557}
#define HS_SUCCESS
Definition midas.h:727
Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush_buffers()

int HsFileSchema::flush_buffers ( )
inlinevirtual

Implements HsSchema.

Definition at line 770 of file history_schema.cxx.

770{ return HS_SUCCESS; };

◆ print()

void HsFileSchema::print ( bool  print_tags = true) const
virtual

Reimplemented from HsSchema.

Definition at line 811 of file history_schema.cxx.

812{
813 unsigned nv = this->variables.size();
814 printf("event [%s], file_name [%s], time %s..%s, %d variables, %d bytes, dat_offset %d, record_size %d\n", this->event_name.c_str(), this->file_name.c_str(), TimeToString(this->time_from).c_str(), TimeToString(this->time_to).c_str(), nv, n_bytes, data_offset, record_size);
815 if (print_tags) {
816 for (unsigned j=0; j<nv; j++)
817 printf(" %d: name [%s], type [%s] tid %d, n_data %d, n_bytes %d, offset %d\n", j, this->variables[j].name.c_str(), rpc_tid_name(this->variables[j].type), this->variables[j].type, this->variables[j].n_data, this->variables[j].n_bytes, this->offsets[j]);
818 }
819}
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
static std::string TimeToString(time_t t)
INT type
Definition mana.cxx:269
#define name(x)
Definition midas_macro.h:24
INT j
Definition odbhist.cxx:40
std::vector< int > offsets
std::string event_name
std::vector< HsSchemaEntry > variables
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_data()

int HsFileSchema::read_data ( const time_t  start_time,
const time_t  end_time,
const int  num_var,
const std::vector< int > &  var_schema_index,
const int  var_index[],
const int  debug,
std::vector< time_t > &  last_time,
MidasHistoryBufferInterface buffer[] 
)
virtual

Implements HsSchema.

Definition at line 2801 of file history_schema.cxx.

2807{
2808 HsFileSchema* s = this;
2809
2810 if (debug)
2811 printf("FileHistory::read_data: file %s, schema time %s..%s, read time %s..%s, %d vars\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str(), num_var);
2812
2813 //if (1) {
2814 // printf("Last time: ");
2815 // for (int i=0; i<num_var; i++) {
2816 // printf(" %s", TimeToString(last_time[i]).c_str());
2817 // }
2818 // printf("\n");
2819 //}
2820
2821 if (debug) {
2822 printf("FileHistory::read_data: file %s map", s->file_name.c_str());
2823 for (size_t i=0; i<var_schema_index.size(); i++) {
2824 printf(" %2d", var_schema_index[i]);
2825 }
2826 printf("\n");
2827 }
2828
2829 int fd = ::open(s->file_name.c_str(), O_RDONLY);
2830 if (fd < 0) {
2831 cm_msg(MERROR, "FileHistory::read_data", "Cannot read \'%s\', open() errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2832 return HS_FILE_ERROR;
2833 }
2834
2835 off_t file_size = ::lseek(fd, 0, SEEK_END);
2836
2837 if (file_size == (off_t)-1) {
2838 cm_msg(MERROR, "FileHistory::read_data", "Cannot read \'%s\', fseek(SEEK_END) errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2839 ::close(fd);
2840 return HS_FILE_ERROR;
2841 }
2842
2843 int nrec = (file_size - s->data_offset)/s->record_size;
2844 if (nrec < 0)
2845 nrec = 0;
2846
2847 if (nrec < 1) {
2848 ::close(fd);
2849 return HS_SUCCESS;
2850 }
2851
2852 int iunused = 0;
2853 time_t tunused = 0;
2854 int irec = 0;
2855 time_t trec = 0;
2856 time_t tstart = 0;
2857 time_t tend = 0;
2858
2859 int status = FindTime(s->file_name.c_str(), fd, s->data_offset, s->record_size, nrec, start_time, &iunused, &tunused, &irec, &trec, &tstart, &tend, 0*debug);
2860
2861 if (status != HS_SUCCESS) {
2862 ::close(fd);
2863 return HS_FILE_ERROR;
2864 }
2865
2866 if (debug) {
2867 printf("FindTime %d, nrec %d, (%d, %s) (%d, %s), tstart %s, tend %s, want %s\n", status, nrec, iunused, TimeToString(tunused).c_str(), irec, TimeToString(trec).c_str(), TimeToString(tstart).c_str(), TimeToString(tend).c_str(), TimeToString(start_time).c_str());
2868 }
2869
2870 if (irec < 0 || irec >= nrec) {
2871 // all data in this file is older than start_time
2872
2873 ::close(fd);
2874
2875 if (debug)
2876 printf("FileHistory::read: file %s, schema time %s..%s, read time %s..%s, file time %s..%s, data in this file is too old\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str(), TimeToString(tstart).c_str(), TimeToString(tend).c_str());
2877
2878 return HS_SUCCESS;
2879 }
2880
2882 // data starts before time declared in schema
2883
2884 ::close(fd);
2885
2886 cm_msg(MERROR, "FileHistory::read_data", "Bad history file \'%s\': timestamp of first data %s is before schema start time %s", s->file_name.c_str(), TimeToString(tstart).c_str(), TimeToString(s->time_from).c_str());
2887
2888 return HS_FILE_ERROR;
2889 }
2890
2891 if (tend && s->time_to && tend > s->time_to) {
2892 // data ends after time declared in schema (overlaps with next file)
2893
2894 ::close(fd);
2895
2896 cm_msg(MERROR, "FileHistory::read_data", "Bad history file \'%s\': timestamp of last data %s is after schema end time %s", s->file_name.c_str(), TimeToString(tend).c_str(), TimeToString(s->time_to).c_str());
2897
2898 return HS_FILE_ERROR;
2899 }
2900
2901 for (int i=0; i<num_var; i++) {
2902 int si = var_schema_index[i];
2903 if (si < 0)
2904 continue;
2905
2906 if (trec < last_time[i]) { // protect against duplicate and non-monotonous data
2907 ::close(fd);
2908
2909 cm_msg(MERROR, "FileHistory::read_data", "Internal history error at file \'%s\': variable %d data timestamp %s is before last timestamp %s", s->file_name.c_str(), i, TimeToString(trec).c_str(), TimeToString(last_time[i]).c_str());
2910
2911 return HS_FILE_ERROR;
2912 }
2913 }
2914
2915 int count = 0;
2916
2918
2919 off_t xpos = ::lseek(fd, fpos, SEEK_SET);
2920 if (xpos == (off_t)-1) {
2921 cm_msg(MERROR, "FileHistory::read_data", "Cannot read \'%s\', lseek(%zu) errno %d (%s)", s->file_name.c_str(), (size_t)fpos, errno, strerror(errno));
2922 ::close(fd);
2923 return HS_FILE_ERROR;
2924 }
2925
2926 char* buf = new char[s->record_size];
2927
2928 int prec = irec;
2929
2930 while (1) {
2931 status = ::read(fd, buf, s->record_size);
2932 if (status == 0) // EOF
2933 break;
2934 if (status == -1) {
2935 cm_msg(MERROR, "FileHistory::read_data", "Cannot read \'%s\', read() errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2936 break;
2937 }
2938 if (status != s->record_size) {
2939 cm_msg(MERROR, "FileHistory::read_data", "Cannot read \'%s\', short read() returned %d instead of %d bytes", s->file_name.c_str(), status, s->record_size);
2940 break;
2941 }
2942
2943 prec++;
2944
2945 bool past_end_of_last_file = (s->time_to == 0) && (prec > nrec);
2946
2947 time_t t = *(DWORD*)buf;
2948
2949 if (debug > 1)
2950 printf("FileHistory::read: file %s, schema time %s..%s, read time %s..%s, row time %s\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str(), TimeToString(t).c_str());
2951
2952 if (t < trec) {
2953 delete[] buf;
2954 ::close(fd);
2955 cm_msg(MERROR, "FileHistory::read_data", "Bad history file \'%s\': record %d timestamp %s is before start time %s", s->file_name.c_str(), irec + count, TimeToString(t).c_str(), TimeToString(trec).c_str());
2956 return HS_FILE_ERROR;
2957 }
2958
2959 if (tend && (t > tend) && !past_end_of_last_file) {
2960 delete[] buf;
2961 ::close(fd);
2962 cm_msg(MERROR, "FileHistory::read_data", "Bad history file \'%s\': record %d timestamp %s is after last timestamp %s", s->file_name.c_str(), irec + count, TimeToString(t).c_str(), TimeToString(tend).c_str());
2963 return HS_FILE_ERROR;
2964 }
2965
2966 if (t > end_time)
2967 break;
2968
2969 char* data = buf + 4;
2970
2971 for (int i=0; i<num_var; i++) {
2972 int si = var_schema_index[i];
2973 if (si < 0)
2974 continue;
2975
2976 if (t < last_time[i]) { // protect against duplicate and non-monotonous data
2977 delete[] buf;
2978 ::close(fd);
2979
2980 cm_msg(MERROR, "FileHistory::read_data", "Bad history file \'%s\': record %d timestamp %s is before timestamp %s of variable %d", s->file_name.c_str(), irec + count, TimeToString(t).c_str(), TimeToString(last_time[i]).c_str(), i);
2981
2982 return HS_FILE_ERROR;
2983 }
2984
2985 double v = 0;
2986 void* ptr = data + s->offsets[si];
2987
2988 int ii = var_index[i];
2989 assert(ii >= 0);
2990 assert(ii < s->variables[si].n_data);
2991
2992 switch (s->variables[si].type) {
2993 default:
2994 // unknown data type
2995 v = 0;
2996 break;
2997 case TID_BYTE:
2998 v = ((unsigned char*)ptr)[ii];
2999 break;
3000 case TID_SBYTE:
3001 v = ((signed char *)ptr)[ii];
3002 break;
3003 case TID_CHAR:
3004 v = ((char*)ptr)[ii];
3005 break;
3006 case TID_WORD:
3007 v = ((unsigned short *)ptr)[ii];
3008 break;
3009 case TID_SHORT:
3010 v = ((signed short *)ptr)[ii];
3011 break;
3012 case TID_DWORD:
3013 v = ((unsigned int *)ptr)[ii];
3014 break;
3015 case TID_INT:
3016 v = ((int *)ptr)[ii];
3017 break;
3018 case TID_BOOL:
3019 v = ((unsigned int *)ptr)[ii];
3020 break;
3021 case TID_FLOAT:
3022 v = ((float*)ptr)[ii];
3023 break;
3024 case TID_DOUBLE:
3025 v = ((double*)ptr)[ii];
3026 break;
3027 }
3028
3029 buffer[i]->Add(t, v);
3030 last_time[i] = t;
3031 }
3032 count++;
3033 }
3034
3035 delete[] buf;
3036
3037 ::close(fd);
3038
3039 if (debug) {
3040 printf("FileHistory::read_data: file %s map", s->file_name.c_str());
3041 for (size_t i=0; i<var_schema_index.size(); i++) {
3042 printf(" %2d", var_schema_index[i]);
3043 }
3044 printf(" read %d rows\n", count);
3045 }
3046
3047 if (debug)
3048 printf("FileHistory::read: file %s, schema time %s..%s, read time %s..%s, %d vars, read %d rows\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str(), num_var, count);
3049
3050 return HS_SUCCESS;
3051}
virtual void Add(time_t time, double value)=0
#define HS_FILE_ERROR
Definition midas.h:728
unsigned int DWORD
Definition mcstd.h:51
#define TID_DOUBLE
Definition midas.h:343
#define TID_SBYTE
Definition midas.h:329
#define TID_BOOL
Definition midas.h:340
#define TID_SHORT
Definition midas.h:334
#define TID_WORD
Definition midas.h:332
#define TID_BYTE
Definition midas.h:327
#define MERROR
Definition midas.h:559
#define TID_CHAR
Definition midas.h:331
#define TID_INT
Definition midas.h:338
#define TID_FLOAT
Definition midas.h:341
#define TID_DWORD
Definition midas.h:336
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
static int FindTime(const char *file_name, int fd, int offset, int recsize, int nrec, time_t timestamp, int *i1p, time_t *t1p, int *i2p, time_t *t2p, time_t *tstart, time_t *tend, int debug)
DWORD last_time
Definition mana.cxx:3070
void * data
Definition mana.cxx:268
BOOL debug
debug printouts
Definition mana.cxx:254
double count
Definition mdump.cxx:33
INT i
Definition mdump.cxx:32
#define read(n, a, f)
DWORD status
Definition odbhist.cxx:39
std::string file_name
Here is the call graph for this function:

◆ read_last_written()

int HsFileSchema::read_last_written ( const time_t  timestamp,
const int  debug,
time_t last_written 
)
virtual

Implements HsSchema.

Definition at line 2721 of file history_schema.cxx.

2724{
2725 int status;
2726 HsFileSchema* s = this;
2727
2728 if (debug)
2729 printf("FileHistory::read_last_written: file %s, schema time %s..%s, timestamp %s\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(timestamp).c_str());
2730
2731 int fd = open(s->file_name.c_str(), O_RDONLY);
2732 if (fd < 0) {
2733 cm_msg(MERROR, "FileHistory::read_last_written", "Cannot read \'%s\', open() errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2734 return HS_FILE_ERROR;
2735 }
2736
2737 int file_size = ::lseek(fd, 0, SEEK_END);
2738
2739 int nrec = (file_size - s->data_offset)/s->record_size;
2740 if (nrec < 0)
2741 nrec = 0;
2742
2743 if (nrec < 1) {
2744 ::close(fd);
2745 if (last_written)
2746 *last_written = 0;
2747 return HS_SUCCESS;
2748 }
2749
2750 time_t lw = 0;
2751
2752 // read last record to check if desired time is inside or outside of the file
2753
2754 if (1) {
2755 char* buf = new char[s->record_size];
2756
2757 status = ReadRecord(s->file_name.c_str(), fd, s->data_offset, s->record_size, nrec - 1, buf);
2758 if (status != HS_SUCCESS) {
2759 delete[] buf;
2760 ::close(fd);
2761 return HS_FILE_ERROR;
2762 }
2763
2764 lw = *(DWORD*)buf;
2765
2766 delete[] buf;
2767 }
2768
2769 if (lw >= timestamp) {
2770 int irec = 0;
2771 time_t trec = 0;
2772 int iunused = 0;
2773 time_t tunused = 0;
2774 time_t tstart = 0; // not used
2775 time_t tend = 0; // not used
2776
2777 status = FindTime(s->file_name.c_str(), fd, s->data_offset, s->record_size, nrec, timestamp, &irec, &trec, &iunused, &tunused, &tstart, &tend, 0*debug);
2778 if (status != HS_SUCCESS) {
2779 ::close(fd);
2780 return HS_FILE_ERROR;
2781 }
2782
2783 assert(trec < timestamp);
2784
2785 lw = trec;
2786 }
2787
2788 if (last_written)
2789 *last_written = lw;
2790
2791 if (debug)
2792 printf("FileHistory::read_last_written: file %s, schema time %s..%s, timestamp %s, last_written %s\n", s->file_name.c_str(), TimeToString(s->time_from).c_str(), TimeToString(s->time_to).c_str(), TimeToString(timestamp).c_str(), TimeToString(lw).c_str());
2793
2794 assert(lw < timestamp);
2795
2796 ::close(fd);
2797
2798 return HS_SUCCESS;
2799}
static int ReadRecord(const char *file_name, int fd, int offset, int recsize, int irec, char *rec)
Here is the call graph for this function:

◆ write_event()

int HsFileSchema::write_event ( const time_t  t,
const char data,
const int  data_size 
)
virtual

Implements HsSchema.

Definition at line 2456 of file history_schema.cxx.

2457{
2458 HsFileSchema* s = this;
2459
2460 int status;
2461
2462 if (s->writer_fd < 0) {
2463 s->writer_fd = open(s->file_name.c_str(), O_RDWR);
2464 if (s->writer_fd < 0) {
2465 cm_msg(MERROR, "FileHistory::write_event", "Cannot write to \'%s\', open() errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2466 return HS_FILE_ERROR;
2467 }
2468
2469 int file_size = lseek(s->writer_fd, 0, SEEK_END);
2470
2471 int nrec = (file_size - s->data_offset)/s->record_size;
2472 if (nrec < 0)
2473 nrec = 0;
2474 int data_end = s->data_offset + nrec*s->record_size;
2475
2476 //printf("file_size %d, nrec %d, data_end %d\n", file_size, nrec, data_end);
2477
2478 if (data_end != file_size) {
2479 if (nrec > 0)
2480 cm_msg(MERROR, "FileHistory::write_event", "File \'%s\' may be truncated, data offset %d, record size %d, file size: %d, should be %d, truncating the file", s->file_name.c_str(), s->data_offset, s->record_size, file_size, data_end);
2481
2483 if (status < 0) {
2484 cm_msg(MERROR, "FileHistory::write_event", "Cannot seek \'%s\' to offset %d, lseek() errno %d (%s)", s->file_name.c_str(), data_end, errno, strerror(errno));
2485 return HS_FILE_ERROR;
2486 }
2488 if (status < 0) {
2489 cm_msg(MERROR, "FileHistory::write_event", "Cannot truncate \'%s\' to size %d, ftruncate() errno %d (%s)", s->file_name.c_str(), data_end, errno, strerror(errno));
2490 return HS_FILE_ERROR;
2491 }
2492 }
2493 }
2494
2495 int expected_size = s->record_size - 4;
2496
2497 // sanity check: record_size and n_bytes are computed from the byte counts in the file header
2498 assert(expected_size == s->n_bytes);
2499
2500 if (s->last_size == 0)
2502
2503 if (data_size != s->last_size) {
2504 cm_msg(MERROR, "FileHistory::write_event", "Event \'%s\' data size mismatch, expected %d bytes, got %d bytes, previously %d bytes", s->event_name.c_str(), expected_size, data_size, s->last_size);
2505 //printf("schema:\n");
2506 //s->print();
2507
2508 if (data_size < expected_size)
2509 return HS_FILE_ERROR;
2510
2511 // truncate for now
2512 // data_size = expected_size;
2513 s->last_size = data_size;
2514 }
2515
2516 int size = 4 + expected_size;
2517
2518 if (size != s->record_buffer_size) {
2519 s->record_buffer = (char*)realloc(s->record_buffer, size);
2520 assert(s->record_buffer != NULL);
2521 s->record_buffer_size = size;
2522 }
2523
2524 memcpy(s->record_buffer, &t, 4);
2526
2527 status = write(s->writer_fd, s->record_buffer, size);
2528 if (status != size) {
2529 cm_msg(MERROR, "FileHistory::write_event", "Cannot write to \'%s\', write(%d) returned %d, errno %d (%s)", s->file_name.c_str(), size, status, errno, strerror(errno));
2530 return HS_FILE_ERROR;
2531 }
2532
2533#if 0
2534 status = write(s->writer_fd, &t, 4);
2535 if (status != 4) {
2536 cm_msg(MERROR, "FileHistory::write_event", "Cannot write to \'%s\', write(timestamp) errno %d (%s)", s->file_name.c_str(), errno, strerror(errno));
2537 return HS_FILE_ERROR;
2538 }
2539
2541 if (status != expected_size) {
2542 cm_msg(MERROR, "FileHistory::write_event", "Cannot write to \'%s\', write(%d) errno %d (%s)", s->file_name.c_str(), data_size, errno, strerror(errno));
2543 return HS_FILE_ERROR;
2544 }
2545#endif
2546
2547 return HS_SUCCESS;
2548}
#define write(n, a, f, d)
Here is the call graph for this function:

Member Data Documentation

◆ data_offset

int HsFileSchema::data_offset = 0

Definition at line 744 of file history_schema.cxx.

◆ file_name

std::string HsFileSchema::file_name

Definition at line 742 of file history_schema.cxx.

◆ last_size

int HsFileSchema::last_size = 0

Definition at line 745 of file history_schema.cxx.

◆ record_buffer

char* HsFileSchema::record_buffer = NULL

Definition at line 748 of file history_schema.cxx.

◆ record_buffer_size

int HsFileSchema::record_buffer_size = 0

Definition at line 747 of file history_schema.cxx.

◆ record_size

int HsFileSchema::record_size = 0

Definition at line 743 of file history_schema.cxx.

◆ writer_fd

int HsFileSchema::writer_fd = -1

Definition at line 746 of file history_schema.cxx.


The documentation for this struct was generated from the following file: