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, const std::vector< HsSchemaEntry > &vars, std::string *filenamep)
 
HsFileSchemaread_file_schema (const char *filename)
 
int read_file_list (bool *pchanged)
 
void clear_file_list ()
 
void tags_to_variables (int ntags, const TAG tags[], std::vector< HsSchemaEntry > &variables)
 
HsSchemamaybe_reopen (const char *event_name, time_t timestamp, HsSchema *s)
 

Protected Attributes

std::string fPath
 
time_t fPathLastMtime = 0
 
std::vector< std::string > fSortedFiles
 
std::vector< boolfSortedRead
 
time_t fConfMaxFileAge = 1*kMonth
 
off64_t fConfMaxFileSize = 100*MiB
 
- Protected Attributes inherited from SchemaHistoryBase
int fDebug = 0
 
std::string fConnectString
 
HsSchemaVector fWriterSchema
 
std::vector< HsSchema * > fWriterEvents
 
HsSchemaVector fReaderSchema
 

Additional Inherited Members

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

Detailed Description

Definition at line 6451 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ FileHistory()

FileHistory::FileHistory ( )
inline

Definition at line 6462 of file history_schema.cxx.

6463 {
6464 // empty
6465 }

Member Function Documentation

◆ clear_file_list()

void FileHistory::clear_file_list ( )
protected

Definition at line 6520 of file history_schema.cxx.

6521{
6522 fPathLastMtime = 0;
6523 fSortedFiles.clear();
6524 fSortedRead.clear();
6525}
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,
const std::vector< HsSchemaEntry > &  vars,
std::string *  filenamep 
)
protected

Definition at line 6860 of file history_schema.cxx.

