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 6285 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ FileHistory()

FileHistory::FileHistory ( )
inline

Definition at line 6296 of file history_schema.cxx.

6297 {
6299 fConfMaxFileSize = 100*MiB;
6300
6301 fPathLastMtime = 0;
6302 }
const time_t kMonth
const double MiB

Member Function Documentation

◆ clear_file_list()

void FileHistory::clear_file_list ( )
protected

Definition at line 6355 of file history_schema.cxx.

6356{
6357 fPathLastMtime = 0;
6358 fSortedFiles.clear();
6359 fSortedRead.clear();
6360}
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 6670 of file history_schema.cxx.

6671{
6672 if (fDebug)
6673 printf("FileHistory::create_file: event [%s]\n", event_name);
6674
6675 // NB: file names are constructed in such a way
6676 // that when sorted lexicographically ("ls -1 | sort")
6677 // they *also* become sorted by time
6678
6679 struct tm tm;
6680 localtime_r(&timestamp, &tm); // somebody must call tzset() before this.
6681
6682 char buf[256];
6683 strftime(buf, sizeof(buf), "%Y%m%d", &tm);
6684
6685 std::string filename;
6686 filename += fPath;
6687 filename += "mhf_";
6688 filename += TimeToString(timestamp);
6689 filename += "_";
6690 filename += buf;
6691 filename += "_";
6692 filename += MidasNameToFileName(event_name);
6693
6694 std::string try_filename = filename + ".dat";
6695
6696 FILE *fp = NULL;
6697 for (int itry=0; itry<10; itry++) {
6698 if (itry > 0) {
6699 char s[256];
6700 sprintf(s, "_%d", rand());
6701 try_filename = filename + s + ".dat";
6702 }
6703
6704 fp = fopen(try_filename.c_str(), "r");
6705 if (fp != NULL) {
6706 // this file already exists, try with a different name
6707 fclose(fp);
6708 continue;
6709 }
6710
6711 fp = fopen(try_filename.c_str(), "w");
6712 if (fp == NULL) {
6713 // somehow cannot create this file, try again
6714 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));
6715 continue;
6716 }
6717
6718 // file opened
6719 break;
6720 }
6721
6722 if (fp == NULL) {
6723 // somehow cannot create any file, whine!
6724 cm_msg(MERROR, "FileHistory::create_file", "Error: Cannot create file \'%s\' for event \'%s\'", filename.c_str(), event_name);
6725 return HS_FILE_ERROR;
6726 }
6727
6728 std::string ss;
6729
6730 ss += "version: 2.0\n";
6731 ss += "event_name: ";
6732 ss += event_name;
6733 ss += "\n";
6734 ss += "time: ";
6735 ss += TimeToString(timestamp);
6736 ss += "\n";
6737
6738 int recsize = 0;
6739
6740 ss += "tag: /DWORD 1 4 /timestamp\n";
6741 recsize += 4;
6742
6743 bool padded = false;
6744 int offset = 0;
6745
6746 bool xdebug = false; // (strcmp(event_name, "u_Beam") == 0);
6747
6748 for (int i=0; i<ntags; i++) {
6749 int tsize = rpc_tid_size(tags[i].type);
6750 int n_bytes = tags[i].n_data*tsize;
6751 int xalign = (offset % tsize);
6752
6753 if (xdebug)
6754 printf("tag %d, tsize %d, n_bytes %d, xalign %d\n", i, tsize, n_bytes, xalign);
6755
6756#if 0
6757 // looks like history data does not do alignement and padding
6758 if (xalign != 0) {
6759 padded = true;
6760 int pad_bytes = tsize - xalign;
6761 assert(pad_bytes > 0);
6762
6763 ss += "tag: ";
6764 ss += "XPAD";
6765 ss += " ";
6766 ss += SmallIntToString(1);
6767 ss += " ";
6769 ss += " ";
6770 ss += "pad_";
6771 ss += SmallIntToString(i);
6772 ss += "\n";
6773
6774 offset += pad_bytes;
6775 recsize += pad_bytes;
6776
6777 assert((offset % tsize) == 0);
6778 fprintf(stderr, "FIXME: need to debug padding!\n");
6779 //abort();
6780 }
6781#endif
6782
6783 ss += "tag: ";
6784 ss += rpc_tid_name(tags[i].type);
6785 ss += " ";
6786 ss += SmallIntToString(tags[i].n_data);
6787 ss += " ";
6788 ss += SmallIntToString(n_bytes);
6789 ss += " ";
6790 ss += tags[i].name;
6791 ss += "\n";
6792
6793 recsize += n_bytes;
6794 offset += n_bytes;
6795 }
6796
6797 ss += "record_size: ";
6799 ss += "\n";
6800
6801 // reserve space for "data_offset: ..."
6802 int sslength = ss.length() + 127;
6803
6804 int block = 1024;
6805 int nb = (sslength + block - 1)/block;
6806 int data_offset = block * nb;
6807
6808 ss += "data_offset: ";
6809 ss += SmallIntToString(data_offset);
6810 ss += "\n";
6811
6812 fprintf(fp, "%s", ss.c_str());
6813
6814 fclose(fp);
6815
6816 if (1 && padded) {
6817 printf("Schema in file %s has padding:\n", try_filename.c_str());
6818 printf("%s", ss.c_str());
6819 }
6820
6821 if (filenamep)
6823
6824 return HS_SUCCESS;
6825}
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:11764
INT rpc_tid_size(INT id)
Definition midas.cxx:11757
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:1237
char name[NAME_LENGTH]
Definition midas.h:1235
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 6336 of file history_schema.cxx.

