MIDAS
Loading...
Searching...
No Matches
FileHistory Class Reference
Inheritance diagram for FileHistory:
Collaboration diagram for FileHistory:

Public Member Functions

 FileHistory ()
 
int hs_connect (const char *connect_string)
 returns HS_SUCCESS
 
int hs_disconnect ()
 disconnect from history, returns HS_SUCCESS
 
int hs_clear_cache ()
 clear internal cache, returns HS_SUCCESS
 
int read_schema (HsSchemaVector *sv, const char *event_name, const time_t timestamp)
 
HsSchemanew_event (const char *event_name, time_t timestamp, int ntags, const TAG tags[])
 
- Public Member Functions inherited from SchemaHistoryBase
 SchemaHistoryBase ()
 
virtual ~SchemaHistoryBase ()
 
virtual int hs_set_debug (int debug)
 set debug level, returns previous debug level
 
int hs_define_event (const char *event_name, time_t timestamp, int ntags, const TAG tags[])
 see hs_define_event(), returns HS_SUCCESS or HS_FILE_ERROR
 
int hs_write_event (const char *event_name, time_t timestamp, int buffer_size, const char *buffer)
 see hs_write_event(), returns HS_SUCCESS or HS_FILE_ERROR
 
int hs_flush_buffers ()
 flush buffered data to storage where it is visible to mhttpd
 
int hs_clear_cache ()
 clear internal cache, returns HS_SUCCESS
 
int hs_get_events (time_t t, std::vector< std::string > *pevents)
 get list of events that exist(ed) at given time and later (value 0 means "return all events from beginning of time"), returns HS_SUCCESS
 
int hs_get_tags (const char *event_name, time_t t, std::vector< TAG > *ptags)
 get list of history variables for given event (use event names returned by hs_get_events()) that exist(ed) at given time and later (value 0 means "all variables for this event that ever existed"), also see hs_get_tags(), returns HS_SUCCESS
 
int hs_get_last_written (time_t timestamp, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], time_t last_written[])
 
int hs_read_buffer (time_t start_time, time_t end_time, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], MidasHistoryBufferInterface *buffer[], int hs_status[])
 returns HS_SUCCESS
 
int hs_read (time_t start_time, time_t end_time, time_t interval, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int st[])
 see hs_read(), returns HS_SUCCESS
 
int hs_read_binned (time_t start_time, time_t end_time, int num_bins, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], int *count_bins[], double *mean_bins[], double *rms_bins[], double *min_bins[], double *max_bins[], time_t *bins_first_time[], double *bins_first_value[], time_t *bins_last_time[], double *bins_last_value[], time_t last_time[], double last_value[], int st[])
 returns HS_SUCCESS
 
- Public Member Functions inherited from MidasHistoryInterface
 MidasHistoryInterface ()
 history type: MIDAS, ODBC, SQLITE, etc
 
virtual ~MidasHistoryInterface ()
 

Protected Member Functions

int create_file (const char *event_name, time_t timestamp, int ntags, const TAG tags[], std::string *filenamep)
 
HsFileSchemaread_file_schema (const char *filename)
 
int read_file_list (bool *pchanged)
 
void clear_file_list ()
 

Protected Attributes

std::string fPath
 
time_t fPathLastMtime
 
std::vector< std::string > fSortedFiles
 
std::vector< boolfSortedRead
 
time_t fConfMaxFileAge
 
double fConfMaxFileSize
 
- Protected Attributes inherited from SchemaHistoryBase
int fDebug
 
std::string fConnectString
 
HsSchemaVector fWriterCurrentSchema
 
std::vector< HsSchema * > fEvents
 
HsSchemaVector fSchema
 

Additional Inherited Members

- Public Attributes inherited from MidasHistoryInterface
char name [NAME_LENGTH]
 
char type [NAME_LENGTH]
 history channel name
 

Detailed Description

Definition at line 6358 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ FileHistory()

FileHistory::FileHistory ( )
inline

Definition at line 6369 of file history_schema.cxx.

6370 {
6372 fConfMaxFileSize = 100*MiB;
6373
6374 fPathLastMtime = 0;
6375 }
const time_t kMonth
const double MiB

Member Function Documentation

◆ clear_file_list()

void FileHistory::clear_file_list ( )
protected

Definition at line 6428 of file history_schema.cxx.