6861{
6862 if (fDebug)
6863 printf("FileHistory::create_file: event [%s]\n", event_name);
6864
6865 // NB: file names are constructed in such a way
6866 // that when sorted lexicographically ("ls -1 | sort")
6867 // they *also* become sorted by time
6868
6869 struct tm tm;
6870 localtime_r(&timestamp, &tm); // somebody must call tzset() before this.
6871
6872 char buf[256];
6873 strftime(buf, sizeof(buf), "%Y%m%d", &tm);
6874
6875 std::string filename;
6876 filename += fPath;
6877 filename += "mhf_";
6878 filename += TimeToString(timestamp);
6879 filename += "_";
6880 filename += buf;
6881 filename += "_";
6882 filename += MidasNameToFileName(event_name);
6883
6884 std::string try_filename = filename + ".dat";
6885
6886 FILE *fp = NULL;
6887 for (int itry=0; itry<10; itry++) {
6888 if (itry > 0) {
6889 char s[256];
6890 sprintf(s, "_%d", rand());
6891 try_filename = filename + s + ".dat";
6892 }
6893
6894 fp = fopen(try_filename.c_str(), "r");
6895 if (fp != NULL) {
6896 // this file already exists, try with a different name
6897 fclose(fp);
6898 continue;
6899 }
6900
6901 fp = fopen(try_filename.c_str(), "w");
6902 if (fp == NULL) {
6903 // somehow cannot create this file, try again
6904 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));
6905 continue;
6906 }
6907
6908 // file opened
6909 break;
6910 }
6911
6912 if (fp == NULL) {
6913 // somehow cannot create any file, whine!
6914 cm_msg(MERROR, "FileHistory::create_file", "Error: Cannot create file \'%s\' for event \'%s\'", filename.c_str(), event_name);
6915 return HS_FILE_ERROR;
6916 }
6917
6918 std::string ss;
6919
6920 ss += "version: 2.0\n";
6921 ss += "event_name: ";
6922 ss += event_name;
6923 ss += "\n";
6924 ss += "time: ";
6925 ss += TimeToString(timestamp);
6926 ss += "\n";
6927
6928 int recsize = 0;
6929
6930 ss += "tag: /DWORD 1 4 /timestamp\n";
6931 recsize += 4;
6932
6933 bool padded = false;
6934 int offset = 0;
6935
6936 bool xdebug = false; // (strcmp(event_name, "u_Beam") == 0);
6937
6938 for (size_t i=0; i<vars.size(); i++) {
6939 int tsize = rpc_tid_size(vars[i].type);
6940 int n_bytes = vars[i].n_data*tsize;
6941 int xalign = (offset % tsize);
6942
6943 if (xdebug)
6944 printf("tag %zu, tsize %d, n_bytes %d, xalign %d\n", i, tsize, n_bytes, xalign);
6945
6946#if 0
6947 // looks like history data does not do alignement and padding
6948 if (xalign != 0) {
6949 padded = true;
6950 int pad_bytes = tsize - xalign;
6951 assert(pad_bytes > 0);
6952
6953 ss += "tag: ";
6954 ss += "XPAD";
6955 ss += " ";
6956 ss += SmallIntToString(1);
6957 ss += " ";
6959 ss += " ";
6960 ss += "pad_";
6961 ss += SmallIntToString(i);
6962 ss += "\n";
6963
6964 offset += pad_bytes;
6965 recsize += pad_bytes;
6966
6967 assert((offset % tsize) == 0);
6968 fprintf(stderr, "FIXME: need to debug padding!\n");
6969 //abort();
6970 }
6971#endif
6972
6973 ss += "tag: ";
6974 ss += rpc_tid_name(vars[i].type);
6975 ss += " ";
6976 ss += SmallIntToString(vars[i].n_data);
6977 ss += " ";
6978 ss += SmallIntToString(n_bytes);
6979 ss += " ";
6980 ss += vars[i].name;
6981 ss += "\n";
6982
6983 recsize += n_bytes;
6984 offset += n_bytes;
6985 }
6986
6987 ss += "record_size: ";
6989 ss += "\n";
6990
6991 // reserve space for "data_offset: ..."
6992 int sslength = ss.length() + 127;
6993
6994 int block = 1024;
6995 int nb = (sslength + block - 1)/block;
6996 int data_offset = block * nb;
6997
6998 ss += "data_offset: ";
7000 ss += "\n";
7001
7002 fprintf(fp, "%s", ss.c_str());
7003
7004 fclose(fp);
7005
7006 if (1 && padded) {
7007 printf("Schema in file %s has padding:\n", try_filename.c_str());
7008 printf("%s", ss.c_str());
7009 }
7010
7011 if (filenamep)
7013
7014 return HS_SUCCESS;
7015}
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:929
const char * rpc_tid_name(INT id)
Definition midas.cxx:11786
INT rpc_tid_size(INT id)
Definition midas.cxx:11779
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
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 6501 of file history_schema.cxx.

6502{
6503 if (fDebug)
6504 printf("FileHistory::hs_clear_cache!\n");
6505 fPathLastMtime = 0;
6507}
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 6482 of file history_schema.cxx.

6483{
6484 if (fDebug)
6485 printf("hs_connect [%s]!\n", connect_string);
6486
6487 hs_disconnect();
6488
6491
6492 // add trailing '/'
6493 if (fPath.length() > 0) {
6494 if (fPath[fPath.length()-1] != DIR_SEPARATOR)
6496 }
6497
6498 return HS_SUCCESS;
6499}
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 6509 of file history_schema.cxx.

6510{
6511 if (fDebug)
6512 printf("FileHistory::hs_disconnect!\n");
6513
6516
6517 return HS_SUCCESS;
6518}
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:

◆ maybe_reopen()

HsSchema * FileHistory::maybe_reopen ( const char event_name,
time_t  timestamp,
HsSchema s 
)
protectedvirtual

Implements SchemaHistoryBase.

Definition at line 7186 of file history_schema.cxx.