6337{
6338 if (fDebug)
6339 printf("FileHistory::hs_clear_cache!\n");
6340 fPathLastMtime = 0;
6342}
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 6317 of file history_schema.cxx.

6318{
6319 if (fDebug)
6320 printf("hs_connect [%s]!\n", connect_string);
6321
6322 hs_disconnect();
6323
6326
6327 // add trailing '/'
6328 if (fPath.length() > 0) {
6329 if (fPath[fPath.length()-1] != DIR_SEPARATOR)
6331 }
6332
6333 return HS_SUCCESS;
6334}
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 6344 of file history_schema.cxx.

6345{
6346 if (fDebug)
6347 printf("FileHistory::hs_disconnect!\n");
6348
6351
6352 return HS_SUCCESS;
6353}
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 6523 of file history_schema.cxx.

6524{
6525 if (fDebug)
6526 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d\n", event_name, TimeToString(timestamp).c_str(), ntags);
6527
6528 int status;
6529
6530 HsFileSchema* s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6531
6532 if (!s) {
6533 //printf("hs_define_event: no schema for event %s\n", event_name);
6534 status = read_schema(&fWriterCurrentSchema, event_name, timestamp);
6535 if (status != HS_SUCCESS)
6536 return NULL;
6537 s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6538 } else {
6539 //printf("hs_define_event: already have schema for event %s\n", s->event_name.c_str());
6540 }
6541
6542 bool xdebug = false;
6543
6544 if (s) { // is existing schema the same as new schema?
6545 bool same = true;
6546
6547 if (same)
6548 if (s->event_name != event_name) {
6549 if (xdebug)
6550 printf("AAA: [%s] [%s]!\n", s->event_name.c_str(), event_name);
6551 same = false;
6552 }
6553
6554 if (same)
6555 if (s->variables.size() != (unsigned)ntags) {
6556 if (xdebug)
6557 printf("BBB: event [%s]: ntags: %d -> %d!\n", event_name, (int)s->variables.size(), ntags);
6558 same = false;
6559 }
6560
6561 if (same)
6562 for (unsigned i=0; i<s->variables.size(); i++) {
6563 if (s->variables[i].name != tags[i].name) {
6564 if (xdebug)
6565 printf("CCC: event [%s] index %d: name [%s] -> [%s]!\n", event_name, i, s->variables[i].name.c_str(), tags[i].name);
6566 same = false;
6567 }
6568 if (s->variables[i].type != (int)tags[i].type) {
6569 if (xdebug)
6570 printf("DDD: event [%s] index %d: type %d -> %d!\n", event_name, i, s->variables[i].type, tags[i].type);
6571 same = false;
6572 }
6573 if (s->variables[i].n_data != (int)tags[i].n_data) {
6574 if (xdebug)
6575 printf("EEE: event [%s] index %d: n_data %d -> %d!\n", event_name, i, s->variables[i].n_data, tags[i].n_data);
6576 same = false;
6577 }
6578 if (!same)
6579 break;
6580 }
6581
6582 if (!same) {
6583 if (xdebug) {
6584 printf("*** Schema for event %s has changed!\n", event_name);
6585
6586 printf("*** Old schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6587 s->print();
6588 printf("*** New tags:\n");
6589 PrintTags(ntags, tags);
6590 }
6591
6592 if (fDebug)
6593 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema mismatch, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags);
6594
6595 s = NULL;
6596 }
6597 }
6598
6599 if (s) {
6600 // maybe this schema is too old - rotate files every so often
6601 time_t age = timestamp - s->time_from;
6602 //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->time_from).c_str(), s->file_name.c_str());
6603 if (age > fConfMaxFileAge) {
6604 if (fDebug)
6605 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);
6606
6607 // force creation of a new file
6608 s = NULL;
6609 }
6610 }
6611
6612 if (s) {
6613 // maybe this file is too big - rotate files to limit maximum size
6614 double size = ss_file_size(s->file_name.c_str());
6615 //printf("*** size %.0f, file %s\n", size, s->file_name.c_str());
6616 if (size > fConfMaxFileSize) {
6617 if (fDebug)
6618 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);
6619
6620 // force creation of a new file
6621 s = NULL;
6622 }
6623 }
6624
6625 if (!s) {
6626 std::string filename;
6627
6628 status = create_file(event_name, timestamp, ntags, tags, &filename);
6629 if (status != HS_SUCCESS)
6630 return NULL;
6631
6632 HsFileSchema* ss = read_file_schema(filename.c_str());
6633 if (!ss) {
6634 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6635 return NULL;
6636 }
6637
6639
6640 s = (HsFileSchema*)fWriterCurrentSchema.find_event(event_name, timestamp);
6641
6642 if (!s) {
6643 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6644 return NULL;
6645 }
6646
6647 if (xdebug) {
6648 printf("*** New schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6649 s->print();
6650 }
6651 }
6652
6653 assert(s != NULL);
6654
6655#if 0
6656 {
6657 printf("schema for [%s] is %p\n", event_name, s);
6658 if (s)
6659 s->print();
6660 }
6661#endif
6662
6663 HsFileSchema* e = new HsFileSchema();
6664
6665 *e = *s; // make a copy of the schema
6666
6667 return e;
6668}
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)
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:6972
static void PrintTags(int ntags, const TAG tags[])
DWORD status
Definition odbhist.cxx:39
std::string file_name
void print(bool print_tags=true) const
std::string event_name
std::vector< HsSchemaEntry > variables
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 6362 of file history_schema.cxx.