6429{
6430 fPathLastMtime = 0;
6431 fSortedFiles.clear();
6432 fSortedRead.clear();
6433}
std::vector< std::string > fSortedFiles
std::vector< bool > fSortedRead
Here is the caller graph for this function:

◆ create_file()

int FileHistory::create_file ( const char event_name,
time_t  timestamp,
int  ntags,
const TAG  tags[],
std::string *  filenamep 
)
protected

Definition at line 6743 of file history_schema.cxx.

6744{
6745 if (fDebug)
6746 printf("FileHistory::create_file: event [%s]\n", event_name);
6747
6748 // NB: file names are constructed in such a way
6749 // that when sorted lexicographically ("ls -1 | sort")
6750 // they *also* become sorted by time
6751
6752 struct tm tm;
6753 localtime_r(&timestamp, &tm); // somebody must call tzset() before this.
6754
6755 char buf[256];
6756 strftime(buf, sizeof(buf), "%Y%m%d", &tm);
6757
6758 std::string filename;
6759 filename += fPath;
6760 filename += "mhf_";
6761 filename += TimeToString(timestamp);
6762 filename += "_";
6763 filename += buf;
6764 filename += "_";
6765 filename += MidasNameToFileName(event_name);
6766
6767 std::string try_filename = filename + ".dat";
6768
6769 FILE *fp = NULL;
6770 for (int itry=0; itry<10; itry++) {
6771 if (itry > 0) {
6772 char s[256];
6773 sprintf(s, "_%d", rand());
6774 try_filename = filename + s + ".dat";
6775 }
6776
6777 fp = fopen(try_filename.c_str(), "r");
6778 if (fp != NULL) {
6779 // this file already exists, try with a different name
6780 fclose(fp);
6781 continue;
6782 }
6783
6784 fp = fopen(try_filename.c_str(), "w");
6785 if (fp == NULL) {
6786 // somehow cannot create this file, try again
6787 cm_msg(MERROR, "FileHistory::create_file", "Error: Cannot create file \'%s\' for event \'%s\', fopen() errno %d (%s)", try_filename.c_str(), event_name, errno, strerror(errno));
6788 continue;
6789 }
6790
6791 // file opened
6792 break;
6793 }
6794
6795 if (fp == NULL) {
6796 // somehow cannot create any file, whine!
6797 cm_msg(MERROR, "FileHistory::create_file", "Error: Cannot create file \'%s\' for event \'%s\'", filename.c_str(), event_name);
6798 return HS_FILE_ERROR;
6799 }
6800
6801 std::string ss;
6802
6803 ss += "version: 2.0\n";
6804 ss += "event_name: ";
6805 ss += event_name;
6806 ss += "\n";
6807 ss += "time: ";
6808 ss += TimeToString(timestamp);
6809 ss += "\n";
6810
6811 int recsize = 0;
6812
6813 ss += "tag: /DWORD 1 4 /timestamp\n";
6814 recsize += 4;
6815
6816 bool padded = false;
6817 int offset = 0;
6818
6819 bool xdebug = false; // (strcmp(event_name, "u_Beam") == 0);
6820
6821 for (int i=0; i<ntags; i++) {
6822 int tsize = rpc_tid_size(tags[i].type);
6823 int n_bytes = tags[i].n_data*tsize;
6824 int xalign = (offset % tsize);
6825
6826 if (xdebug)
6827 printf("tag %d, tsize %d, n_bytes %d, xalign %d\n", i, tsize, n_bytes, xalign);
6828
6829#if 0
6830 // looks like history data does not do alignement and padding
6831 if (xalign != 0) {
6832 padded = true;
6833 int pad_bytes = tsize - xalign;
6834 assert(pad_bytes > 0);
6835
6836 ss += "tag: ";
6837 ss += "XPAD";
6838 ss += " ";
6839 ss += SmallIntToString(1);
6840 ss += " ";
6842 ss += " ";
6843 ss += "pad_";
6844 ss += SmallIntToString(i);
6845 ss += "\n";
6846
6847 offset += pad_bytes;
6848 recsize += pad_bytes;
6849
6850 assert((offset % tsize) == 0);
6851 fprintf(stderr, "FIXME: need to debug padding!\n");
6852 //abort();
6853 }
6854#endif
6855
6856 ss += "tag: ";
6857 ss += rpc_tid_name(tags[i].type);
6858 ss += " ";
6859 ss += SmallIntToString(tags[i].n_data);
6860 ss += " ";
6861 ss += SmallIntToString(n_bytes);
6862 ss += " ";
6863 ss += tags[i].name;
6864 ss += "\n";
6865
6866 recsize += n_bytes;
6867 offset += n_bytes;
6868 }
6869
6870 ss += "record_size: ";
6872 ss += "\n";
6873
6874 // reserve space for "data_offset: ..."
6875 int sslength = ss.length() + 127;
6876
6877 int block = 1024;
6878 int nb = (sslength + block - 1)/block;
6879 int data_offset = block * nb;
6880
6881 ss += "data_offset: ";
6883 ss += "\n";
6884
6885 fprintf(fp, "%s", ss.c_str());
6886
6887 fclose(fp);
6888
6889 if (1 && padded) {
6890 printf("Schema in file %s has padding:\n", try_filename.c_str());
6891 printf("%s", ss.c_str());
6892 }
6893
6894 if (filenamep)
6896
6897 return HS_SUCCESS;
6898}
std::string fPath
char type[NAME_LENGTH]
history channel name
Definition history.h:112
#define HS_SUCCESS
Definition midas.h:727
#define HS_FILE_ERROR
Definition midas.h:728
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
const char * rpc_tid_name(INT id)
Definition midas.cxx:11772
INT rpc_tid_size(INT id)
Definition midas.cxx:11765
static std::string TimeToString(time_t t)
static std::string SmallIntToString(int i)
static std::string MidasNameToFileName(const char *s)
INT i
Definition mdump.cxx:32
static int offset
Definition mgd.cxx:1500
static FILE * fp
MUTEX_T * tm
Definition odbedit.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
DWORD n_data
Definition midas.h:1235
char name[NAME_LENGTH]
Definition midas.h:1233
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hs_clear_cache()