7187{
7188 HsFileSchema* fs = dynamic_cast<HsFileSchema*>(s);
7189
7190 assert(fs != NULL); // FileHistory::maybe_reopen() must be called only with file history schema.
7191
7192 if (fs->fFileSize <= fConfMaxFileSize) {
7193 // not big enough, let it grow
7194 return s;
7195 }
7196
7197 // must rotate the file
7198
7199 if (fDebug) {
7200#ifdef OS_DARWIN
7201 printf("FileHistory::maybe_reopen: reopen file \"%s\", size %lld, max size %lld\n", fs->fFileName.c_str(), fs->fFileSize, fConfMaxFileSize);
7202#else
7203 printf("FileHistory::maybe_reopen: reopen file \"%s\", size %jd, max size %jd\n", fs->fFileName.c_str(), fs->fFileSize, fConfMaxFileSize);
7204#endif
7205 }
7206
7207 std::string new_filename;
7208
7209 int status = create_file(event_name, timestamp, fs->fVariables, &new_filename);
7210
7211 if (status != HS_SUCCESS) {
7212 // cannot create new history file
7213 return s;
7214 }
7215
7217
7218 if (!new_fs) {
7219 // cannot open new history file
7220 return s;
7221 }
7222
7223 new_fs->fDisabled = false;
7224
7226 *new_fs_copy = *new_fs; // make a copy
7227
7228 //printf("replacing schema %p %p with %p %p\n", s, fs, new_fs, new_fs_copy);
7229
7230 for (size_t i=0; i<fWriterEvents.size(); i++) {
7231 if (s == fWriterEvents[i]) {
7232 delete fWriterEvents[i];
7234 s = NULL; // pointer to fEvents[i]
7235 fs = NULL; // pointer to fEvents[i]
7236 }
7237 }
7238
7239 assert(s == NULL); // the schema we are replacing must be in fWriterEvents.
7240
7241 fWriterSchema.add(new_fs_copy); // make sure new file is added to the list of files
7242
7243 assert(new_fs->fFileSize < fConfMaxFileSize); // check that we are not returning the original big file
7244
7245 //new_fs->print();
7246
7247 return new_fs;
7248}
HsFileSchema * read_file_schema(const char *filename)
off64_t fConfMaxFileSize
int create_file(const char *event_name, time_t timestamp, const std::vector< HsSchemaEntry > &vars, std::string *filenamep)
void add(HsSchema *s)
HsSchemaVector fWriterSchema
std::vector< HsSchema * > fWriterEvents
DWORD status
Definition odbhist.cxx:39
Here is the call 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 6706 of file history_schema.cxx.

