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< bool > fSortedRead
 
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 6463 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ FileHistory()

FileHistory::FileHistory ( )
inline

Definition at line 6474 of file history_schema.cxx.

6475 {
6476 // empty
6477 }

Member Function Documentation

◆ clear_file_list()

void FileHistory::clear_file_list ( )
protected

Definition at line 6532 of file history_schema.cxx.

6533{
6534 fPathLastMtime = 0;
6535 fSortedFiles.clear();
6536 fSortedRead.clear();
6537}
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 6872 of file history_schema.cxx.

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

6514{
6515 if (fDebug)
6516 printf("FileHistory::hs_clear_cache!\n");
6517 fPathLastMtime = 0;
6519}
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 6494 of file history_schema.cxx.

6495{
6496 if (fDebug)
6497 printf("hs_connect [%s]!\n", connect_string);
6498
6499 hs_disconnect();
6500
6501 fConnectString = connect_string;
6502 fPath = connect_string;
6503
6504 // add trailing '/'
6505 if (fPath.length() > 0) {
6506 if (fPath[fPath.length()-1] != DIR_SEPARATOR)
6508 }
6509
6510 return HS_SUCCESS;
6511}
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 6521 of file history_schema.cxx.

6522{
6523 if (fDebug)
6524 printf("FileHistory::hs_disconnect!\n");
6525
6528
6529 return HS_SUCCESS;
6530}
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 7198 of file history_schema.cxx.

7199{
7200 HsFileSchema* fs = dynamic_cast<HsFileSchema*>(s);
7201
7202 assert(fs != NULL); // FileHistory::maybe_reopen() must be called only with file history schema.
7203
7204 if (fs->fFileSize <= fConfMaxFileSize) {
7205 // not big enough, let it grow
7206 return s;
7207 }
7208
7209 // must rotate the file
7210
7211 if (fDebug) {
7212#ifdef OS_DARWIN
7213 printf("FileHistory::maybe_reopen: reopen file \"%s\", size %lld, max size %lld\n", fs->fFileName.c_str(), fs->fFileSize, fConfMaxFileSize);
7214#else
7215 printf("FileHistory::maybe_reopen: reopen file \"%s\", size %jd, max size %jd\n", fs->fFileName.c_str(), fs->fFileSize, fConfMaxFileSize);
7216#endif
7217 }
7218
7219 std::string new_filename;
7220
7221 int status = create_file(event_name, timestamp, fs->fVariables, &new_filename);
7222
7223 if (status != HS_SUCCESS) {
7224 // cannot create new history file
7225 return s;
7226 }
7227
7228 HsFileSchema* new_fs = read_file_schema(new_filename.c_str());
7229
7230 if (!new_fs) {
7231 // cannot open new history file
7232 return s;
7233 }
7234
7235 new_fs->fDisabled = false;
7236
7237 HsFileSchema* new_fs_copy = new HsFileSchema;
7238 *new_fs_copy = *new_fs; // make a copy
7239
7240 //printf("replacing schema %p %p with %p %p\n", s, fs, new_fs, new_fs_copy);
7241
7242 for (size_t i=0; i<fWriterEvents.size(); i++) {
7243 if (s == fWriterEvents[i]) {
7244 delete fWriterEvents[i];
7245 fWriterEvents[i] = new_fs;
7246 s = NULL; // pointer to fEvents[i]
7247 fs = NULL; // pointer to fEvents[i]
7248 }
7249 }
7250
7251 assert(s == NULL); // the schema we are replacing must be in fWriterEvents.
7252
7253 fWriterSchema.add(new_fs_copy); // make sure new file is added to the list of files
7254
7255 assert(new_fs->fFileSize < fConfMaxFileSize); // check that we are not returning the original big file
7256
7257 //new_fs->print();
7258
7259 return new_fs;
7260}
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)
std::string fFileName
std::vector< HsSchemaEntry > fVariables
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 6718 of file history_schema.cxx.

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

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

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

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

6701{
6702 for (int i=0; i<ntags; i++) {
6704
6705 int tsize = rpc_tid_size(tags[i].type);
6706
6707 e.tag_name = tags[i].name;
6708 e.tag_type = rpc_tid_name(tags[i].type);
6709 e.name = tags[i].name;
6710 e.type = tags[i].type;
6711 e.n_data = tags[i].n_data;
6712 e.n_bytes = tags[i].n_data*tsize;
6713
6714 variables.push_back(e);
6715 }
6716}
DWORD type
Definition midas.h:1235
DWORD n_data
Definition midas.h:1236
char name[NAME_LENGTH]
Definition midas.h:1234
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 6470 of file history_schema.cxx.

◆ fConfMaxFileSize

off64_t FileHistory::fConfMaxFileSize = 100*MiB
protected

Definition at line 6471 of file history_schema.cxx.

◆ fPath

std::string FileHistory::fPath
protected

Definition at line 6466 of file history_schema.cxx.

◆ fPathLastMtime

time_t FileHistory::fPathLastMtime = 0
protected

Definition at line 6467 of file history_schema.cxx.

◆ fSortedFiles

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

Definition at line 6468 of file history_schema.cxx.

◆ fSortedRead

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

Definition at line 6469 of file history_schema.cxx.


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