int FileHistory::hs_clear_cache ( )
virtual

clear internal cache, returns HS_SUCCESS

Implements MidasHistoryInterface.

Definition at line 6409 of file history_schema.cxx.

6410{
6411 if (fDebug)
6412 printf("FileHistory::hs_clear_cache!\n");
6413 fPathLastMtime = 0;
6415}
int hs_clear_cache()
clear internal cache, returns HS_SUCCESS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hs_connect()

int FileHistory::hs_connect ( const char connect_string)
virtual

returns HS_SUCCESS

Implements SchemaHistoryBase.

Definition at line 6390 of file history_schema.cxx.

6391{
6392 if (fDebug)
6393 printf("hs_connect [%s]!\n", connect_string);
6394
6395 hs_disconnect();
6396
6399
6400 // add trailing '/'
6401 if (fPath.length() > 0) {
6402 if (fPath[fPath.length()-1] != DIR_SEPARATOR)
6404 }
6405
6406 return HS_SUCCESS;
6407}
int hs_disconnect()
disconnect from history, returns HS_SUCCESS
#define DIR_SEPARATOR
Definition midas.h:193
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the call graph for this function:

◆ hs_disconnect()

int FileHistory::hs_disconnect ( )
virtual

disconnect from history, returns HS_SUCCESS

Implements SchemaHistoryBase.

Definition at line 6417 of file history_schema.cxx.

6418{
6419 if (fDebug)
6420 printf("FileHistory::hs_disconnect!\n");
6421
6424
6425 return HS_SUCCESS;
6426}
int hs_clear_cache()
clear internal cache, returns HS_SUCCESS
int hs_flush_buffers()
flush buffered data to storage where it is visible to mhttpd
Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_event()

HsSchema * FileHistory::new_event ( const char event_name,
time_t  timestamp,
int  ntags,
const TAG  tags[] 
)
virtual

Implements SchemaHistoryBase.

Definition at line 6596 of file history_schema.cxx.