6707{
6708 if (fDebug)
6709 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d\n", event_name, TimeToString(timestamp).c_str(), ntags);
6710
6711 int status;
6712
6713 HsFileSchema* s = (HsFileSchema*)fWriterSchema.find_event(event_name, timestamp);
6714
6715 if (!s) {
6716 //printf("hs_define_event: no schema for event %s\n", event_name);
6717 status = read_schema(&fWriterSchema, event_name, timestamp);
6718 if (status != HS_SUCCESS)
6719 return NULL;
6720 s = (HsFileSchema*)fWriterSchema.find_event(event_name, timestamp);
6721 } else {
6722 //printf("hs_define_event: already have schema for event %s\n", s->fEventName.c_str());
6723 }
6724
6725 bool xdebug = false;
6726
6727 if (s) { // is existing schema the same as new schema?
6728 bool same = true;
6729
6730 if (same) {
6731 if (s->fEventName != event_name) {
6732 if (xdebug)
6733 printf("AAA: [%s] [%s]!\n", s->fEventName.c_str(), event_name);
6734 same = false;
6735 }
6736 }
6737
6738 if (same) {
6739 if (s->fVariables.size() != (size_t)ntags) {
6740 if (xdebug)
6741 printf("BBB: event [%s]: ntags: %zu -> %d!\n", event_name, s->fVariables.size(), ntags);
6742 same = false;
6743 }
6744 }
6745
6746 if (same) {
6747 for (size_t i=0; i<s->fVariables.size(); i++) {
6748 if (s->fVariables[i].name != tags[i].name) {
6749 if (xdebug)
6750 printf("CCC: event [%s] index %zu: name [%s] -> [%s]!\n", event_name, i, s->fVariables[i].name.c_str(), tags[i].name);
6751 same = false;
6752 }
6753 if (s->fVariables[i].type != (int)tags[i].type) {
6754 if (xdebug)
6755 printf("DDD: event [%s] index %zu: type %d -> %d!\n", event_name, i, s->fVariables[i].type, tags[i].type);
6756 same = false;
6757 }
6758 if (s->fVariables[i].n_data != (int)tags[i].n_data) {
6759 if (xdebug)
6760 printf("EEE: event [%s] index %zu: n_data %d -> %d!\n", event_name, i, s->fVariables[i].n_data, tags[i].n_data);
6761 same = false;
6762 }
6763 if (!same)
6764 break;
6765 }
6766 }
6767
6768 if (!same) {
6769 if (xdebug) {
6770 printf("*** Schema for event %s has changed!\n", event_name);
6771
6772 printf("*** Old schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6773 s->print();
6774 printf("*** New tags:\n");
6775 PrintTags(ntags, tags);
6776 }
6777
6778 if (fDebug)
6779 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema mismatch, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags);
6780
6781 s = NULL;
6782 }
6783 }
6784
6785 if (s) {
6786 // maybe this schema is too old - rotate files every so often
6787 time_t age = timestamp - s->fTimeFrom;
6788 //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());
6789 if (age > fConfMaxFileAge) {
6790 if (fDebug)
6791 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);
6792
6793 // force creation of a new file
6794 s = NULL;
6795 }
6796 }
6797
6798 if (s) {
6799 // maybe this file is too big - rotate files to limit maximum size
6800 double size = ss_file_size(s->fFileName.c_str());
6801 //printf("*** size %.0f, file %s\n", size, s->fFileName.c_str());
6802 if (size > fConfMaxFileSize) {
6803 if (fDebug)
6804 printf("FileHistory::new_event: event [%s], timestamp %s, ntags %d: file too big, size %.1f MiBytes, max size %.1f MiBytes, starting a new file.\n", event_name, TimeToString(timestamp).c_str(), ntags, size/MiB, fConfMaxFileSize/MiB);
6805
6806 // force creation of a new file
6807 s = NULL;
6808 }
6809 }
6810
6811 if (!s) {
6812 std::string filename;
6813
6814 std::vector<HsSchemaEntry> vars;
6815
6816 tags_to_variables(ntags, tags, vars);
6817
6818 status = create_file(event_name, timestamp, vars, &filename);
6819 if (status != HS_SUCCESS)
6820 return NULL;
6821
6822 HsFileSchema* ss = read_file_schema(filename.c_str());
6823 if (!ss) {
6824 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6825 return NULL;
6826 }
6827
6829
6830 s = (HsFileSchema*)fWriterSchema.find_event(event_name, timestamp);
6831
6832 if (!s) {
6833 cm_msg(MERROR, "FileHistory::new_event", "Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6834 return NULL;
6835 }
6836
6837 if (xdebug) {
6838 printf("*** New schema for event [%s] time %s:\n", event_name, TimeToString(timestamp).c_str());
6839 s->print();
6840 }
6841 }
6842
6843 assert(s != NULL);
6844
6845#if 0
6846 {
6847 printf("schema for [%s] is %p\n", event_name, s);
6848 if (s)
6849 s->print();
6850 }
6851#endif
6852
6853 HsFileSchema* e = new HsFileSchema();
6854
6855 *e = *s; // make a copy of the schema
6856
6857 return e;
6858}
void tags_to_variables(int ntags, const TAG tags[], std::vector< HsSchemaEntry > &variables)
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)
double ss_file_size(const char *path)
Definition system.cxx:7050
const time_t kMonth
const double MiB
static void PrintTags(int ntags, const TAG tags[])
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 6527 of file history_schema.cxx.