6363{
6364 int status;
6365 double start_time = ss_time_sec();
6366
6367 if (pchanged)
6368 *pchanged = false;
6369
6370 struct stat stat_buf;
6371 status = stat(fPath.c_str(), &stat_buf);
6372 if (status != 0) {
6373 cm_msg(MERROR, "FileHistory::read_file_list", "Cannot stat(%s), errno %d (%s)", fPath.c_str(), errno, strerror(errno));
6374 return HS_FILE_ERROR;
6375 }
6376
6377 //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));
6378
6379 if (stat_buf.st_mtime == fPathLastMtime) {
6380 if (fDebug)
6381 printf("FileHistory::read_file_list: history directory \"%s\" mtime %d did not change\n", fPath.c_str(), int(stat_buf.st_mtime));
6382 return HS_SUCCESS;
6383 }
6384
6385 fPathLastMtime = stat_buf.st_mtime;
6386
6387 if (fDebug)
6388 printf("FileHistory::read_file_list: reading list of history files in \"%s\"\n", fPath.c_str());
6389
6390 std::vector<std::string> flist;
6391
6392 ss_file_find(fPath.c_str(), "mhf_*.dat", &flist);
6393
6394 double ls_time = ss_time_sec();
6395 double ls_elapsed = ls_time - start_time;
6396 if (ls_elapsed > 5.000) {
6397 cm_msg(MINFO, "FileHistory::read_file_list", "\"ls -l\" of \"%s\" took %.1f sec", fPath.c_str(), ls_elapsed);
6399 }
6400
6401 // note: reverse iterator is used to sort filenames by time, newest first
6402 std::sort(flist.rbegin(), flist.rend());
6403
6404#if 0
6405 {
6406 printf("file names sorted by time:\n");
6407 for (unsigned i=0; i<flist.size(); i++) {
6408 printf("%d: %s\n", i, flist[i].c_str());
6409 }
6410 }
6411#endif
6412
6413 std::vector<bool> fread;
6414 fread.resize(flist.size()); // fill with "false"
6415
6416 // loop over the old list of files,
6417 // for files we already read, loop over new file
6418 // list and mark the same file as read. K.O.
6419 for (size_t j=0; j<fSortedFiles.size(); j++) {
6420 if (fSortedRead[j]) {
6421 for (size_t i=0; i<flist.size(); i++) {
6422 if (flist[i] == fSortedFiles[j]) {
6423 fread[i] = true;
6424 break;
6425 }
6426 }
6427 }
6428 }
6429
6432
6433 if (pchanged)
6434 *pchanged = true;
6435
6436 return HS_SUCCESS;
6437}
#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:6713
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 6827 of file history_schema.cxx.