6597{
6598 if (fDebug)
6599 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d\n", event_name, TimeToString(timestamp).c_str(), ntags);
6600
6601 int status;
6602
6603 HsFileSchema* s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6604
6605 if (!s) {
6606 //printf("hs_define_event: no schema for event %s\n", event_name);
6607 status = read_schema(&fWriterCurrentSchema, event_name, timestamp);
6608 if (status != HS_SUCCESS)
6609 return NULL;
6610 s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6611 } else {
6612 //printf("hs_define_event: already have schema for event %s\n", s->fEventName.c_str());
6613 }
6614
6615 bool xdebug = false;
6616
6617 if (s) { // is existing schema the same as new schema?
6618 bool same = true;
6619
6620 if (same)
6621 if (s->fEventName != event_name) {
6622 if (xdebug)
6623 printf("AAA: [%s] [%s]!\n", s->fEventName.c_str(), event_name);
6624 same = false;
6625 }
6626
6627 if (same)
6628 if (s->fVariables.size() != (unsigned)ntags) {
6629 if (xdebug)
6630 printf("BBB: event [%s]: ntags: %d -> %d!\n", event_name, (int)s->fVariables.size(), ntags);
6631 same = false;
6632 }
6633
6634 if (same)
6635 for (unsigned i=0; i<s->fVariables.size(); i++) {
6636 if (s->fVariables[i].name != tags[i].name) {
6637 if (xdebug)
6638 printf("CCC: event [%s] index %d: name [%s] -> [%s]!\n", event_name, i, s->fVariables[i].name.c_str(), tags[i].name);
6639 same = false;
6640 }
6641 if (s->fVariables[i].type != (int)tags[i].type) {
6642 if (xdebug)
6643 printf("DDD: event [%s] index %d: type %d -> %d!\n", event_name, i, s->fVariables[i].type, tags[i].type);
6644 same = false;
6645 }
6646 if (s->fVariables[i].n_data != (int)tags[i].n_data) {
6647 if (xdebug)
6648 printf("EEE: event [%s] index %d: n_data %d -> %d!\n", event_name, i, s->fVariables[i].n_data, tags[i].n_data);
6649 same = false;
6650 }
6651 if (!same)
6652 break;
6653 }
6654
6655 if (!same) {
6656 if (xdebug) {
6657 printf("*** Schema for event %s has changed!\n", event_name);
6658
6659 printf("*** Old schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6660 s->print();
6661 printf("*** New tags:\n");
6662 PrintTags(ntags, tags);
6663 }
6664
6665 if (fDebug)
6666 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema mismatch, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags);
6667
6668 s = NULL;
6669 }
6670 }
6671
6672 if (s) {
6673 // maybe this schema is too old - rotate files every so often
6674 time_t age = timestamp - s->fTimeFrom;
6675 //printf("*** age %s (%.1f months), timestamp %s, time_from %s, file %s\n", TimeToString(age).c_str(), (double)age/(double)kMonth, TimeToString(timestamp).c_str(), TimeToString(s->fTimeFrom).c_str(), s->fFileName.c_str());
6676 if (age > fConfMaxFileAge) {
6677 if (fDebug)
6678 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema is too old, age %.1f months, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags, (double)age/(double)kMonth);
6679
6680 // force creation of a new file
6681 s = NULL;
6682 }
6683 }
6684
6685 if (s) {
6686 // maybe this file is too big - rotate files to limit maximum size
6687 double size = ss_file_size(s->fFileName.c_str());
6688 //printf("*** size %.0f, file %s\n", size, s->fFileName.c_str());
6689 if (size > fConfMaxFileSize) {
6690 if (fDebug)
6691 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: file too big, size %.1f MiBytes, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags, size/MiB);
6692
6693 // force creation of a new file
6694 s = NULL;
6695 }
6696 }
6697
6698 if (!s) {
6699 std::string filename;
6700
6701 status = create_file(event_name, timestamp, ntags, tags, &filename);
6702 if (status != HS_SUCCESS)
6703 return NULL;
6704
6705 HsFileSchema* ss = read_file_schema(filename.c_str());
6706 if (!ss) {
6707 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6708 return NULL;
6709 }
6710
6712
6713 s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6714
6715 if (!s) {
6716 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6717 return NULL;
6718 }
6719
6720 if (xdebug) {
6721 printf("*** New schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6722 s->print();
6723 }
6724 }
6725
6726 assert(s != NULL);
6727
6728#if 0
6729 {
6730 printf("schema for [%s] is %p\n", event_name, s);
6731 if (s)
6732 s->print();
6733 }
6734#endif
6735
6736 HsFileSchema* e = new HsFileSchema();
6737
6738 *e = *s; // make a copy of the schema
6739
6740 return e;
6741}
HsFileSchema * read_file_schema(const char *filename)
int create_file(const char *event_name, time_t timestamp, int ntags, const TAG tags[], std::string *filenamep)
int read_schema(HsSchemaVector *sv, const char *event_name, const time_t timestamp)
std::string fFileName
void print(bool print_tags=true) const
std::vector< HsSchemaEntry > fVariables
std::string fEventName
HsSchema * find_event(const char *event_name, const time_t timestamp, int debug=0)
void add(HsSchema *s)
HsSchemaVector fWriterCurrentSchema
double ss_file_size(const char *path)
Definition system.cxx:6978
static void PrintTags(int ntags, const TAG tags[])
DWORD status
Definition odbhist.cxx:39
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:

◆ read_file_list()

int FileHistory::read_file_list ( bool pchanged)
protected

Definition at line 6435 of file history_schema.cxx.

6436{
6437 int status;
6438 double start_time = ss_time_sec();
6439
6440 if (pchanged)
6441 *pchanged = false;
6442
6443 struct stat stat_buf;
6444 status = stat(fPath.c_str(), &stat_buf);
6445 if (status != 0) {
6446 cm_msg(MERROR, "FileHistory::read_file_list", "Cannot stat(%s), errno %d (%s)", fPath.c_str(), errno, strerror(errno));
6447 return HS_FILE_ERROR;
6448 }
6449
6450 //printf("dir [%s], mtime: %d %d last: %d %d, mtime %s", fPath.c_str(), stat_buf.st_mtimespec.tv_sec, stat_buf.st_mtimespec.tv_nsec, last_mtimespec.tv_sec, last_mtimespec.tv_nsec, ctime(&stat_buf.st_mtimespec.tv_sec));
6451
6452 if (stat_buf.st_mtime == fPathLastMtime) {
6453 if (fDebug)
6454 printf("FileHistory::read_file_list: history directory \"%s\" mtime %d did not change\n", fPath.c_str(), int(stat_buf.st_mtime));
6455 return HS_SUCCESS;
6456 }
6457
6458 fPathLastMtime = stat_buf.st_mtime;
6459
6460 if (fDebug)
6461 printf("FileHistory::read_file_list: reading list of history files in \"%s\"\n", fPath.c_str());
6462
6463 std::vector<std::string> flist;
6464
6465 ss_file_find(fPath.c_str(), "mhf_*.dat", &flist);
6466
6467 double ls_time = ss_time_sec();
6468 double ls_elapsed = ls_time - start_time;
6469 if (ls_elapsed > 5.000) {
6470 cm_msg(MINFO, "FileHistory::read_file_list", "\"ls -l\" of \"%s\" took %.1f sec", fPath.c_str(), ls_elapsed);
6472 }
6473
6474 // note: reverse iterator is used to sort filenames by time, newest first
6475 std::sort(flist.rbegin(), flist.rend());
6476
6477#if 0
6478 {
6479 printf("file names sorted by time:\n");
6480 for (unsigned i=0; i<flist.size(); i++) {
6481 printf("%d: %s\n", i, flist[i].c_str());
6482 }
6483 }
6484#endif
6485
6486 std::vector<bool> fread;
6487 fread.resize(flist.size()); // fill with "false"
6488
6489 // loop over the old list of files,
6490 // for files we already read, loop over new file
6491 // list and mark the same file as read. K.O.
6492 for (size_t j=0; j<fSortedFiles.size(); j++) {
6493 if (fSortedRead[j]) {
6494 for (size_t i=0; i<flist.size(); i++) {
6495 if (flist[i] == fSortedFiles[j]) {
6496 fread[i] = true;
6497 break;
6498 }
6499 }
6500 }
6501 }
6502
6505
6506 if (pchanged)
6507 *pchanged = true;
6508
6509 return HS_SUCCESS;
6510}
#define MINFO
Definition midas.h:560
double ss_time_sec()
Definition system.cxx:3467
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6719
INT cm_msg_flush_buffer()
Definition midas.cxx:865
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_file_schema()

HsFileSchema * FileHistory::read_file_schema ( const char filename)
protected

Definition at line 6900 of file history_schema.cxx.