6528{
6529 int status;
6530 double start_time = ss_time_sec();
6531
6532 if (pchanged)
6533 *pchanged = false;
6534
6535 struct stat stat_buf;
6536 status = stat(fPath.c_str(), &stat_buf);
6537 if (status != 0) {
6538 cm_msg(MERROR, "FileHistory::read_file_list", "Cannot stat(%s), errno %d (%s)", fPath.c_str(), errno, strerror(errno));
6539 return HS_FILE_ERROR;
6540 }
6541
6542 //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));
6543
6544 if (stat_buf.st_mtime == fPathLastMtime) {
6545 if (fDebug)
6546 printf("FileHistory::read_file_list: history directory \"%s\" mtime %d did not change\n", fPath.c_str(), int(stat_buf.st_mtime));
6547 return HS_SUCCESS;
6548 }
6549
6550 fPathLastMtime = stat_buf.st_mtime;
6551
6552 if (fDebug)
6553 printf("FileHistory::read_file_list: reading list of history files in \"%s\"\n", fPath.c_str());
6554
6555 std::vector<std::string> flist;
6556
6557 ss_file_find(fPath.c_str(), "mhf_*.dat", &flist);
6558
6559 double ls_time = ss_time_sec();
6560 double ls_elapsed = ls_time - start_time;
6561 if (ls_elapsed > 5.000) {
6562 cm_msg(MINFO, "FileHistory::read_file_list", "\"ls -l\" of \"%s\" took %.1f sec", fPath.c_str(), ls_elapsed);
6564 }
6565
6566 // note: reverse iterator is used to sort filenames by time, newest first
6567 std::sort(flist.rbegin(), flist.rend());
6568
6569#if 0
6570 {
6571 printf("file names sorted by time:\n");
6572 for (size_t i=0; i<flist.size(); i++) {
6573 printf("%d: %s\n", i, flist[i].c_str());
6574 }
6575 }
6576#endif
6577
6578 std::vector<bool> fread;
6579 fread.resize(flist.size()); // fill with "false"
6580
6581 // loop over the old list of files,
6582 // for files we already read, loop over new file
6583 // list and mark the same file as read. K.O.
6584 for (size_t j=0; j<fSortedFiles.size(); j++) {
6585 if (fSortedRead[j]) {
6586 for (size_t i=0; i<flist.size(); i++) {
6587 if (flist[i] == fSortedFiles[j]) {
6588 fread[i] = true;
6589 break;
6590 }
6591 }
6592 }
6593 }
6594
6597
6598 if (pchanged)
6599 *pchanged = true;
6600
6601 return HS_SUCCESS;
6602}
#define MINFO
Definition midas.h:560
double ss_time_sec()
Definition system.cxx:3539
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6791
INT cm_msg_flush_buffer()
Definition midas.cxx:879
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 7017 of file history_schema.cxx.