6828{
6829 if (fDebug)
6830 printf("FileHistory::read_file_schema: file %s\n", filename);
6831
6832 FILE* fp = fopen(filename, "r");
6833 if (!fp) {
6834 cm_msg(MERROR, "FileHistory::read_file_schema", "Cannot read \'%s\', fopen() errno %d (%s)", filename, errno, strerror(errno));
6835 return NULL;
6836 }
6837
6838 HsFileSchema* s = NULL;
6839
6840 // File format looks like this:
6841 // version: 2.0
6842 // event_name: u_Beam
6843 // time: 1023174012
6844 // tag: /DWORD 1 4 /timestamp
6845 // tag: FLOAT 1 4 B1
6846 // ...
6847 // tag: FLOAT 1 4 Ref Heater
6848 // record_size: 84
6849 // data_offset: 1024
6850
6851 int rd_recsize = 0;
6852 int offset = 0;
6853
6854 while (1) {
6855 char buf[1024];
6856 char* b = fgets(buf, sizeof(buf), fp);
6857
6858 //printf("read: %s\n", b);
6859
6860 if (!b) {
6861 break; // end of file
6862 }
6863
6864 char*bb;
6865
6866 bb = strchr(b, '\n');
6867 if (bb)
6868 *bb = 0;
6869
6870 bb = strchr(b, '\r');
6871 if (bb)
6872 *bb = 0;
6873
6874 bb = strstr(b, "version: 2.0");
6875 if (bb == b) {
6876 s = new HsFileSchema();
6877 assert(s);
6878
6879 s->file_name = filename;
6880 continue;
6881 }
6882
6883 if (!s) {
6884 // malformed history file
6885 break;
6886 }
6887
6888 bb = strstr(b, "event_name: ");
6889 if (bb == b) {
6890 s->event_name = bb + 12;
6891 continue;
6892 }
6893
6894 bb = strstr(b, "time: ");
6895 if (bb == b) {
6896 s->time_from = strtoul(bb + 6, NULL, 10);
6897 continue;
6898 }
6899
6900 // tag format is like this:
6901 //
6902 // tag: FLOAT 1 4 Ref Heater
6903 //
6904 // "FLOAT" is the MIDAS type, "/DWORD" is special tag for the timestamp
6905 // "1" is the number of array elements
6906 // "4" is the total tag size in bytes (n_data*tid_size)
6907 // "Ref Heater" is the tag name
6908
6909 bb = strstr(b, "tag: ");
6910 if (bb == b) {
6911 bb += 5; // now points to the tag MIDAS type
6912 const char* midas_type = bb;
6913 char* bbb = strchr(bb, ' ');
6914 if (bbb) {
6915 *bbb = 0;
6916 HsSchemaEntry t;
6917 if (midas_type[0] == '/') {
6918 t.type = 0;
6919 } else {
6921 if (t.type == 0) {
6922 cm_msg(MERROR, "FileHistory::read_file_schema", "Unknown MIDAS data type \'%s\' in history file \'%s\'", midas_type, filename);
6923 if (s)
6924 delete s;
6925 s = NULL;
6926 break;
6927 }
6928 }
6929 bbb++;
6930 while (*bbb == ' ')
6931 bbb++;
6932 if (*bbb) {
6933 t.n_data = strtoul(bbb, &bbb, 10);
6934 while (*bbb == ' ')
6935 bbb++;
6936 if (*bbb) {
6937 t.n_bytes = strtoul(bbb, &bbb, 10);
6938 while (*bbb == ' ')
6939 bbb++;
6940 t.name = bbb;
6941 }
6942 }
6943
6944 if (midas_type[0] != '/') {
6945 s->variables.push_back(t);
6946 s->offsets.push_back(offset);
6947 offset += t.n_bytes;
6948 }
6949
6950 rd_recsize += t.n_bytes;
6951 }
6952 continue;
6953 }
6954
6955 bb = strstr(b, "record_size: ");
6956 if (bb == b) {
6957 s->record_size = atoi(bb + 12);
6958 continue;
6959 }
6960
6961 bb = strstr(b, "data_offset: ");
6962 if (bb == b) {
6963 s->data_offset = atoi(bb + 12);
6964 // data offset is the last entry in the file
6965 break;
6966 }
6967 }
6968
6969 fclose(fp);
6970
6971 if (!s) {
6972 cm_msg(MERROR, "FileHistory::read_file_schema", "Malformed history schema in \'%s\', maybe it is not a history file", filename);
6973 return NULL;
6974 }
6975
6976 if (rd_recsize != s->record_size) {
6977 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->record_size, rd_recsize);
6978 if (s)
6979 delete s;
6980 return NULL;
6981 }
6982
6983 if (!s) {
6984 cm_msg(MERROR, "FileHistory::read_file_schema", "Could not read history schema from \'%s\', maybe it is not a history file", filename);
6985 if (s)
6986 delete s;
6987 return NULL;
6988 }
6989
6990 if (fDebug > 1)
6991 s->print();
6992
6993 return s;
6994}
int rpc_name_tid(const char *name)
Definition midas.cxx:11778
int type
int n_data
std::string name
int n_bytes
std::vector< int > offsets
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 6439 of file history_schema.cxx.