6901{
6902 if (fDebug)
6903 printf("FileHistory::read_file_schema: file %s\n", filename);
6904
6905 FILE* fp = fopen(filename, "r");
6906 if (!fp) {
6907 cm_msg(MERROR, "FileHistory::read_file_schema", "Cannot read \'%s\', fopen() errno %d (%s)", filename, errno, strerror(errno));
6908 return NULL;
6909 }
6910
6911 HsFileSchema* s = NULL;
6912
6913 // File format looks like this:
6914 // version: 2.0
6915 // event_name: u_Beam
6916 // time: 1023174012
6917 // tag: /DWORD 1 4 /timestamp
6918 // tag: FLOAT 1 4 B1
6919 // ...
6920 // tag: FLOAT 1 4 Ref Heater
6921 // record_size: 84
6922 // data_offset: 1024
6923
6924 int rd_recsize = 0;
6925 int offset = 0;
6926
6927 while (1) {
6928 char buf[1024];
6929 char* b = fgets(buf, sizeof(buf), fp);
6930
6931 //printf("read: %s\n", b);
6932
6933 if (!b) {
6934 break; // end of file
6935 }
6936
6937 char*bb;
6938
6939 bb = strchr(b, '\n');
6940 if (bb)
6941 *bb = 0;
6942
6943 bb = strchr(b, '\r');
6944 if (bb)
6945 *bb = 0;
6946
6947 bb = strstr(b, "version: 2.0");
6948 if (bb == b) {
6949 s = new HsFileSchema();
6950 assert(s);
6951
6952 s->fFileName = filename;
6953 continue;
6954 }
6955
6956 if (!s) {
6957 // malformed history file
6958 break;
6959 }
6960
6961 bb = strstr(b, "event_name: ");
6962 if (bb == b) {
6963 s->fEventName = bb + 12;
6964 continue;
6965 }
6966
6967 bb = strstr(b, "time: ");
6968 if (bb == b) {
6969 s->fTimeFrom = strtoul(bb + 6, NULL, 10);
6970 continue;
6971 }
6972
6973 // tag format is like this:
6974 //
6975 // tag: FLOAT 1 4 Ref Heater
6976 //
6977 // "FLOAT" is the MIDAS type, "/DWORD" is special tag for the timestamp
6978 // "1" is the number of array elements
6979 // "4" is the total tag size in bytes (n_data*tid_size)
6980 // "Ref Heater" is the tag name
6981
6982 bb = strstr(b, "tag: ");
6983 if (bb == b) {
6984 bb += 5; // now points to the tag MIDAS type
6985 const char* midas_type = bb;
6986 char* bbb = strchr(bb, ' ');
6987 if (bbb) {
6988 *bbb = 0;
6989 HsSchemaEntry t;
6990 if (midas_type[0] == '/') {
6991 t.type = 0;
6992 } else {
6994 if (t.type == 0) {
6995 cm_msg(MERROR, "FileHistory::read_file_schema", "Unknown MIDAS data type \'%s\' in history file \'%s\'", midas_type, filename);
6996 if (s)
6997 delete s;
6998 s = NULL;
6999 break;
7000 }
7001 }
7002 bbb++;
7003 while (*bbb == ' ')
7004 bbb++;
7005 if (*bbb) {
7006 t.n_data = strtoul(bbb, &bbb, 10);
7007 while (*bbb == ' ')
7008 bbb++;
7009 if (*bbb) {
7010 t.n_bytes = strtoul(bbb, &bbb, 10);
7011 while (*bbb == ' ')
7012 bbb++;
7013 t.name = bbb;
7014 }
7015 }
7016
7017 if (midas_type[0] != '/') {
7018 s->fVariables.push_back(t);
7019 s->fOffsets.push_back(offset);
7020 offset += t.n_bytes;
7021 }
7022
7023 rd_recsize += t.n_bytes;
7024 }
7025 continue;
7026 }
7027
7028 bb = strstr(b, "record_size: ");
7029 if (bb == b) {
7030 s->fRecordSize = atoi(bb + 12);
7031 continue;
7032 }
7033
7034 bb = strstr(b, "data_offset: ");
7035 if (bb == b) {
7036 s->fDataOffset = atoi(bb + 12);
7037 // data offset is the last entry in the file
7038 break;
7039 }
7040 }
7041
7042 fclose(fp);
7043
7044 if (!s) {
7045 cm_msg(MERROR, "FileHistory::read_file_schema", "Malformed history schema in \'%s\', maybe it is not a history file", filename);
7046 return NULL;
7047 }
7048
7049 if (rd_recsize != s->fRecordSize) {
7050 cm_msg(MERROR, "FileHistory::read_file_schema", "Record size mismatch in history schema from \'%s\', file says %d while total of all tags is %d", filename, s->fRecordSize, rd_recsize);
7051 if (s)
7052 delete s;
7053 return NULL;
7054 }
7055
7056 if (!s) {
7057 cm_msg(MERROR, "FileHistory::read_file_schema", "Could not read history schema from \'%s\', maybe it is not a history file", filename);
7058 if (s)
7059 delete s;
7060 return NULL;
7061 }
7062
7063 if (fDebug > 1)
7064 s->print();
7065
7066 return s;
7067}
std::vector< int > fOffsets
int rpc_name_tid(const char *name)
Definition midas.cxx:11786
int type
int n_data
std::string name
int n_bytes
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_schema()