7018{
7019 if (fDebug)
7020 printf("FileHistory::read_file_schema: file %s\n", filename);
7021
7022 FILE* fp = fopen(filename, "r");
7023 if (!fp) {
7024 cm_msg(MERROR, "FileHistory::read_file_schema", "Cannot read \'%s\', fopen() errno %d (%s)", filename, errno, strerror(errno));
7025 return NULL;
7026 }
7027
7028 HsFileSchema* s = NULL;
7029
7030 // File format looks like this:
7031 // version: 2.0
7032 // event_name: u_Beam
7033 // time: 1023174012
7034 // tag: /DWORD 1 4 /timestamp
7035 // tag: FLOAT 1 4 B1
7036 // ...
7037 // tag: FLOAT 1 4 Ref Heater
7038 // record_size: 84
7039 // data_offset: 1024
7040
7041 size_t rd_recsize = 0;
7042 int offset = 0;
7043
7044 while (1) {
7045 char buf[1024];
7046 char* b = fgets(buf, sizeof(buf), fp);
7047
7048 //printf("read: %s\n", b);
7049
7050 if (!b) {
7051 break; // end of file
7052 }
7053
7054 char*bb;
7055
7056 bb = strchr(b, '\n');
7057 if (bb)
7058 *bb = 0;
7059
7060 bb = strchr(b, '\r');
7061 if (bb)
7062 *bb = 0;
7063
7064 bb = strstr(b, "version: 2.0");
7065 if (bb == b) {
7066 s = new HsFileSchema();
7067 assert(s);
7068
7069 s->fFileName = filename;
7070 continue;
7071 }
7072
7073 if (!s) {
7074 // malformed history file
7075 break;
7076 }
7077
7078 bb = strstr(b, "event_name: ");
7079 if (bb == b) {
7080 s->fEventName = bb + 12;
7081 continue;
7082 }
7083
7084 bb = strstr(b, "time: ");
7085 if (bb == b) {
7086 s->fTimeFrom = strtoul(bb + 6, NULL, 10);
7087 continue;
7088 }
7089
7090 // tag format is like this:
7091 //
7092 // tag: FLOAT 1 4 Ref Heater
7093 //
7094 // "FLOAT" is the MIDAS type, "/DWORD" is special tag for the timestamp
7095 // "1" is the number of array elements
7096 // "4" is the total tag size in bytes (n_data*tid_size)
7097 // "Ref Heater" is the tag name
7098
7099 bb = strstr(b, "tag: ");
7100 if (bb == b) {
7101 bb += 5; // now points to the tag MIDAS type
7102 const char* midas_type = bb;
7103 char* bbb = strchr(bb, ' ');
7104 if (bbb) {
7105 *bbb = 0;
7106 HsSchemaEntry t;
7107 if (midas_type[0] == '/') {
7108 t.type = 0;
7109 } else {
7111 if (t.type == 0) {
7112 cm_msg(MERROR, "FileHistory::read_file_schema", "Unknown MIDAS data type \'%s\' in history file \'%s\'", midas_type, filename);
7113 if (s)
7114 delete s;
7115 s = NULL;
7116 break;
7117 }
7118 }
7119 bbb++;
7120 while (*bbb == ' ')
7121 bbb++;
7122 if (*bbb) {
7123 t.n_data = strtoul(bbb, &bbb, 10);
7124 while (*bbb == ' ')
7125 bbb++;
7126 if (*bbb) {
7127 t.n_bytes = strtoul(bbb, &bbb, 10);
7128 while (*bbb == ' ')
7129 bbb++;
7130 t.name = bbb;
7131 }
7132 }
7133
7134 if (midas_type[0] != '/') {
7135 s->fVariables.push_back(t);
7136 s->fOffsets.push_back(offset);
7137 offset += t.n_bytes;
7138 }
7139
7140 rd_recsize += t.n_bytes;
7141 }
7142 continue;
7143 }
7144
7145 bb = strstr(b, "record_size: ");
7146 if (bb == b) {
7147 s->fRecordSize = atoi(bb + 12);
7148 continue;
7149 }
7150
7151 bb = strstr(b, "data_offset: ");
7152 if (bb == b) {
7153 s->fDataOffset = atoi(bb + 12);
7154 // data offset is the last entry in the file
7155 break;
7156 }
7157 }
7158
7159 fclose(fp);
7160
7161 if (!s) {
7162 cm_msg(MERROR, "FileHistory::read_file_schema", "Malformed history schema in \'%s\', maybe it is not a history file", filename);
7163 return NULL;
7164 }
7165
7166 if (rd_recsize != s->fRecordSize) {
7167 cm_msg(MERROR, "FileHistory::read_file_schema", "Record size mismatch in history schema from \'%s\', file says %zu while total of all tags is %zu", filename, s->fRecordSize, rd_recsize);
7168 if (s)
7169 delete s;
7170 return NULL;
7171 }
7172
7173 if (!s) {
7174 cm_msg(MERROR, "FileHistory::read_file_schema", "Could not read history schema from \'%s\', maybe it is not a history file", filename);
7175 if (s)
7176 delete s;
7177 return NULL;
7178 }
7179
7180 if (fDebug > 1)
7181 s->print();
7182
7183 return s;
7184}
std::vector< int > fOffsets
int rpc_name_tid(const char *name)
Definition midas.cxx:11800
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 6604 of file history_schema.cxx.