6440{
6441 if (fDebug)
6442 printf("FileHistory::read_schema: event [%s] at time %s\n", event_name, TimeToString(timestamp).c_str());
6443
6444 if (fSchema.size() == 0) {
6445 if (fDebug)
6446 printf("FileHistory::read_schema: schema is empty, do a full reload from disk\n");
6448 }
6449
6451 DWORD old_timeout = 0;
6454
6455 bool changed = false;
6456
6458
6459 if (status != HS_SUCCESS) {
6461 return status;
6462 }
6463
6464 if (!changed) {
6465 if ((*sv).find_event(event_name, timestamp)) {
6466 if (fDebug)
6467 printf("FileHistory::read_schema: event [%s] at time %s, no new history files, already have this schema\n", event_name, TimeToString(timestamp).c_str());
6469 return HS_SUCCESS;
6470 }
6471 }
6472
6473 double start_time = ss_time_sec();
6474
6475 int count_read = 0;
6476
6477 for (unsigned i=0; i<fSortedFiles.size(); i++) {
6478 std::string file_name = fPath + fSortedFiles[i];
6479 if (fSortedRead[i])
6480 continue;
6481 //bool dupe = false;
6482 //for (unsigned ss=0; ss<sv->size(); ss++) {
6483 // HsFileSchema* ssp = (HsFileSchema*)(*sv)[ss];
6484 // if (file_name == ssp->file_name) {
6485 // dupe = true;
6486 // break;
6487 // }
6488 //}
6489 //if (dupe)
6490 // continue;
6491 fSortedRead[i] = true;
6493 if (!s)
6494 continue;
6495 sv->add(s);
6496 count_read++;
6497
6498 if (event_name) {
6499 if (s->event_name == event_name) {
6500 //printf("file %s event_name %s time %s, age %f\n", file_name.c_str(), s->event_name.c_str(), TimeToString(s->time_from).c_str(), double(timestamp - s->time_from));
6501 if (s->time_from <= timestamp) {
6502 // this file is older than the time requested,
6503 // subsequent files will be even older,
6504 // we can stop reading here.
6505 break;
6506 }
6507 }
6508 }
6509 }
6510
6511 double end_time = ss_time_sec();
6512 double read_elapsed = end_time - start_time;
6513 if (read_elapsed > 5.000) {
6514 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);
6516 }
6517
6519
6520 return HS_SUCCESS;
6521}
#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:3317
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 6292 of file history_schema.cxx.

◆ fConfMaxFileSize

double FileHistory::fConfMaxFileSize
protected

Definition at line 6293 of file history_schema.cxx.

◆ fPath

std::string FileHistory::fPath
protected

Definition at line 6288 of file history_schema.cxx.

◆ fPathLastMtime

time_t FileHistory::fPathLastMtime
protected

Definition at line 6289 of file history_schema.cxx.

◆ fSortedFiles

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

Definition at line 6290 of file history_schema.cxx.

◆ fSortedRead

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

Definition at line 6291 of file history_schema.cxx.


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