int FileHistory::read_schema ( HsSchemaVector sv,
const char event_name,
const time_t  timestamp 
)
virtual

Implements SchemaHistoryBase.

Definition at line 6512 of file history_schema.cxx.

6513{
6514 if (fDebug)
6515 printf("FileHistory::read_schema: event [%s] at time %s\n", event_name, TimeToString(timestamp).c_str());
6516
6517 if (fSchema.size() == 0) {
6518 if (fDebug)
6519 printf("FileHistory::read_schema: schema is empty, do a full reload from disk\n");
6521 }
6522
6524 DWORD old_timeout = 0;
6527
6528 bool changed = false;
6529
6531
6532 if (status != HS_SUCCESS) {
6534 return status;
6535 }
6536
6537 if (!changed) {
6538 if ((*sv).find_event(event_name, timestamp)) {
6539 if (fDebug)
6540 printf("FileHistory::read_schema: event [%s] at time %s, no new history files, already have this schema\n", event_name, TimeToString(timestamp).c_str());
6542 return HS_SUCCESS;
6543 }
6544 }
6545
6546 double start_time = ss_time_sec();
6547
6548 int count_read = 0;
6549
6550 for (unsigned i=0; i<fSortedFiles.size(); i++) {
6551 std::string file_name = fPath + fSortedFiles[i];
6552 if (fSortedRead[i])
6553 continue;
6554 //bool dupe = false;
6555 //for (unsigned ss=0; ss<sv->size(); ss++) {
6556 // HsFileSchema* ssp = (HsFileSchema*)(*sv)[ss];
6557 // if (file_name == ssp->fFileName) {
6558 // dupe = true;
6559 // break;
6560 // }
6561 //}
6562 //if (dupe)
6563 // continue;
6564 fSortedRead[i] = true;
6566 if (!s)
6567 continue;
6568 sv->add(s);
6569 count_read++;
6570
6571 if (event_name) {
6572 if (s->fEventName == event_name) {
6573 //printf("file %s event_name %s time %s, age %f\n", file_name.c_str(), s->fEventName.c_str(), TimeToString(s->fTimeFrom).c_str(), double(timestamp - s->fTimeFrom));
6574 if (s->fTimeFrom <= timestamp) {
6575 // this file is older than the time requested,
6576 // subsequent files will be even older,
6577 // we can stop reading here.
6578 break;
6579 }
6580 }
6581 }
6582 }
6583
6584 double end_time = ss_time_sec();
6585 double read_elapsed = end_time - start_time;
6586 if (read_elapsed > 5.000) {
6587 cm_msg(MINFO, "FileHistory::read_schema", "Loading schema for event \"%s\" timestamp %s, reading %d history files took %.1f sec", event_name, TimeToString(timestamp).c_str(), count_read, read_elapsed);
6589 }
6590
6592
6593 return HS_SUCCESS;
6594}
#define FALSE
Definition cfortran.h:309
int read_file_list(bool *pchanged)
unsigned size() const
HsSchemaVector fSchema
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3325
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3283
unsigned int DWORD
Definition mcstd.h:51
DWORD BOOL
Definition midas.h:105
char file_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ fConfMaxFileAge

time_t FileHistory::fConfMaxFileAge
protected

Definition at line 6365 of file history_schema.cxx.

◆ fConfMaxFileSize

double FileHistory::fConfMaxFileSize
protected

Definition at line 6366 of file history_schema.cxx.

◆ fPath

std::string FileHistory::fPath
protected

Definition at line 6361 of file history_schema.cxx.

◆ fPathLastMtime

time_t FileHistory::fPathLastMtime
protected

Definition at line 6362 of file history_schema.cxx.

◆ fSortedFiles

std::vector<std::string> FileHistory::fSortedFiles
protected

Definition at line 6363 of file history_schema.cxx.

◆ fSortedRead

std::vector<bool> FileHistory::fSortedRead
protected

Definition at line 6364 of file history_schema.cxx.


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