6605{
6606 if (fDebug)
6607 printf("FileHistory::read_schema: event [%s] at time %s\n", event_name, TimeToString(timestamp).c_str());
6608
6609 if (sv->size() == 0) {
6610 if (fDebug)
6611 printf("FileHistory::read_schema: schema is empty, do a full reload from disk\n");
6613 }
6614
6616 DWORD old_timeout = 0;
6619
6620 bool changed = false;
6621
6623
6624 if (status != HS_SUCCESS) {
6626 return status;
6627 }
6628
6629 if (!changed) {
6630 if ((*sv).find_event(event_name, timestamp)) {
6631 if (fDebug)
6632 printf("FileHistory::read_schema: event [%s] at time %s, no new history files, already have this schema\n", event_name, TimeToString(timestamp).c_str());
6634 return HS_SUCCESS;
6635 }
6636 }
6637
6638 double start_time = ss_time_sec();
6639
6640 int count_read = 0;
6641
6642 for (size_t i=0; i<fSortedFiles.size(); i++) {
6643 std::string file_name = fPath + fSortedFiles[i];
6644 if (fSortedRead[i])
6645 continue;
6646 //bool dupe = false;
6647 //for (size_t ss=0; ss<sv->size(); ss++) {
6648 // HsFileSchema* ssp = (HsFileSchema*)(*sv)[ss];
6649 // if (file_name == ssp->fFileName) {
6650 // dupe = true;
6651 // break;
6652 // }
6653 //}
6654 //if (dupe)
6655 // continue;
6656 fSortedRead[i] = true;
6658 if (!s)
6659 continue;
6660 sv->add(s);
6661 count_read++;
6662
6663 if (event_name) {
6664 if (s->fEventName == event_name) {
6665 //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));
6666 if (s->fTimeFrom <= timestamp) {
6667 // this file is older than the time requested,
6668 // subsequent files will be even older,
6669 // we can stop reading here.
6670 break;
6671 }
6672 }
6673 }
6674 }
6675
6676 double end_time = ss_time_sec();
6677 double read_elapsed = end_time - start_time;
6678 if (read_elapsed > 5.000) {
6679 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);
6681 }
6682
6684
6685 return HS_SUCCESS;
6686}
#define FALSE
Definition cfortran.h:309
int read_file_list(bool *pchanged)
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3339
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3297
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:

◆ tags_to_variables()

void FileHistory::tags_to_variables ( int  ntags,
const TAG  tags[],
std::vector< HsSchemaEntry > &  variables 
)
protected

Definition at line 6688 of file history_schema.cxx.

6689{
6690 for (int i=0; i<ntags; i++) {
6692
6693 int tsize = rpc_tid_size(tags[i].type);
6694
6695 e.tag_name = tags[i].name;
6696 e.tag_type = rpc_tid_name(tags[i].type);
6697 e.name = tags[i].name;
6698 e.type = tags[i].type;
6699 e.n_data = tags[i].n_data;
6700 e.n_bytes = tags[i].n_data*tsize;
6701
6702 variables.push_back(e);
6703 }
6704}
DWORD type
Definition midas.h:1234
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:

Member Data Documentation

◆ fConfMaxFileAge

time_t FileHistory::fConfMaxFileAge = 1*kMonth
protected

Definition at line 6458 of file history_schema.cxx.

◆ fConfMaxFileSize

off64_t FileHistory::fConfMaxFileSize = 100*MiB
protected

Definition at line 6459 of file history_schema.cxx.

◆ fPath

std::string FileHistory::fPath
protected

Definition at line 6454 of file history_schema.cxx.

◆ fPathLastMtime

time_t FileHistory::fPathLastMtime = 0
protected

Definition at line 6455 of file history_schema.cxx.

◆ fSortedFiles

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

Definition at line 6456 of file history_schema.cxx.

◆ fSortedRead

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

Definition at line 6457 of file history_schema.cxx.


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