DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::oks::OksKernel Class Reference

Provides interface to the OKS kernel. More...

#include <kernel.hpp>

Collaboration diagram for dunedaq::oks::OksKernel:
[legend]

Public Types

enum  RepositoryUpdateType { DiscardChanges , MergeChanges , NoChanges }

Public Member Functions

 OksKernel (bool silence_mode=false, bool verbose_mode=false, bool profiling_mode=false, bool allow_repository=true, const char *version=nullptr, std::string branch_name="")
 Constructor to build OksKernel object.
 OksKernel (const OksKernel &src, bool copy_repository=false)
 Copy constructor.
 ~OksKernel ()
OksProfiler * GetOksProfiler () const
bool get_verbose_mode () const
 Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.
void set_verbose_mode (const bool b)
 Set status of verbose mode. To switch 'On'/'Off' use the method's parameter:
bool get_silence_mode () const
 Get status of silence mode. The method returns true, if the silence mode is switched 'On'. In such case the OKS will not print any info, warnings and error messages.
void set_silence_mode (const bool b)
 Set status of silence mode. To switch 'On'/'Off' use the method's parameter:
bool get_profiling_mode () const
 Get status of profiling mode. The method returns true, if the profiling mode is switched 'On'. In such case the OKS will report time spend to execute main methods and a summary table of their calls on the OKS kernel destroy.
void set_profiling_mode (const bool b)
 Set status of profiling mode. To switch 'On'/'Off' use the method's parameter:
bool get_allow_duplicated_classes_mode () const
 Get status of duplicated classes mode. The method returns true, if the duplicated classes mode is switched 'On'. In such case the OKS will allow to load classes with equal names. Only first loaded class is taken into account, the next ones are ignored.
bool get_allow_duplicated_objects_mode () const
 Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is switched 'On'. In such case the OKS will allow to load objects of the same class with equal IDs. The ID for duplicated object will be generated automatically.
void set_test_duplicated_objects_via_inheritance_mode (const bool b)
 Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter:
bool get_test_duplicated_objects_via_inheritance_mode () const
 Get status of test inherited duplicated objects mode. The method returns true, if the mode is switched 'On'. In such case the OKS will throw exception when there are objects with equal IDs within class inheritance hierarchy.
void set_allow_duplicated_classes_mode (const bool b)
 Set status of duplicated classes mode. To switch 'On'/'Off' use the method's parameter:
void set_allow_duplicated_objects_mode (const bool b)
 Set status of duplicated objects mode. To switch 'On'/'Off' use the method's parameter:
std::shared_mutex & get_mutex ()
 Return OKS kernel mutex.
OksFile * find_schema_file (const std::string &s) const
 Finds OKS schema file.
OksFile * find_data_file (const std::string &s) const
 Finds OKS data file.
std::list< OksClass * > * create_list_of_schema_classes (OksFile *) const
 Creates list of classes which belong to given file.
std::list< OksObject * > * create_list_of_data_objects (OksFile *) const
 Creates list of objects which belong to given file.
OksFile * create_file_info (const std::string &short_file_name, const std::string &file_name)
 Creates OKS file descriptor.
std::string get_file_path (const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
 Calculates full path to file.
const std::string & get_repository_version ()
bool is_user_repository_created () const
const std::string & get_user_repository_root () const
 Get user OKS repository root.
void set_user_repository_root (const std::string &path, const std::string &version="")
 Set user OKS repository root.
void get_includes (const std::string &file_name, std::set< std::string > &includes, bool use_repository_name=false)
 Opens file and reads its shallow includes.
void k_close_dangling_includes ()
 Close files which lost their parent.
OksFile * load_file (const std::string &name, bool bind=true)
 Load OKS database file.
OksFile * load_schema (const std::string &name, const OksFile *parent=0)
 Load OKS schema file.
OksFile * new_schema (const std::string &name)
 Create OKS schema file.
void save_schema (OksFile *file_h, bool force=false, OksFile *true_file_h=0)
 Save OKS schema file.
void save_schema (OksFile *file_h, bool force, const OksClass::Map &classes)
 Save classes into given OKS schema file.
void backup_schema (OksFile *pf, const char *suffix=".bak")
 Backup OKS schema file.
void save_as_schema (const std::string &name, OksFile *file_h)
 Save OKS schema file under new name.
void save_all_schema ()
 Save all OKS schema files.
void close_schema (OksFile *file_h)
 Close OKS schema file.
void close_all_schema ()
 Close all OKS schema files.
void set_active_schema (OksFile *file_h)
 Set active OKS schema file.
void k_set_active_schema (OksFile *file_h)
 Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.
OksFile * get_active_schema () const
 Get active OKS schema file.
const OksFile::Map & schema_files () const
 Get all schema files.
void create_lists_of_updated_schema_files (std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
 Get modified schema files.
void get_updated_repository_files (std::set< std::string > &updated, std::set< std::string > &added, std::set< std::string > &removed)
 Get repository modified schema files.
OksFile * load_data (const std::string &name, bool bind=true)
 Load OKS data file.
void reload_data (std::set< OksFile * > &files, bool allow_schema_extension=true)
 Reload OKS data files.
OksFile * new_data (const std::string &name, const std::string &logical_name="", const std::string &type="")
 Create OKS data file.
void save_data (OksFile *file_h, bool ignore_bad_objects=false, OksFile *true_file_h=nullptr, bool force_defaults=false)
 Save OKS data file.
void save_data (OksFile *file_h, const OksObject::FSet &objects)
 Save objects into given OKS data file.
void backup_data (OksFile *pf, const char *suffix=".bak")
 Backup OKS data file.
void save_as_data (const std::string &new_name, OksFile *file_h)
 Save OKS data file under new name.
void save_all_data (bool force_defaults=false)
 Save all OKS data files.
void close_data (OksFile *file_h, bool unbind_objects=true)
 Close OKS data file.
void close_all_data ()
 Close all OKS data files.
void set_active_data (OksFile *file_h)
 Set active OKS data file.
void k_set_active_data (OksFile *)
 Set active OKS data file.
OksFile * get_active_data () const
 Get active OKS data file.
const OksFile::Map & data_files () const
 Get all data files.
void create_lists_of_updated_data_files (std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
 Get modified data files.
void get_modified_files (std::set< OksFile * > &mfs, std::set< OksFile * > &rfs, const std::string &version)
 Get modified data files.
const std::list< std::string > & get_repository_dirs () const
 Get repository search directories.
void commit_repository (const std::string &comments, const std::string &credentials="")
 Commit user modifications into repository.
void tag_repository (const std::string &tag)
 Tag current state of repository.
std::time_t get_repository_checkout_ts () const
 Return repository checkout timestamp.
void update_repository (const std::string &hash_val, RepositoryUpdateType update_type)
 Update user repository files from origin by hash.
void update_repository (const std::string &param, const std::string &val, RepositoryUpdateType update_type)
 Update user repository files from origin.
std::list< std::string > get_repository_versions_diff (const std::string &sha1, const std::string &sha2)
std::list< std::string > get_repository_unmerged_files ()
std::vector< OksRepositoryVersion > get_repository_versions (bool skip_irrelevant, const std::string &command_line)
 Return repository versions.
std::vector< OksRepositoryVersion > get_repository_versions_by_hash (bool skip_irrelevant=true, const std::string &sha1="", const std::string &sha2="")
 Return repository versions between hash keys.
std::vector< OksRepositoryVersion > get_repository_versions_by_date (bool skip_irrelevant=true, const std::string &since="", const std::string &until="")
 Return repository versions between timestamps.
std::string read_repository_version ()
 Read and return current repository version.
std::string insert_repository_dir (const std::string &dir, bool push_back=true)
 Insert repository search directory.
void remove_repository_dir (const std::string &dir)
 Remove repository search directory.
const OksClass::Map & classes () const
 Get classes.
size_t number_of_classes () const
 Get number of classes.
const OksObject::Set & objects () const
 Get objects.
size_t number_of_objects () const
 Get number of objects.
OksClass * find_class (const std::string &class_name) const
 Find class by name (C++ string).
OksClass * find_class (const char *class_name) const
 Find class by name (C-string).
void get_all_classes (const std::vector< std::string > &names_in, ClassSet &classes_out) const
 The method searches all classes including subclasses for given names.
void registrate_all_classes (bool skip_registered=false)
 The method rebuilds all classes taking into account inheritance.
bool is_dangling (OksClass *class_ptr) const
 Check pointer on oks class.
bool is_dangling (OksObject *obj_ptr) const
 Check pointer on oks object.
void subscribe_create_class (void(*f)(OksClass *))
 Subscribe on class creation.
void subscribe_change_class (void(*f)(OksClass *, OksClass::ChangeType, const void *))
 Subscribe on class changing.
void subscribe_delete_class (void(*f)(OksClass *))
 Subscribe on class destroying.
void subscribe_create_object (OksObject::notify_obj cb_f, void *parameter)
 Subscribe on object creation.
void subscribe_change_object (OksObject::notify_obj, void *)
 Subscribe on object changing.
void subscribe_delete_object (OksObject::notify_obj, void *)
 Subscribe on object deleting.
void bind_objects ()
 Bind oks objects.
const std::string & get_bind_objects_status () const noexcept
 Return status of oks objects binding.
const std::string & get_bind_classes_status () const noexcept
 Return status of oks classes binding.
void unset_repository_created ()
 Set repository created flag to false to avoid created repository removal in destructor;.

Static Public Member Functions

static const char * GetVersion ()
 Get OKS version. The method returns string containing CVS tag and date of OKS build.
static std::string & get_host_name ()
 Get hostname of given process.
static std::string & get_domain_name ()
 Get domain name of host.
static std::string & get_user_name ()
 Get username of given process.
static bool get_skip_string_range ()
 Get status of string range validator.
static void set_skip_string_range (const bool b)
 Set status of string range validator. To switch 'On'/'Off' use the method's parameter:
static bool check_read_only (OksFile *f)
 Check if the OKS file is read-only.
static const std::string & get_repository_root ()
 Get OKS repository root.
static const std::string & get_repository_mapping_dir ()
 Get OKS repository name.
static std::string get_tmp_file (const std::string &file_name)
 Generates temporal file name.
static const char * get_cwd ()
static void reset_cwd ()
 Reset current working dir in case of chdir() call.
static void set_use_strict_repository_paths (bool flag)
 Set flag to use strict-repository-paths check.

Private Types

template<typename T>
using map_str_t = std::map<std::string, T>

Private Member Functions

std::string create_user_repository_dir ()
void remove_user_repository_dir ()
void k_copy_repository (const std::string &source, const std::string &destination)
void k_checkout_repository (const std::string &param, const std::string &val, const std::string &branch)
 Check out repository files into local user directory.
OksFile * find_file (const std::string &s, const OksFile::Map &files) const
void k_rename_repository_file (OksFile *file_h, const std::string &new_name)
OksFile * k_load_file (const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
void k_load_includes (const OksFile &, OksPipeline *)
bool k_preload_includes (OksFile *file_h, std::set< OksFile * > &new_files, bool allow_schema_extension)
void clear_preload_file_info ()
void restore_preload_file_info ()
OksFile * k_load_schema (const std::string &, const OksFile *)
void k_load_schema (OksFile *fp, std::shared_ptr< OksXmlInputStream > xmls, const OksFile *parent_h)
void k_close_schema (OksFile *)
void k_save_schema (OksFile *, bool force=false, OksFile *=0, const OksClass::Map *=0)
void k_rename_schema (OksFile *, const std::string &short_name, const std::string &long_name)
OksFile * k_load_data (const std::string &, bool, const OksFile *, OksPipeline *)
void k_load_data (OksFile *fp, char format, std::shared_ptr< OksXmlInputStream > xmls, long file_length, bool bind, const OksFile *parent_h, OksPipeline *)
void k_close_data (OksFile *, bool)
void k_save_data (OksFile *, bool=false, OksFile *=nullptr, const OksObject::FSet *=nullptr, bool force_defaults=false)
void k_rename_data (OksFile *, const std::string &short_name, const std::string &long_name)
void k_bind_objects ()
void k_check_bind_classes_status () const noexcept
void unbind_all_rels (const OksObject::FSet &rm_objs, OksObject::FSet &updated) const
 Unbind all references on given oks objects. The method unbinds all relationships referencing given objects.
void k_add (OksClass *)
void k_remove (OksClass *)
void define (OksObject *o)
void undefine (OksObject *o)
void add_data_file (OksFile *)
void add_schema_file (OksFile *)
void remove_data_file (OksFile *)
void remove_schema_file (OksFile *)
bool test_parent (OksFile *file, OksFile::IMap::iterator &i)

Private Attributes

bool p_silence
bool p_verbose
bool p_profiling
bool p_allow_repository
bool p_allow_duplicated_classes
bool p_allow_duplicated_objects
bool p_test_duplicated_objects_via_inheritance
std::string p_user_repository_root
bool p_user_repository_root_inited
bool p_user_repository_root_created
std::string p_repository_version
std::time_t p_repository_checkout_ts
std::time_t p_repository_update_ts
std::shared_mutex p_kernel_mutex
std::mutex p_objects_mutex
std::mutex p_objects_refs_mutex
std::shared_mutex p_schema_mutex
OksFile::Map p_schema_files
OksFile::Map p_data_files
OksFile * p_active_schema
OksFile * p_active_data
bool p_close_all
std::list< std::string > p_repository_dirs
OksClass::Map p_classes
OksProfiler * profiler
OksObject::Set p_objects
std::string p_bind_objects_status
std::string p_bind_classes_status
LoadErrors p_load_errors
std::map< const OksFile *, OksFile * > p_preload_file_info
std::vector< OksFile * > p_preload_added_files
OksObject::notify_obj p_create_object_notify_fn
void * p_create_object_notify_param
OksObject::notify_obj p_change_object_notify_fn
void * p_change_object_notify_param
OksObject::notify_obj p_delete_object_notify_fn
void * p_delete_object_notify_param

Static Private Attributes

static bool p_skip_string_range = false
static bool p_use_strict_repository_paths = true
static std::string p_repository_root
static std::string p_repository_mapping_dir
static std::mutex p_parallel_out_mutex
static char * s_cwd = nullptr
static unsigned long p_count = 0
static int p_threads_pool_size = 0

Friends

class OksFile
class OksClass
class OksObject
struct OksLoadObjectsJob
struct OksData
std::ostream & operator<< (std::ostream &s, OksKernel &k)

Detailed Description

Provides interface to the OKS kernel.

It is responsible for loading OKS data and schema files and it provides access to loaded OKS classes and their objects.

To work with OKS schema the following base methods are available:

To work with OKS data the following base methods are available:

  • load_data() - load OKS data from file (i.e. read description of OKS objects)
  • reload_data() - reload data file, e.g. to revert to saved data or when it was modified by external process
  • new_data() - create new OKS data file
  • set_active_data() - use this data file for newly created classes
  • save_data() - save OKS data file
  • close_data() - close OKS data file and unload all objects from it
  • objects() - get all objects (unsorted by classes or IDs)

To work with OKS server the following methods can be used:

When schema or data are modified, the process can give callback using the following methods:

When objects are created in unordered manner or by efficiency reasons files are loaded with non-bind option, the objects can be bind (i.e. linked) using the following methods:

In case of problems most of above methods throw exceptions derived from oks::exception class.

Most of the OksKernel methods are thread-safe. Those which are not thread-safe, are started from prefix "k_".

Definition at line 614 of file kernel.hpp.

Member Typedef Documentation

◆ map_str_t

template<typename T>
using dunedaq::oks::OksKernel::map_str_t = std::map<std::string, T>
private

Definition at line 624 of file kernel.hpp.

Member Enumeration Documentation

◆ RepositoryUpdateType

Enumerator
DiscardChanges 
MergeChanges 
NoChanges 

Definition at line 1555 of file kernel.hpp.

Constructor & Destructor Documentation

◆ OksKernel() [1/2]

dunedaq::oks::OksKernel::OksKernel ( bool silence_mode = false,
bool verbose_mode = false,
bool profiling_mode = false,
bool allow_repository = true,
const char * version = nullptr,
std::string branch_name = "" )

Constructor to build OksKernel object.

All parameters of the constructor are optional.

Parameters
silence_mode- defines kernel silence mode
verbose_mode- defines kernel verbose mode
profiling_mode- switch kernel into profiling mode

Definition at line 675 of file kernel.cpp.

676 : p_silence(sm)
677 , p_verbose(vm)
678 , p_profiling(tm)
679 , p_allow_repository(allow_repository)
685 , p_active_schema(nullptr)
686 , p_active_data(nullptr)
687 , p_close_all(false)
688 , profiler(nullptr)
695{
696 OSK_VERBOSE_REPORT("Enter OksKernel::OksKernel(" << sm << ", " << vm << ", " << tm << ')')
697
698 struct __InitFromEnv__
699 {
700 const char* name;
701 bool& value;
702 } vars[] = { { "OKS_KERNEL_VERBOSE", p_verbose },
703 { "OKS_KERNEL_SILENCE", p_silence },
704 { "OKS_KERNEL_PROFILING", p_profiling },
705 { "OKS_KERNEL_ALLOW_REPOSITORY", p_allow_repository },
706 { "OKS_KERNEL_ALLOW_DUPLICATED_CLASSES", p_allow_duplicated_classes },
707 { "OKS_KERNEL_ALLOW_DUPLICATED_OBJECTS", p_allow_duplicated_objects },
708 { "OKS_KERNEL_TEST_DUPLICATED_OBJECTS_VIA_INHERITANCE", p_test_duplicated_objects_via_inheritance },
709 { "OKS_KERNEL_SKIP_STRING_RANGE", p_skip_string_range } };
710
711 for (unsigned int i = 0; i < sizeof(vars) / sizeof(__InitFromEnv__); ++i) {
712 if (char* s = getenv(vars[i].name)) {
713 vars[i].value = (strcmp(s, "no")) ? true : false;
714 }
715 }
716
717 {
718 const char* oks_db_root = getenv("OKS_DB_ROOT");
719
720 if (oks_db_root == nullptr || *oks_db_root == 0)
721 oks_db_root = getenv("DUNEDAQ_DB_PATH");
722 else
724
725 OSK_VERBOSE_REPORT("database root = \'" << oks_db_root << "\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
726
727 // if not defined, set oks_db_root to empty string (to avoid std::string constructor crash when string is 0)
728
729 if (oks_db_root == nullptr)
730 oks_db_root = "";
731
732 // temporal set
733
734 Oks::Tokenizer t(oks_db_root, ":");
735 std::string token;
736
737 while (t.next(token))
739 }
740
741 {
742 std::unique_lock lock(p_kernel_mutex);
743
744 if (!p_count++) {
748 }
749
750 get_cwd();
751 }
752
753 {
754 static std::once_flag flag;
755
756 std::call_once(flag, []() {
757 if (char* s = getenv("OKS_KERNEL_THREADS_POOL_SIZE")) {
758 if (*s != '\0') {
759 p_threads_pool_size = atoi(s);
760 if (p_threads_pool_size < 1)
762 }
763 }
764
765 if (!p_threads_pool_size) {
766 errno = 0;
767 p_threads_pool_size = sysconf(_SC_NPROCESSORS_ONLN);
768 if (p_threads_pool_size == -1 && !errno) {
769 Oks::error_msg("OksKernel::OksKernel()") << " sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno
770 << ": \'" << strerror(errno) << '\'' << std::endl;
772 }
773 }
774
777
778 TLOG_DEBUG(2) << "Threads pool size: " << p_threads_pool_size;
779 });
780 }
781
782 // process OKS server URL settings if any
783 if (p_allow_repository && !get_repository_root().empty()) {
784 if (get_user_repository_root().empty()) {
785 // parse specific version option if any
786 std::string param, val;
787
788 if (!version)
789 version = getenv("TDAQ_DB_VERSION");
790
791 if (version) {
792 if (*version) {
793 if (const char* value = strchr(version, ':')) {
794 param.assign(version, value - version);
795 val.assign(value + 1);
796 } else
797 Oks::error_msg("OksKernel::OksKernel")
798 << "bad version value \"" << version
799 << "\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
800 }
801 }
802
803 try {
804 std::string tmp_dirname = OksKernel::create_user_repository_dir();
805
806 set_user_repository_root(tmp_dirname);
809
810 if (branch_name.empty())
811 if (const char* var = getenv("TDAQ_DB_BRANCH"))
812 branch_name = var;
813
814 k_checkout_repository(param, val, branch_name);
815 } catch (exception& ex) {
816 Oks::error_msg("OksKernel::OksKernel") << "cannot check out user repository: " << ex.what() << std::endl;
817 }
818 } else {
819 if (!p_silence) {
820 try {
821 std::lock_guard lock(p_parallel_out_mutex);
822 std::cout << "attach to repository \"" << get_user_repository_root() << "\" version "
823 << read_repository_version() << std::endl;
824 } catch (exception& ex) {
825 Oks::error_msg("OksKernel::OksKernel") << "cannot read user repository version: " << ex.what() << std::endl;
826 }
827 }
828 }
829 }
830
831#ifndef ERS_NO_DEBUG
832 if (p_profiling)
833 profiler = (OksProfiler*)new OksProfiler();
834#endif
835}
void insert(const std::string &path)
Definition kernel.cpp:91
static NotifyFN create_notify_fn
Definition class.hpp:911
static NotifyFN delete_notify_fn
Definition class.hpp:913
static ChangeNotifyFN change_notify_fn
Definition class.hpp:912
OksObject::notify_obj p_change_object_notify_fn
Definition kernel.hpp:2098
const std::string & get_user_repository_root() const
Get user OKS repository root.
Definition kernel.cpp:335
static bool p_use_strict_repository_paths
Definition kernel.hpp:1952
static std::mutex p_parallel_out_mutex
Definition kernel.hpp:1969
void set_user_repository_root(const std::string &path, const std::string &version="")
Set user OKS repository root.
Definition kernel.cpp:353
OksProfiler * profiler
Definition kernel.hpp:1991
std::string create_user_repository_dir()
Definition kernel.cpp:2061
OksObject::notify_obj p_delete_object_notify_fn
Definition kernel.hpp:2101
void * p_delete_object_notify_param
Definition kernel.hpp:2102
static int p_threads_pool_size
Definition kernel.hpp:1995
static unsigned long p_count
Definition kernel.hpp:1989
std::string read_repository_version()
Read and return current repository version.
Definition kernel.cpp:5258
std::string p_user_repository_root
Definition kernel.hpp:1956
static bool p_skip_string_range
Definition kernel.hpp:1951
static const std::string & get_repository_root()
Get OKS repository root.
Definition kernel.cpp:280
void * p_change_object_notify_param
Definition kernel.hpp:2099
static const char * get_cwd()
Definition kernel.cpp:636
std::shared_mutex p_kernel_mutex
Definition kernel.hpp:1965
bool p_test_duplicated_objects_via_inheritance
Definition kernel.hpp:1949
OksObject::notify_obj p_create_object_notify_fn
Definition kernel.hpp:2095
std::string insert_repository_dir(const std::string &dir, bool push_back=true)
Insert repository search directory.
Definition kernel.cpp:1264
void k_checkout_repository(const std::string &param, const std::string &val, const std::string &branch)
Check out repository files into local user directory.
Definition kernel.cpp:4643
void * p_create_object_notify_param
Definition kernel.hpp:2096
static std::ostream & error_msg(const char *)
Definition kernel.cpp:511
#define OSK_VERBOSE_REPORT(MSG)
Definition defs.hpp:83
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:111
static GitFoldersHolder s_git_folders
Definition kernel.cpp:108

◆ OksKernel() [2/2]

dunedaq::oks::OksKernel::OksKernel ( const OksKernel & src,
bool copy_repository = false )

Copy constructor.

It is used by RDB RW server to make fast copy.

Parameters
src- kernel to copy

Definition at line 837 of file kernel.cpp.

838 : p_silence(src.p_silence)
839 , p_verbose(src.p_verbose)
840 , p_profiling(src.p_profiling)
841 , p_allow_repository(src.p_allow_repository)
842 , p_allow_duplicated_classes(src.p_allow_duplicated_classes)
843 , p_allow_duplicated_objects(src.p_allow_duplicated_objects)
844 , p_test_duplicated_objects_via_inheritance(src.p_test_duplicated_objects_via_inheritance)
845 , p_user_repository_root(src.p_user_repository_root)
846 , p_user_repository_root_inited(src.p_user_repository_root_inited)
848 , p_repository_version(src.p_repository_version)
849 , p_repository_checkout_ts(src.p_repository_checkout_ts)
850 , p_repository_update_ts(src.p_repository_update_ts)
851 , p_active_schema(nullptr)
852 , p_active_data(nullptr)
853 , p_close_all(false)
854 , profiler(nullptr)
861{
862
863 {
864 std::unique_lock lock(p_kernel_mutex);
865 p_count++;
866 }
867
868 if (copy_repository && p_user_repository_root_inited) {
869 try {
874 k_copy_repository(src.p_user_repository_root, p_user_repository_root);
875 } catch (exception& ex) {
876 Oks::error_msg("OksKernel::OksKernel") << "cannot copy user repository: " << ex.what() << std::endl;
878 throw;
879 }
880
882 }
883
884 // copy repository directories
885 for (const auto& i : src.p_repository_dirs)
886 p_repository_dirs.push_back(i);
887
888 // copy schema and data files
889 {
890 const OksFile::Map* src_files[2] = { &src.p_schema_files, &src.p_data_files };
891 OksFile::Map* dst_files[2] = { &p_schema_files, &p_data_files };
892
893 for (int i = 0; i < 2; ++i) {
894 for (const auto& j : *src_files[i]) {
895 OksFile* f = new OksFile(*j.second);
896 f->p_kernel = this;
897 (*dst_files[i])[&f->p_full_name] = f;
898 }
899 }
900 }
901
902 // search a class in map is not efficient, if there are many such operations; use array with class index for fast
903 // search
904 OksClass** c_table = new OksClass*[src.p_classes.size()];
905 unsigned int idx(0);
906
907 // copy classes: first iteration to define class names and simple properties
908 for (const auto& i : src.p_classes) {
909 const OksClass& src_c(*i.second);
910 OksClass* c = new OksClass(src_c.p_name,
911 src_c.p_description,
912 src_c.p_abstract,
913 nullptr,
914 src_c.p_transient); // pass 0 kernel to avoid class insertion
915
916 c->p_kernel = this;
917 p_classes[c->get_name().c_str()] = c;
918
919 const_cast<OksClass&>(src_c).p_id = idx++;
920 c->p_id = src_c.p_id;
921 c_table[c->p_id] = c;
922
923 c->p_abstract = src_c.p_abstract;
924 c->p_to_be_deleted = src_c.p_to_be_deleted;
925 c->p_instance_size = src_c.p_instance_size;
926 c->p_file = (*p_schema_files.find(&src_c.p_file->p_full_name)).second;
927 c->p_objects = (src_c.p_objects ? new OksObject::Map() : nullptr);
928
929 // copy super-classes
930 if (const std::list<std::string*>* scls = src_c.p_super_classes) {
931 c->p_super_classes = new std::list<std::string*>();
932
933 for (const auto& j : *scls)
934 c->p_super_classes->push_back(new std::string(*j));
935 }
936
937 // copy direct attributes
938 if (const std::list<OksAttribute*>* attrs = src_c.p_attributes) {
939 c->p_attributes = new std::list<OksAttribute*>();
940
941 for (const auto& j : *attrs) {
942 OksAttribute* a = new OksAttribute(j->p_name, c);
943
944 a->p_range = j->p_range;
945 a->p_data_type = j->p_data_type;
946 a->p_multi_values = j->p_multi_values;
947 a->p_no_null = j->p_no_null;
948 a->p_init_value = j->p_init_value;
949 a->p_init_data = j->p_init_data;
950 a->p_format = j->p_format;
951 a->p_description = j->p_description;
952
953 if (j->p_enumerators)
954 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
955
956 c->p_attributes->push_back(a);
957 }
958 }
959
960 // copy direct relationships
961 if (const std::list<OksRelationship*>* rels = src_c.p_relationships) {
962 c->p_relationships = new std::list<OksRelationship*>();
963
964 for (const auto& j : *rels) {
965 OksRelationship* r = new OksRelationship(j->p_name, c);
966
967 r->p_rclass = j->p_rclass;
968 r->p_low_cc = j->p_low_cc;
969 r->p_high_cc = j->p_high_cc;
970 r->p_composite = j->p_composite;
971 r->p_exclusive = j->p_exclusive;
972 r->p_dependent = j->p_dependent;
973 r->p_description = j->p_description;
974
975 c->p_relationships->push_back(r);
976 }
977 }
978
979 // copy direct methods
980 if (const std::list<OksMethod*>* mets = src_c.p_methods) {
981 c->p_methods = new std::list<OksMethod*>();
982
983 for (const auto& j : *mets) {
984 OksMethod* m = new OksMethod(j->p_name, j->p_description, c);
985
986 if (const std::list<OksMethodImplementation*>* impls = j->p_implementations) {
987 m->p_implementations = new std::list<OksMethodImplementation*>();
988
989 for (const auto& x : *impls)
990 m->p_implementations->push_back(
991 new OksMethodImplementation(x->get_language(), x->get_prototype(), x->get_body(), m));
992 }
993
994 c->p_methods->push_back(m);
995 }
996 }
997 }
998
999 // copy classes: second iteration to resolve pointers to classes
1000
1001 for (const auto& i : src.p_classes) {
1002 OksClass* c = c_table[i.second->p_id];
1003
1004 // link p_class_type of relationship
1005 if (const std::list<OksRelationship*>* rels = i.second->p_relationships) {
1006 for (const auto& j : *rels)
1007 c->find_relationship(j->get_name())->p_class_type =
1008 (j->p_class_type ? c_table[j->p_class_type->p_id] : nullptr);
1009 }
1010
1011 // copy all super- and sub- classes
1012 if (const OksClass::FList* spcls = i.second->p_all_super_classes) {
1013 c->p_all_super_classes = new OksClass::FList();
1014
1015 for (const auto& j : *spcls)
1016 c->p_all_super_classes->push_back(c_table[j->p_id]);
1017 }
1018
1019 if (const OksClass::FList* sbcls = i.second->p_all_sub_classes) {
1020 c->p_all_sub_classes = new OksClass::FList();
1021
1022 for (const auto& j : *sbcls)
1023 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1024 }
1025
1026 // create oks object layout information
1027 c->p_data_info = new OksDataInfo::Map();
1028 size_t instance_size = 0;
1029
1030 // copy all attributes
1031 if (const std::list<OksAttribute*>* attrs = i.second->p_all_attributes) {
1032 c->p_all_attributes = new std::list<OksAttribute*>();
1033
1034 for (const auto& j : *attrs) {
1035 OksAttribute* a = (c_table[j->p_class->p_id])->find_direct_attribute(j->get_name());
1036 c->p_all_attributes->push_back(a);
1037 (*c->p_data_info)[a->get_name()] = new OksDataInfo(instance_size++, a);
1038 }
1039 }
1040
1041 // copy all relationships
1042 if (const std::list<OksRelationship*>* rels = i.second->p_all_relationships) {
1043 c->p_all_relationships = new std::list<OksRelationship*>();
1044
1045 for (const auto& j : *rels) {
1046 OksRelationship* r = (c_table[j->p_class->p_id])->find_direct_relationship(j->get_name());
1047 c->p_all_relationships->push_back(r);
1048 (*c->p_data_info)[r->get_name()] = new OksDataInfo(instance_size++, r);
1049 }
1050 }
1051
1052 // copy all methods
1053 if (const std::list<OksMethod*>* mets = i.second->p_all_methods) {
1054 c->p_all_methods = new std::list<OksMethod*>();
1055
1056 for (const auto& j : *mets)
1057 c->p_all_methods->push_back((c_table[j->p_class->p_id])->find_direct_method(j->get_name()));
1058 }
1059
1060 // copy inheritance hierarchy
1061 if (const std::vector<OksClass*>* ih = i.second->p_inheritance_hierarchy) {
1062 c->p_inheritance_hierarchy = new std::vector<OksClass*>();
1063 c->p_inheritance_hierarchy->reserve(ih->size());
1064
1065 for (const auto& j : *ih)
1066 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1067 }
1068 }
1069
1070 // copy objects
1071
1072 if (!src.p_objects.empty()) {
1073
1074 // search an object in a class is not efficien, if there are many such operations
1075 // use array with class index for fast search
1076
1077 OksObject** o_table = new OksObject*[src.p_objects.size()];
1078 idx = 0;
1079
1080 // first iteration: create objects with attributes
1081
1082 for (OksObject::Set::const_iterator i = src.p_objects.begin(); i != src.p_objects.end(); ++i, ++idx) {
1083 OksObject* src_o(*i);
1084 src_o->p_user_data = reinterpret_cast<void*>(idx);
1085
1086 OksClass* c = c_table[src_o->uid.class_id->p_id];
1087
1088 OksObject* o = new OksObject(c,
1089 src_o->uid.object_id,
1090 src_o->p_user_data,
1091 src_o->p_int32_id,
1092 src_o->p_duplicated_object_id_idx,
1093 (*p_data_files.find(&src_o->file->p_full_name)).second);
1094
1095 o_table[idx] = o;
1096 (*c->p_objects)[&o->uid.object_id] = o;
1097 p_objects.insert(o);
1098
1099 if (size_t num_of_attrs = c->number_of_all_attributes()) {
1100 const OksData* src_data = src_o->data;
1101 OksData* dst_data = o->data;
1102
1103 std::list<OksAttribute*>::const_iterator ia_dst = c->all_attributes()->begin();
1104 std::list<OksAttribute*>::const_iterator ia_src = src_o->uid.class_id->all_attributes()->begin();
1105
1106 for (size_t j = 0; j < num_of_attrs; ++j) {
1107 *dst_data = *src_data;
1108
1109 OksAttribute* a_dst(*ia_dst);
1110
1111 // process in a special way CLASS type (reference on class)
1112
1113 if (a_dst->get_data_type() == OksData::class_type) {
1114 if (a_dst->get_is_multi_values() == false) {
1115 dst_data->data.CLASS = c_table[src_data->data.CLASS->p_id];
1116 } else {
1117 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1118 OksData::List::iterator li_src = src_data->data.LIST->begin();
1119
1120 while (li_dst != dst_data->data.LIST->end()) {
1121 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1122 ++li_dst;
1123 ++li_src;
1124 }
1125 }
1126 }
1127
1128 // process in a special way ENUM type (reference on attribute's data)
1129
1130 else if (a_dst->get_data_type() == OksData::enum_type) {
1131 OksAttribute* a_src(*ia_src);
1132 const std::string* p_enumerators_first(&((*(a_src->p_enumerators))[0]));
1133
1134 if (a_dst->get_is_multi_values() == false) {
1135 unsigned long dx = src_data->data.ENUMERATION - p_enumerators_first;
1136 dst_data->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1137 } else {
1138 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1139 OksData::List::iterator li_src = src_data->data.LIST->begin();
1140
1141 while (li_dst != dst_data->data.LIST->end()) {
1142 unsigned long dx = (*li_src)->data.ENUMERATION - p_enumerators_first;
1143 (*li_dst)->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1144 ++li_dst;
1145 ++li_src;
1146 }
1147 }
1148 }
1149
1150 src_data++;
1151 dst_data++;
1152
1153 ia_dst++;
1154 ia_src++;
1155 }
1156 }
1157 }
1158
1159 // second iteration: link relationships of objects
1160
1161 for (const auto& src_o : src.p_objects) {
1162 OksClass* c = c_table[src_o->uid.class_id->p_id];
1163 OksObject* o(o_table[reinterpret_cast<unsigned long>(src_o->p_user_data)]);
1164
1165 if (size_t num_of_rels = c->number_of_all_relationships()) {
1166 const OksData* src_data(src_o->data + c->number_of_all_attributes());
1167 OksData* dst_data(o->data + c->number_of_all_attributes());
1168
1169 for (size_t j = 0; j < num_of_rels; ++j) {
1170 dst_data->type = src_data->type;
1171 switch (src_data->type) {
1172 case OksData::list_type:
1173 dst_data->data.LIST = new OksData::List();
1174 for (const auto& x : *src_data->data.LIST) {
1175 OksData* d = new OksData();
1176
1177 if (x->type == OksData::object_type) {
1178 if (const OksObject* o2 = x->data.OBJECT) {
1179 d->Set(o_table[reinterpret_cast<unsigned long>(o2->p_user_data)]);
1180 } else {
1181 d->Set((OksObject*)nullptr);
1182 }
1183 } else if (x->type == OksData::uid_type) {
1184 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1185 } else if (x->type == OksData::uid2_type) {
1186 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1187 } else {
1188 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship list"));
1189 }
1190
1191 dst_data->data.LIST->push_back(d);
1192 }
1193 break;
1194
1196 if (const OksObject* o2 = src_data->data.OBJECT) {
1197 dst_data->data.OBJECT = o_table[reinterpret_cast<unsigned long>(o2->p_user_data)];
1198 } else {
1199 dst_data->data.OBJECT = 0;
1200 }
1201 break;
1202
1203 case OksData::uid_type:
1204 dst_data->data.UID.class_id = c_table[src_data->data.UID.class_id->p_id];
1205 dst_data->data.UID.object_id = new OksString(*src_data->data.UID.object_id);
1206 break;
1207
1208 case OksData::uid2_type:
1209 dst_data->data.UID2.class_id = new OksString(*src_data->data.UID2.class_id);
1210 dst_data->data.UID2.object_id = new OksString(*src_data->data.UID2.object_id);
1211 break;
1212
1213 default:
1214 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship"));
1215 break;
1216 }
1217
1218 src_data++;
1219 dst_data++;
1220 }
1221 }
1222
1223 if (const std::list<OksRCR*>* src_rcrs = src_o->p_rcr) {
1224 o->p_rcr = new std::list<OksRCR*>();
1225
1226 for (const auto& j : *src_rcrs)
1227 o->p_rcr->push_back(new OksRCR(
1228 o_table[reinterpret_cast<unsigned long>(j->obj->p_user_data)],
1229 (c_table[j->relationship->p_class->p_id])->find_direct_relationship(j->relationship->get_name())));
1230 } else {
1231 o->p_rcr = nullptr;
1232 }
1233 }
1234
1235 delete[] o_table;
1236 }
1237
1238 delete[] c_table;
1239
1240 // rename all files
1241 if (copy_repository && p_user_repository_root_inited) {
1242 OksFile::Map* files_map[2] = { &p_schema_files, &p_data_files };
1243
1244 for (int i = 0; i < 2; ++i) {
1245 std::vector<OksFile*> files;
1246
1247 for (auto& f : *files_map[i])
1248 files.push_back(f.second);
1249
1250 files_map[i]->clear();
1251
1252 for (auto& f : files) {
1253 std::string name = p_user_repository_root;
1254 name.push_back('/');
1255 name.append(f->get_repository_name());
1256 f->rename(name);
1257 (*files_map[i])[&f->p_full_name] = f;
1258 }
1259 }
1260 }
1261}
#define ERS_HERE
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:254
OksClass(const std::string &name, OksKernel *kernel, bool transient=false)
Create OKS class.
Definition class.cpp:81
OksFile(const std::string &, const std::string &, const std::string &, const std::string &, OksKernel *)
Definition file.cpp:264
std::map< const std::string *, OksFile *, SortByName > Map
Definition file.hpp:382
friend class OksClass
Definition kernel.hpp:618
std::string p_repository_version
Definition kernel.hpp:1959
std::time_t p_repository_checkout_ts
Definition kernel.hpp:1960
OksClass::Map p_classes
Definition kernel.hpp:1987
OksFile::Map p_schema_files
Definition kernel.hpp:1973
friend struct OksData
Definition kernel.hpp:621
std::list< std::string > p_repository_dirs
Definition kernel.hpp:1983
void remove_user_repository_dir()
Definition kernel.cpp:4706
std::time_t p_repository_update_ts
Definition kernel.hpp:1961
void k_copy_repository(const std::string &source, const std::string &destination)
Definition kernel.cpp:4723
friend class OksFile
Definition kernel.hpp:617
friend class OksObject
Definition kernel.hpp:619
OksObject::Set p_objects
Definition kernel.hpp:1993
OksFile::Map p_data_files
Definition kernel.hpp:1974
OksMethodImplementation(const std::string &language, const std::string &prototype, const std::string &body, OksMethod *p=nullptr)
OKS method implementation constructor.
Definition method.cpp:28
OksMethod(const std::string &name, OksClass *p=nullptr)
OKS method constructor.
Definition method.cpp:116
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
Definition object.hpp:1170
OksObject(const OksClass *oks_class, const char *object_id=0, bool skip_init=false)
OKS object constructor.
Definition object.cpp:1151
OksRelationship(const std::string &name, OksClass *p=nullptr)
OKS relationship simple constructor.
OksString()
to deallocate memory when destroyed
Definition object.hpp:421
static bool real_path(std::string &, bool ignore_errors)
Definition kernel.cpp:546
void error(const Issue &issue)
Definition ers.hpp:101
OksDataInfo(size_t o, const OksAttribute *a)
Constructors.
Definition object.hpp:387
std::map< std::string, OksDataInfo * > Map
Declare map of pointers to OksDataInfo (unsorted by name).
Definition object.hpp:383
std::list< OksData *, boost::fast_pool_allocator< OksData * > > List
Definition object.hpp:515
OksRCR(OksObject *o, const OksRelationship *r)
Definition object.hpp:1082

◆ ~OksKernel()

dunedaq::oks::OksKernel::~OksKernel ( )

Definition at line 1326 of file kernel.cpp.

1327{
1328 {
1330 OSK_VERBOSE_REPORT("ENTER OksKernel::~OksKernel()")
1331
1334
1335 std::unique_lock lock(p_kernel_mutex);
1336
1337 p_classes.erase(p_classes.begin(), p_classes.end());
1338
1339 --p_count;
1340
1341 if (p_count == 0) {
1342 std::lock_guard scoped_lock(s_get_cwd_mutex);
1343 delete[] s_cwd;
1344 s_cwd = nullptr;
1345 }
1346
1348 }
1349
1350#ifndef ERS_NO_DEBUG
1351 if (p_profiling)
1352 std::cout << *profiler << std::endl;
1353#endif
1354
1355 OSK_VERBOSE_REPORT("LEAVE OksKernel::~OksKernel()")
1356}
static char * s_cwd
Definition kernel.hpp:1985
void close_all_data()
Close all OKS data files.
Definition kernel.cpp:4027
void close_all_schema()
Close all OKS schema files.
Definition kernel.cpp:2679
#define OSK_PROFILING(FID, K)
Definition defs.hpp:96
static std::mutex s_get_cwd_mutex
Definition kernel.cpp:57

Member Function Documentation

◆ add_data_file()

void dunedaq::oks::OksKernel::add_data_file ( OksFile * f)
private

Definition at line 3546 of file kernel.cpp.

3547{
3548 p_data_files[&f->p_full_name] = f;
3549}

◆ add_schema_file()

void dunedaq::oks::OksKernel::add_schema_file ( OksFile * f)
private

Definition at line 3552 of file kernel.cpp.

3553{
3554 p_schema_files[&f->p_full_name] = f;
3555}

◆ backup_data()

void dunedaq::oks::OksKernel::backup_data ( OksFile * pf,
const char * suffix = ".bak" )

Backup OKS data file.

The method makes a backup of given OKS data file. The save operation is silent and ignores any consistency rules. The file is always saved in extended format.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
suffixa suffix to be added to the name of file
Exceptions
Throwoks::exception in case of problems.

Definition at line 3586 of file kernel.cpp.

3587{
3588 std::shared_lock lock(p_kernel_mutex);
3589
3590 OksFile f(pf->get_full_file_name() + suffix, pf->get_logical_name(), pf->get_type(), pf->get_oks_format(), this);
3591
3592 f.p_created_by = pf->p_created_by;
3593 f.p_creation_time = pf->p_creation_time;
3594 f.p_created_on = pf->p_created_on;
3595 f.p_list_of_include_files = pf->p_list_of_include_files;
3596
3597 if (!p_silence) {
3598 std::lock_guard lock(p_parallel_out_mutex);
3599 std::cout << "Making backup of data file \"" << pf->p_full_name << "\"...\n";
3600 }
3601
3602 bool silence = p_silence;
3603
3604 p_silence = true;
3605
3606 try {
3607 k_save_data(&f, true, pf);
3608 } catch (exception& ex) {
3609 p_silence = silence;
3610 throw CanNotBackupFile(pf->p_full_name, ex);
3611 }
3612
3613 p_silence = silence;
3614}
CanNotBackupFile(const std::string &name, const exception &reason) noexcept
Definition kernel.hpp:250
void k_save_data(OksFile *, bool=false, OksFile *=nullptr, const OksObject::FSet *=nullptr, bool force_defaults=false)
Definition kernel.cpp:3619

◆ backup_schema()

void dunedaq::oks::OksKernel::backup_schema ( OksFile * pf,
const char * suffix = ".bak" )

Backup OKS schema file.

The method makes a backup of given OKS schema file. The save operation is silent and ignores any consistency rules.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
suffixa suffix to be added to the name of file
Exceptions
Throwoks::exception in case of problems.

Definition at line 2371 of file kernel.cpp.

2372{
2373 std::shared_lock lock(p_kernel_mutex);
2374
2375 OksFile f(pf->get_full_file_name() + suffix, pf->get_logical_name(), pf->get_type(), pf->get_oks_format(), this);
2376
2377 f.p_created_by = pf->p_created_by;
2378 f.p_creation_time = pf->p_creation_time;
2379 f.p_created_on = pf->p_created_on;
2380 f.p_list_of_include_files = pf->p_list_of_include_files;
2381
2382 if (!p_silence) {
2383 std::cout << "Making backup of schema file \"" << pf->p_full_name << "\"...\n";
2384 }
2385
2386 bool silence = p_silence;
2387
2388 p_silence = true;
2389
2390 try {
2391 k_save_schema(&f, true, pf);
2392 } catch (exception& ex) {
2393 p_silence = silence;
2394 throw CanNotBackupFile(pf->p_full_name, ex);
2395 }
2396
2397 p_silence = silence;
2398}
void k_save_schema(OksFile *, bool force=false, OksFile *=0, const OksClass::Map *=0)
Definition kernel.cpp:2403

◆ bind_objects()

void dunedaq::oks::OksKernel::bind_objects ( )

Bind oks objects.

The method sets links between oks objects converting whenever it is possible values of relationships from the UID types to the OksObject pointer. It is used after sequential loading of several data files with bind_objects parameter set to false.

The status of the last bind objects call can be checked using get_bind_objects_status() method.

Exceptions
Throwoks::exception in case of problems.

Definition at line 4138 of file kernel.cpp.

4139{
4140 std::unique_lock lock(p_kernel_mutex);
4142}

◆ check_read_only()

bool dunedaq::oks::OksKernel::check_read_only ( OksFile * f)
static

Check if the OKS file is read-only.

Method returns true if the file is read-only and false if it is not. The method also changes the read-only flag in the file descriptor.

The method is thread-safe.

Definition at line 1394 of file kernel.cpp.

1395{
1396 static std::string suffix;
1397 static std::once_flag flag;
1398
1399 std::call_once(flag, []() {
1400 std::ostringstream s;
1401 s << '-' << get_user_name() << ':' << get_host_name() << ':' << getpid() << std::ends;
1402 suffix = s.str();
1403 });
1404
1405 std::string s(fp->p_full_name);
1406 s.append(suffix);
1407
1408 {
1409 static std::mutex p_check_read_only_mutex;
1410 std::lock_guard scoped_lock(p_check_read_only_mutex);
1411
1412 {
1413 std::ofstream f(s.c_str(), std::ios::out);
1414 fp->p_is_read_only = (!f.good());
1415 }
1416
1417 TLOG_DEBUG(3) << "read-only test on file \"" << s << "\" returns " << fp->p_is_read_only;
1418
1419 if (!fp->p_is_read_only) {
1420 unlink(s.c_str());
1421 }
1422
1423 return fp->p_is_read_only;
1424 }
1425}
static std::string & get_host_name()
Get hostname of given process.
Definition kernel.cpp:392
static std::string & get_user_name()
Get username of given process.
Definition kernel.cpp:427

◆ classes()

const OksClass::Map & dunedaq::oks::OksKernel::classes ( ) const
inline

Get classes.

In multi-threaded environment to iterate through the set it could be necessary to acquire at least read oks kernel lock before calling the method to be sure that another thread does not modify the set of classes (i.e. destroy or create classes, open or close oks schema files).

Returns
The method returns const reference on set of classes loaded in-memory.

Definition at line 1711 of file kernel.hpp.

1711{ return p_classes; }

◆ clear_preload_file_info()

void dunedaq::oks::OksKernel::clear_preload_file_info ( )
private

Definition at line 3313 of file kernel.cpp.

3314{
3315 for (std::map<const OksFile*, OksFile*>::iterator i = p_preload_file_info.begin(); i != p_preload_file_info.end();
3316 ++i) {
3317 delete i->second;
3318 }
3319
3320 p_preload_file_info.clear();
3321 p_preload_added_files.clear();
3322}
std::vector< OksFile * > p_preload_added_files
Definition kernel.hpp:2003
std::map< const OksFile *, OksFile * > p_preload_file_info
Definition kernel.hpp:2002

◆ close_all_data()

void dunedaq::oks::OksKernel::close_all_data ( )

Close all OKS data files.

The method closes all OKS data files which were created or loaded by the OKS kernel.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 4027 of file kernel.cpp.

4028{
4029 TLOG_DEBUG(4) << "enter";
4030
4031 {
4032 std::unique_lock lock(p_kernel_mutex);
4033
4034 p_close_all = true;
4035
4036 while (!p_data_files.empty()) {
4037 k_close_data(p_data_files.begin()->second, false);
4038 }
4039
4040 if (!p_objects.empty()) {
4041 for (OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4042 delete *i;
4043 }
4044
4045 p_objects.clear();
4046
4047 for (OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
4048 if (i->second->p_objects) {
4049 delete i->second->p_objects;
4050 i->second->p_objects = 0;
4051 }
4052 }
4053 }
4054
4055 p_close_all = false;
4056 }
4057
4058 TLOG_DEBUG(4) << "exit";
4059}
void k_close_data(OksFile *, bool)
Definition kernel.cpp:3975

◆ close_all_schema()

void dunedaq::oks::OksKernel::close_all_schema ( )

Close all OKS schema files.

The method closes all OKS schema files which were created or loaded by the OKS kernel.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 2679 of file kernel.cpp.

2680{
2681 TLOG_DEBUG(4) << "enter";
2682
2683 {
2684 std::unique_lock lock(p_kernel_mutex);
2685
2686 for (OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2687 i->second->p_to_be_deleted = true;
2688 }
2689
2690 while (!p_schema_files.empty()) {
2691 k_close_schema(p_schema_files.begin()->second);
2692 }
2693 }
2694
2695 TLOG_DEBUG(4) << "exit";
2696}
void k_close_schema(OksFile *)
Definition kernel.cpp:2625

◆ close_data()

void dunedaq::oks::OksKernel::close_data ( OksFile * file_h,
bool unbind_objects = true )

Close OKS data file.

The method closes given OKS data file. All objects belonging to this data file will be destroyed in-memory. The relationships values of objects from others data files loaded in-memory will be converted from OksObject pointer to UID for all objects of closing data file, if the unbind_objects parameter is true. If it is necessary to close all loaded data files, it is recommended to use close_all_data() method and do not use close_data(..., true) method sequentially by performance reasons.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
unbind_objectsconvert values of relationships pointing to objects of closing data file from OksObject pointer to the UID

Definition at line 3966 of file kernel.cpp.

3967{
3968 std::unique_lock lock(p_kernel_mutex);
3969 k_close_data(fp, unbind);
3970}

◆ close_schema()

void dunedaq::oks::OksKernel::close_schema ( OksFile * file_h)

Close OKS schema file.

The method closes given OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method

Definition at line 2616 of file kernel.cpp.

2617{
2618 std::unique_lock lock(p_kernel_mutex);
2619 k_close_schema(pf);
2620}

◆ commit_repository()

void dunedaq::oks::OksKernel::commit_repository ( const std::string & comments,
const std::string & credentials = "" )

Commit user modifications into repository.

The method commits changes made in user repository into origin GIT repository.

Parameters
commentsuser comments
credentialsdaq token to get real user name (ignore, if empty)
Exceptions
Throwoks::exception in case of problems.

Definition at line 4828 of file kernel.cpp.

4829{
4830 std::unique_lock lock(p_kernel_mutex);
4831
4832 if (OksKernel::get_repository_root().empty())
4833 throw RepositoryOperationFailed("commit",
4834 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4835
4836 if (get_user_repository_root().empty())
4838 "commit", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4839
4840 std::string cmd("oks-commit.sh");
4841
4842 if (get_verbose_mode())
4843 cmd.append(" -v");
4844
4845 cmd.append(" -u ");
4846 cmd.append(get_user_repository_root());
4847
4848 if (comments.empty() || std::all_of(comments.begin(), comments.end(), [](char c) { return std::isspace(c); }))
4849 throw RepositoryOperationFailed("commit", "the commit message may not be empty");
4850
4851 const std::string log_file_name(get_temporary_dir() + '/' + "oks-commit-msg." + std::to_string(getpid()) + ':' +
4852 std::to_string(reinterpret_cast<std::uintptr_t>(this)) + ".txt");
4853
4854 try {
4855 std::ofstream f(log_file_name);
4856
4857 f.exceptions(std::ostream::failbit | std::ostream::badbit);
4858
4859 if (!f)
4860 throw std::runtime_error("create message file failed");
4861
4862 f << comments;
4863 f.close();
4864 } catch (const std::exception& ex) {
4865 std::ostringstream ss;
4866 ss << "cannot write to file \'" << log_file_name << "\' to save commit message: " << ex.what();
4867 throw RepositoryOperationFailed("commit", ss.str());
4868 }
4869
4870 cmd.append(" -f \'");
4871 cmd.append(log_file_name);
4872 cmd.push_back('\'');
4873
4874 // if (!credentials.empty())
4875 // {
4876 // try
4877 // {
4878 // auto token = daq::tokens::verify(credentials);
4879
4880 // const std::string author = token.get_subject();
4881
4882 // std::string email;
4883
4884 // if (token.has_payload_claim("email"))
4885 // email = token.get_payload_claim("email").as_string();
4886
4887 // if (email.empty())
4888 // email = author + '@' + get_domain_name();
4889
4890 // OksSystem::User user(author);
4891
4892 // cmd.append(" -n \'");
4893 // cmd.append(user.real_name());
4894 // cmd.append("\' -e \'");
4895 // cmd.append(email);
4896 // cmd.push_back('\'');
4897
4898 // static std::once_flag flag;
4899
4900 // std::call_once(flag, []()
4901 // {
4902 // const char * opt = " -o SendEnv=OKS_COMMIT_USER";
4903
4904 // std::string val;
4905
4906 // if (const char * s = getenv("GIT_SSH_COMMAND"))
4907 // {
4908 // if (strstr(s, opt) == nullptr)
4909 // val = s;
4910 // }
4911 // else
4912 // {
4913 // val = "ssh";
4914 // }
4915
4916 // if (!val.empty())
4917 // {
4918 // val.append(opt);
4919 // setenv("GIT_SSH_COMMAND", val.c_str(), 1);
4920 // }
4921 // }
4922 // );
4923
4924 // setenv("OKS_COMMIT_USER", credentials.c_str(), 1);
4925 // }
4926 // catch(const ers::Issue& ex)
4927 // {
4928 // std::ostringstream text;
4929 // text << '\t' << ex;
4930 // throw RepositoryOperationFailed("commit", text.str());
4931 // }
4932 // }
4933
4934 auto start_usage = std::chrono::steady_clock::now();
4935
4936 if (!p_silence) {
4937 std::lock_guard lock(p_parallel_out_mutex);
4938 log_timestamp() << "[OKS commit] => " << cmd << std::endl;
4939 }
4940
4941 CommandOutput cmd_out("oks-commit", this, cmd);
4942
4943 int status = system(cmd.c_str());
4944
4945 unlink(log_file_name.c_str());
4946
4947 if (!credentials.empty())
4948 unsetenv("OKS_COMMIT_USER");
4949
4950 cmd_out.check_command_status(status);
4951
4952 p_repository_update_ts = std::time(0);
4953
4954 if (!p_silence) {
4955 std::lock_guard lock(p_parallel_out_mutex);
4956 std::cout << cmd_out.cat2str();
4958 << "[OKS commit] => done in "
4959 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4960 1000.
4961 << " ms" << std::endl;
4962 }
4963
4964 static std::string version_prefix("commit oks version ");
4965 std::string version = cmd_out.last_str();
4966 std::string::size_type pos = version.find(version_prefix);
4967
4968 if (pos == 0)
4969 p_repository_version = version.substr(version_prefix.size());
4970 else
4971 throw RepositoryOperationFailed("commit", "cannot read oks version");
4972}
bool get_verbose_mode() const
Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.
Definition kernel.hpp:700
RepositoryOperationFailed(const char *op, const exception &reason) noexcept
Definition kernel.hpp:120
std::ostream & log_timestamp(__LogSeverity__ severity=Log)
Definition kernel.cpp:5470

◆ create_file_info()

OksFile * dunedaq::oks::OksKernel::create_file_info ( const std::string & short_file_name,
const std::string & file_name )

Creates OKS file descriptor.

Method returns pointer to the OKS file descriptor defined by the file_name parameter or 0 if such file does not exist. The user is responsible to destroy the descriptor after usage.

Parameters
short_file_nameshort name of the file (e.g. relative to OKS root)
file_namean absolute file name

The method is thread-safe.

Definition at line 1428 of file kernel.cpp.

1429{
1430 OksFile* file_h = 0;
1431
1432 {
1433 std::shared_ptr<std::ifstream> f(new std::ifstream(full_path.c_str()));
1434
1435 if (f->good()) {
1436 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1437 file_h = new OksFile(xmls, short_path, full_path, this);
1438 }
1439 }
1440
1441 // check file access permissions
1442
1443 if (file_h) {
1444 check_read_only(file_h);
1445 }
1446
1447 return file_h;
1448}
static bool check_read_only(OksFile *f)
Check if the OKS file is read-only.
Definition kernel.cpp:1394
OksXmlInputStream(std::shared_ptr< std::istream > p)
Definition xml.hpp:343

◆ create_list_of_data_objects()

std::list< OksObject * > * dunedaq::oks::OksKernel::create_list_of_data_objects ( OksFile * fp) const

Creates list of objects which belong to given file.

Method returns pointer to the list of OKS objects or 0 if the file contains no objects. The user is responsible to destroy the list after usage.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 4106 of file kernel.cpp.

4107{
4108 const char _fname[] = "create_list_of_data_objects";
4109 std::string fname = make_fname(_fname, sizeof(_fname) - 1, fp->get_full_file_name(), nullptr, nullptr);
4110
4112 OSK_VERBOSE_REPORT("ENTER " << fname)
4113
4114 std::list<OksObject*>* olist = new std::list<OksObject*>();
4115
4116 if (!p_objects.empty()) {
4117 for (OksObject::Set::const_iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4118 if ((*i)->file == fp)
4119 olist->push_back(*i);
4120 }
4121 }
4122
4123 if (olist->empty()) {
4124 delete olist;
4125 olist = 0;
4126 }
4127
4128 OSK_VERBOSE_REPORT("LEAVE " << fname)
4129
4130 return olist;
4131}
std::string make_fname(const char *f, size_t f_len, const std::string &file, bool *p, const OksFile *const *fh)
Definition kernel.cpp:468

◆ create_list_of_schema_classes()

std::list< OksClass * > * dunedaq::oks::OksKernel::create_list_of_schema_classes ( OksFile * pf) const

Creates list of classes which belong to given file.

Method returns pointer to the list of OKS classes or 0 if the file contains no classes. The user is responsible to destroy the list after usage.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2743 of file kernel.cpp.

2744{
2745 std::string fname("OksKernel::create_list_of_schema_classes(");
2746 fname.append(pf->get_full_file_name());
2747 fname.push_back('\'');
2748
2750 OSK_VERBOSE_REPORT("ENTER " << fname)
2751
2752 std::list<OksClass*>* clist = nullptr;
2753
2754 if (!p_classes.empty()) {
2755 for (OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2756 if (pf == i->second->p_file) {
2757 if (!clist && !(clist = new std::list<OksClass*>())) {
2758 return 0;
2759 }
2760
2761 clist->push_back(i->second);
2762 }
2763 }
2764 }
2765
2766 OSK_VERBOSE_REPORT("LEAVE " << fname)
2767
2768 return clist;
2769}

◆ create_lists_of_updated_data_files()

void dunedaq::oks::OksKernel::create_lists_of_updated_data_files ( std::list< OksFile * > ** updated,
std::list< OksFile * > ** removed ) const

Get modified data files.

The method returns all data files which were modified or removed by an external process. The method checks file system status of all OKS data files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified data files
removedpointer to the list of removed data files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 2809 of file kernel.cpp.

2810{
2811 std::shared_lock lock(p_kernel_mutex);
2812
2814}
static void create_updated_lists(const OksFile::Map &files, std::list< OksFile * > **ufs, std::list< OksFile * > **rfs, OksFile::FileStatus wu, OksFile::FileStatus wr)
Definition kernel.cpp:2774

◆ create_lists_of_updated_schema_files()

void dunedaq::oks::OksKernel::create_lists_of_updated_schema_files ( std::list< OksFile * > ** updated,
std::list< OksFile * > ** removed ) const

Get modified schema files.

The method returns all schema files which were modified or removed by an external process. The method checks file system status of all OKS schema files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified schema files
removedpointer to the list of removed schema files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 2801 of file kernel.cpp.

2802{
2803 std::shared_lock lock(p_kernel_mutex);
2804
2806}

◆ create_user_repository_dir()

std::string dunedaq::oks::OksKernel::create_user_repository_dir ( )
private

Definition at line 2061 of file kernel.cpp.

2062{
2063 if (const char* path = getenv("TDAQ_DB_USER_REPOSITORY_PATH"))
2064 return path;
2065
2066 // create user repository directory if necessary
2067 std::string user_repo;
2068
2069 if (const char* user_repo_base = getenv("TDAQ_DB_USER_REPOSITORY_ROOT"))
2070 user_repo = user_repo_base;
2071 else
2072 user_repo = get_temporary_dir();
2073
2074 user_repo.push_back('/');
2075 if (const char* user_repo_pattern = getenv("TDAQ_DB_USER_REPOSITORY_PATTERN"))
2076 user_repo.append(user_repo_pattern);
2077 else
2078 user_repo.append("oks.XXXXXX");
2079
2080 std::unique_ptr<char[]> dir_template(new char[user_repo.size() + 1]);
2081 strcpy(dir_template.get(), user_repo.c_str());
2082
2083 if (char* tmp_dirname = mkdtemp(dir_template.get())) {
2084 return tmp_dirname;
2085 }
2086
2087 throw CanNotCreateRepositoryDir("make_user_repository_dir", user_repo);
2088}
CanNotCreateRepositoryDir(const char *prefix, const std::string &name) noexcept
Definition kernel.hpp:197

◆ data_files()

const OksFile::Map & dunedaq::oks::OksKernel::data_files ( ) const
inline

Get all data files.

Get all data files which were created or loaded by the OKS kernel. The method is thread-safe.

Returns
Return map of the OKS data file descriptors (sorted by file names).

Definition at line 1472 of file kernel.hpp.

1472{ return p_data_files; }

◆ define()

void dunedaq::oks::OksKernel::define ( OksObject * o)
inlineprivate

Definition at line 2075 of file kernel.hpp.

2076 {
2077 std::lock_guard lock(p_objects_mutex);
2078 p_objects.insert(o);
2079 }
std::mutex p_objects_mutex
Definition kernel.hpp:1966

◆ find_class() [1/2]

OksClass * dunedaq::oks::OksKernel::find_class ( const char * class_name) const

Find class by name (C-string).

If the method is used in the multi-threaded environment, it could be necessary to set read kernel lock before calling the method, if other threads can to create or to destroy oks classes and to open or close oks schema files.

Parameters
class_namename of the class
Returns
Return pointer on OKS class or null pointer, if such class cannot be found.

Definition at line 4224 of file kernel.cpp.

4225{
4226 OksClass::Map::const_iterator i = p_classes.find(name);
4227 return (i != p_classes.end() ? i->second : 0);
4228}

◆ find_class() [2/2]

OksClass * dunedaq::oks::OksKernel::find_class ( const std::string & class_name) const
inline

Find class by name (C++ string).

If the method is used in the multi-threaded environment, it could be necessary to set read kernel lock before calling the method, if other threads can to create or to destroy oks classes and to open or close oks schema files.

Parameters
class_namename of the class (std::string)
Returns
Return pointer on OKS class or null pointer, if such class can not be found.

Definition at line 1754 of file kernel.hpp.

1754{ return find_class(class_name.c_str()); }
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Definition kernel.hpp:1754

◆ find_data_file()

OksFile * dunedaq::oks::OksKernel::find_data_file ( const std::string & s) const

Finds OKS data file.

Method returns pointer to the OKS data file with name s or 0, if there is no such data file found.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2119 of file kernel.cpp.

2120{
2121 return find_file(s, p_data_files);
2122}
OksFile * find_file(const std::string &s, const OksFile::Map &files) const
Definition kernel.cpp:2091

◆ find_file()

OksFile * dunedaq::oks::OksKernel::find_file ( const std::string & s,
const OksFile::Map & files ) const
private

Definition at line 2091 of file kernel.cpp.

2092{
2093 try {
2094 std::string at = get_file_path(s, nullptr);
2095 OksFile::Map::const_iterator i = files.find(&at);
2096 if (i != files.end())
2097 return (*i).second;
2098 } catch (...) {
2099 // return 0;
2100 }
2101
2102 // search files included as relative to parent
2103 for (const auto& f : files) {
2104 if (s == f.second->get_short_file_name()) {
2105 return f.second;
2106 }
2107 }
2108
2109 return nullptr;
2110}
std::string get_file_path(const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
Calculates full path to file.
Definition kernel.cpp:1516

◆ find_schema_file()

OksFile * dunedaq::oks::OksKernel::find_schema_file ( const std::string & s) const

Finds OKS schema file.

Method returns pointer to the OKS schema file with name s or 0, if there is no such schema file found.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2113 of file kernel.cpp.

2114{
2115 return find_file(s, p_schema_files);
2116}

◆ get_active_data()

OksFile * dunedaq::oks::OksKernel::get_active_data ( ) const
inline

Get active OKS data file.

The method is thread-safe.

Returns
Return pointer to the active OKS data file descriptor or 0 if there is no an active data file.

Definition at line 1461 of file kernel.hpp.

1461{ return p_active_data; }

◆ get_active_schema()

OksFile * dunedaq::oks::OksKernel::get_active_schema ( ) const
inline

Get active OKS schema file.

The method returns active schema file.

Returns
Return pointer to the active OKS schema file descriptor or 0 if there is no an active schema.

The method is thread-safe.

Definition at line 1199 of file kernel.hpp.

1199{ return p_active_schema; }

◆ get_all_classes()

void dunedaq::oks::OksKernel::get_all_classes ( const std::vector< std::string > & names_in,
ClassSet & classes_out ) const

The method searches all classes including subclasses for given names.

Parameters
names_inarray of names of the classes to search in
classes_outthe output containing pointers to all classes by above names and their subclasses

Definition at line 4451 of file kernel.cpp.

4452{
4453 for (std::vector<std::string>::const_iterator i = names_in.begin(); i != names_in.end(); ++i) {
4454 OksClass* c = find_class(*i);
4455 if (c != 0 && classes_out.find(c) == classes_out.end()) {
4456 classes_out.insert(c);
4457 if (const OksClass::FList* sc = c->all_sub_classes()) {
4458 for (OksClass::FList::const_iterator j = sc->begin(); j != sc->end(); ++j) {
4459 classes_out.insert(*j);
4460 }
4461 }
4462 }
4463 }
4464}

◆ get_allow_duplicated_classes_mode()

bool dunedaq::oks::OksKernel::get_allow_duplicated_classes_mode ( ) const
inline

Get status of duplicated classes mode. The method returns true, if the duplicated classes mode is switched 'On'. In such case the OKS will allow to load classes with equal names. Only first loaded class is taken into account, the next ones are ignored.

Definition at line 759 of file kernel.hpp.

◆ get_allow_duplicated_objects_mode()

bool dunedaq::oks::OksKernel::get_allow_duplicated_objects_mode ( ) const
inline

Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is switched 'On'. In such case the OKS will allow to load objects of the same class with equal IDs. The ID for duplicated object will be generated automatically.

Definition at line 768 of file kernel.hpp.

◆ get_bind_classes_status()

const std::string & dunedaq::oks::OksKernel::get_bind_classes_status ( ) const
inlinenoexcept

Return status of oks classes binding.

The method checks lack of dangling references on class types and returns string containing unbound references if any.

Returns
If all classes were successfully linked, the string is empty. Otherwise it contains description of unbound references and classes.

Definition at line 1934 of file kernel.hpp.

1934{ return p_bind_classes_status; }
std::string p_bind_classes_status
Definition kernel.hpp:1998

◆ get_bind_objects_status()

const std::string & dunedaq::oks::OksKernel::get_bind_objects_status ( ) const
inlinenoexcept

Return status of oks objects binding.

The method returns string containing unbound references after last bind_objects() call.

Returns
If all objects were successfully linked, the string is empty. Otherwise it contains description of unbound references and objects.

Definition at line 1922 of file kernel.hpp.

1922{ return p_bind_objects_status; }
std::string p_bind_objects_status
Definition kernel.hpp:1997

◆ get_cwd()

const char * dunedaq::oks::OksKernel::get_cwd ( )
static
Returns
current working dir

Definition at line 636 of file kernel.cpp.

637{
638 std::lock_guard scoped_lock(s_get_cwd_mutex);
639
640 if (!s_cwd) {
641 errno = 0;
642 long size = pathconf(".", _PC_PATH_MAX);
643 if (errno) {
644 Oks::error_msg("OksKernel::OksKernel") << "pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno << ": \'"
645 << strerror(errno) << '\'' << std::endl;
646 } else {
647 if (size == -1) {
648 size = PATH_MAX;
649 }
650 s_cwd = new char[size];
651 if (!getcwd(s_cwd, (size_t)size)) {
652 Oks::error_msg("OksKernel::OksKernel")
653 << "getcwd() has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
654 delete[] s_cwd;
655 s_cwd = 0;
656 }
657 }
658
659 if (!s_cwd) {
660 s_cwd = new char[2];
661 s_cwd[0] = '/';
662 s_cwd[1] = 0;
663 }
664
665 TLOG_DEBUG(1) << "Current working dir: \'" << s_cwd << '\'';
666 }
667
668 return s_cwd;
669}
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size

◆ get_domain_name()

std::string & dunedaq::oks::OksKernel::get_domain_name ( )
static

Get domain name of host.

Definition at line 408 of file kernel.cpp.

409{
410 static std::string s_domain_name;
411 static std::once_flag flag;
412
413 std::call_once(flag, []() {
414 std::string::size_type idx = get_host_name().find('.');
415
416 if (idx != std::string::npos)
417 s_domain_name = get_host_name().substr(idx + 1);
418
419 if (s_domain_name.empty())
420 s_domain_name = "unknown.domain";
421 });
422
423 return s_domain_name;
424}

◆ get_file_path()

std::string dunedaq::oks::OksKernel::get_file_path ( const std::string & path,
const OksFile * parent_file = 0,
bool strict_paths = true ) const

Calculates full path to file.

Method calculates full path to file. It takes into account the values of the OKS_DB_ROOT, TDAQ_DB_REPOSITORY, TDAQ_DB_USER_REPOSITORY and TDAQ_DB_PATH environment variables and optionally checks if the path is relative to the parent file defined by the parent_file parameter.

The method is thread-safe.

Parameters
pathshort, relative or absolute path to file
parent_filepointer to file including given one
Exceptions
Throwstd::exception in case of problems.

Definition at line 1516 of file kernel.cpp.

1517{
1518 strict_paths &= p_use_strict_repository_paths;
1519
1520 const char _fname[] = "get_file_path";
1521 std::string fname;
1522
1523 TLOG_DEBUG(2) << "ENTER " << make_fname(_fname, sizeof(_fname) - 1, s, nullptr, &file_h);
1524
1525 std::list<std::string> tested_files;
1526
1527 // check absolute path or path relative to working directory
1528 bool is_absolute_path = false;
1529
1530 std::string s2(s);
1532 fname = make_fname(_fname, sizeof(_fname) - 1, s2, nullptr, &file_h);
1533
1534 // test if file has an absolute path
1535 if (s2[0] == '/')
1536 is_absolute_path = true;
1537
1538 // continue only if the file is an absolute path or it is not included
1539 if (is_absolute_path || file_h == 0) {
1540 if (!is_absolute_path && s_cwd && *s_cwd) {
1541 std::string s3 = s_cwd;
1542 s3.push_back('/');
1543 s2 = s3 + s2;
1544 }
1545
1546 if (Oks::real_path(s2, true)) {
1547 if (!get_user_repository_root().empty() && strict_paths) {
1548 if (!get_repository_mapping_dir().empty() && s2.find(get_repository_mapping_dir()) == 0) {
1549 s2.erase(0, get_repository_mapping_dir().size() + 1);
1551 } else if (s2.find(get_user_repository_root()) == 0) {
1552 // presumably from explicitly set TDAQ_DB_USER_REPOSITORY created externally
1553 TLOG_DEBUG(2) << fname << " returns external \'" << s2 << "\' (an absolute filename or relative to CWD=\'"
1554 << s_cwd << "\')";
1555 return s2;
1556 }
1557
1558 std::ostringstream text;
1559 text << fname
1560 << " file does not belong to oks git repository\n"
1561 "provide file repository name, or unset TDAQ_DB_REPOSITORY and try again with the DUNEDAQ_DB_PATH "
1562 "environment variable";
1563 throw std::runtime_error(text.str().c_str());
1564 } else {
1565 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (an absolute filename or relative to CWD=\'" << s_cwd
1566 << "\')";
1567 return s2;
1568 }
1569 } else {
1570 if (is_absolute_path) {
1571 const char _test_name[] = "an absolute file name";
1572 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1573 } else {
1574 const char _test_name[] = "relative to current working directory";
1575 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1576 }
1577 }
1578 }
1579
1580 if (!get_user_repository_root().empty()) {
1582 }
1583
1585 // check paths relative to OKS database root directories
1586 if (!is_absolute_path)
1587 for (auto& i : p_repository_dirs) {
1588 TEST_PATH_TOKEN(i, s, "DUNEDAQ_DB_PATH")
1589 }
1590
1591 // check non-absolute path relative to parent file if any
1592 if (file_h && !is_absolute_path) {
1593 std::string s2(file_h->get_full_file_name());
1594 std::string::size_type pos = s2.find_last_of('/');
1595
1596 if (pos != std::string::npos) {
1597 s2.erase(pos + 1);
1598 s2.append(s);
1600
1601 if (Oks::real_path(s2, true)) {
1602 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (filename relative to parent file)";
1603 return s2;
1604 } else {
1605 const char _test_name[] = "relative to parent file";
1606 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1607 }
1608 }
1609 }
1610 }
1611
1612 TLOG_DEBUG(2) << fname << " throw exception (file was not found)";
1613
1614 std::ostringstream text;
1615 text << fname << " found no readable file among " << tested_files.size() << " tested:\n";
1616 for (auto& i : tested_files)
1617 text << i << std::endl;
1618
1619 throw std::runtime_error(text.str().c_str());
1620}
static const std::string & get_repository_mapping_dir()
Get OKS repository name.
Definition kernel.cpp:318
static void substitute_variables(std::string &)
Definition kernel.cpp:525
#define TEST_PATH_TOKEN(path, file, msg)
Definition kernel.cpp:1501
std::string mk_name_and_test(const std::string &name, const char *test, size_t test_len)
Definition kernel.cpp:1492

◆ get_host_name()

std::string & dunedaq::oks::OksKernel::get_host_name ( )
static

Get hostname of given process.

Definition at line 392 of file kernel.cpp.

393{
394 static std::string s_host_name;
395 static std::once_flag flag;
396
397 std::call_once(flag, []() {
399
400 if (s_host_name.empty())
401 s_host_name = "unknown.host";
402 });
403
404 return s_host_name;
405}
static const std::string & full_local_name()
fully qualified local host name
Definition Host.cpp:243
static const LocalHost * instance()
pointer to the singleton local host
Definition Host.cpp:255

◆ get_includes()

void dunedaq::oks::OksKernel::get_includes ( const std::string & file_name,
std::set< std::string > & includes,
bool use_repository_name = false )

Opens file and reads its shallow includes.

The method is thread-safe.

Exceptions
Throwstd::exception in case of problems.

Definition at line 1752 of file kernel.cpp.

1753{
1754 try {
1755 std::shared_ptr<std::ifstream> f(new std::ifstream(file_name.c_str()));
1756
1757 if (!f->good()) {
1758 throw std::runtime_error("get_includes(): cannot open file");
1759 }
1760
1761 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1762 OksFile fp(xmls, file_name, file_name, this);
1763
1764 if (fp.p_list_of_include_files.size()) {
1765 for (std::list<std::string>::iterator i = fp.p_list_of_include_files.begin();
1766 i != fp.p_list_of_include_files.end();
1767 ++i) {
1768 includes.insert(use_repository_name ? get_file_path(*i, &fp).substr(get_user_repository_root().size() + 1)
1769 : get_file_path(*i, &fp));
1770 }
1771 }
1772
1773 f->close();
1774 } catch (exception& e) {
1775 throw(FailedLoadFile("file", file_name, e));
1776 } catch (std::exception& e) {
1777 throw(FailedLoadFile("file", file_name, e.what()));
1778 }
1779}
FailedLoadFile(const std::string &item, const std::string &name, const exception &reason) noexcept
Definition kernel.hpp:64

◆ get_modified_files()

void dunedaq::oks::OksKernel::get_modified_files ( std::set< OksFile * > & mfs,
std::set< OksFile * > & rfs,
const std::string & version )

Get modified data files.

The method returns the data files modified or removed by an external process in file system or repository.

The method return parameters are:

Parameters
mfsset of modified data files
rfsset of removed data files
versionrepository version to compare with (if needed)

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 2817 of file kernel.cpp.

2818{
2819 std::list<OksFile*>* files[] = { nullptr, nullptr, nullptr, nullptr };
2820
2821 std::set<OksFile*>* sets[] = { &mfs, &rfs };
2822
2823 create_lists_of_updated_data_files(&files[0], &files[1]);
2824 create_lists_of_updated_schema_files(&files[2], &files[3]);
2825
2826 for (int i = 0; i < 4; ++i)
2827 if (std::list<OksFile*>* f = files[i]) {
2828 while (!f->empty()) {
2829 sets[i % 2]->insert(f->front());
2830 f->pop_front();
2831 }
2832 delete f;
2833 }
2834
2835 if (!get_user_repository_root().empty() && !version.empty())
2836 for (const auto& file_name : get_repository_versions_diff(get_repository_version(), version)) {
2837 if (OksFile* f = find_data_file(file_name))
2838 sets[0]->insert(f);
2839 else if (OksFile* f = find_schema_file(file_name))
2840 sets[0]->insert(f);
2841 }
2842}
std::list< std::string > get_repository_versions_diff(const std::string &sha1, const std::string &sha2)
Definition kernel.cpp:5026
void create_lists_of_updated_data_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified data files.
Definition kernel.cpp:2809
OksFile * find_data_file(const std::string &s) const
Finds OKS data file.
Definition kernel.cpp:2119
void create_lists_of_updated_schema_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified schema files.
Definition kernel.cpp:2801
OksFile * find_schema_file(const std::string &s) const
Finds OKS schema file.
Definition kernel.cpp:2113
const std::string & get_repository_version()
Definition kernel.hpp:950

◆ get_mutex()

std::shared_mutex & dunedaq::oks::OksKernel::get_mutex ( )
inline

Return OKS kernel mutex.

The mutex is used to lock most OKS kernel update operations like loading of files. It is used by the RDB server performing OKS operations in multi-threaded environment.

Definition at line 843 of file kernel.hpp.

843{ return p_kernel_mutex; }

◆ get_profiling_mode()

bool dunedaq::oks::OksKernel::get_profiling_mode ( ) const
inline

Get status of profiling mode. The method returns true, if the profiling mode is switched 'On'. In such case the OKS will report time spend to execute main methods and a summary table of their calls on the OKS kernel destroy.

Definition at line 739 of file kernel.hpp.

739{ return p_profiling; }

◆ get_repository_checkout_ts()

std::time_t dunedaq::oks::OksKernel::get_repository_checkout_ts ( ) const
inline

Return repository checkout timestamp.

Return timestamp when the repository was checkout or updated last time (e.g. to track new changes).

Definition at line 1553 of file kernel.hpp.

1553{ return p_repository_checkout_ts; }

◆ get_repository_dirs()

const std::list< std::string > & dunedaq::oks::OksKernel::get_repository_dirs ( ) const
inline

Get repository search directories.

The method is not thread-safe.

Returns
The method returns list of repository search directories.

Definition at line 1520 of file kernel.hpp.

1520{ return p_repository_dirs; }

◆ get_repository_mapping_dir()

const std::string & dunedaq::oks::OksKernel::get_repository_mapping_dir ( )
static

Get OKS repository name.

The repository name is defined by last directory of the TDAQ_DB_REPOSITORY environment variable, e.g.: for the name of oks-repository-root="/usr/local/databases/v10" is "v10". The method returns an empty string, if the oks-repository-root is not set or its value contains no name.

Definition at line 318 of file kernel.cpp.

319{
320 static std::once_flag flag;
321
322 std::call_once(flag, []() {
323 if (const char* s = getenv("OKS_REPOSITORY_MAPPING_DIR")) {
326 }
327 });
328
330}
static std::string p_repository_mapping_dir
Definition kernel.hpp:1955

◆ get_repository_root()

const std::string & dunedaq::oks::OksKernel::get_repository_root ( )
static

Get OKS repository root.

The repository root is defined by the TDAQ_DB_REPOSITORY environment variable. The method returns an empty string, if the variable is not set or its value is empty.

Definition at line 280 of file kernel.cpp.

281{
282 static std::once_flag flag;
283
284 std::call_once(flag, []() {
285 if (const char* s = getenv("TDAQ_DB_REPOSITORY")) {
286 std::string rep(s);
287
288 if (!std::all_of(rep.begin(), rep.end(), [](char c) { return std::isspace(c); })) {
289 const char* p = getenv("OKS_GIT_PROTOCOL");
290
291 if (p && !*p)
292 p = nullptr;
293
294 Oks::Tokenizer t(rep, "|");
295 std::string token;
296
297 while (t.next(token) && p_repository_root.empty()) {
298 if (p) {
299 if (token.find(p) == 0) {
300 p_repository_root = token;
301 }
302 } else {
303 p_repository_root = token;
304 }
305 }
306
307 if (p_repository_root.empty())
308 Oks::error_msg("OksKernel::OksKernel")
309 << "cannot find OKS_GIT_PROTOCOL=\"" << p << "\" in TDAQ_DB_REPOSITORY=\"" << rep << '\"' << std::endl;
310 }
311 }
312 });
313
314 return p_repository_root;
315}
static std::string p_repository_root
Definition kernel.hpp:1954

◆ get_repository_unmerged_files()

std::list< std::string > dunedaq::oks::OksKernel::get_repository_unmerged_files ( )
inline

Special behavior of get_repository_versions_diff(), return unmerged files

Definition at line 1605 of file kernel.hpp.

1605{ return get_repository_versions_diff("", ""); }

◆ get_repository_version()

const std::string & dunedaq::oks::OksKernel::get_repository_version ( )
inline

Definition at line 950 of file kernel.hpp.

950{ return p_repository_version; }

◆ get_repository_versions()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions ( bool skip_irrelevant,
const std::string & command_line )

Return repository versions.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
command_lineforward command line parameter to the oks-git-log.sh
Exceptions
Throwoks::exception in case of problems.

Definition at line 5103 of file kernel.cpp.

5104{
5105 std::string cmd("oks-log.sh");
5106
5107 if (get_verbose_mode())
5108 cmd.append(" -v");
5109
5110 cmd.append(" -u ");
5111 cmd.append(get_user_repository_root());
5112
5113 cmd.append(command_line);
5114
5115 CommandOutput cmd_out("oks-log", this, cmd);
5116 cmd_out.check_command_status(system(cmd.c_str()));
5117
5118 std::string output = cmd_out.cat2str();
5119
5120 std::istringstream s(output);
5121
5122 std::string line;
5123 bool found = false;
5124
5125 while (std::getline(s, line))
5126 if (line.find("git log ") == 0) {
5127 found = true;
5128 break;
5129 }
5130
5131 if (found == false) {
5132 std::ostringstream text;
5133 text << "cannot find \"git log\" pattern in output of oks-log.sh:\n" << output;
5134 throw RepositoryOperationFailed("log", text.str());
5135 }
5136
5137 std::set<std::string> loaded_files;
5138
5139 if (skip_irrelevant) {
5140 std::size_t len = get_user_repository_root().size() + 1;
5141
5142 for (const auto& x : p_schema_files)
5143 loaded_files.emplace(x.first->substr(len));
5144
5145 for (const auto& x : p_data_files)
5146 loaded_files.emplace(x.first->substr(len));
5147 }
5148
5149 std::vector<OksRepositoryVersion> vec;
5150 OksRepositoryVersion ver;
5151
5152 found = false;
5153
5154 while (std::getline(s, line)) {
5155 if (found == false) {
5156 ver.clear();
5157
5158 std::string::size_type idx1 = 0;
5159 std::string::size_type idx2 = line.find('|');
5160
5161 if (idx2 != std::string::npos) {
5162 ver.m_commit_hash = line.substr(idx1, idx2);
5163 idx1 = idx2 + 1;
5164 idx2 = line.find('|', idx1);
5165
5166 if (idx2 != std::string::npos) {
5167 ver.m_user = line.substr(idx1, idx2 - idx1);
5168 idx1 = idx2 + 1;
5169 idx2 = line.find('|', idx1);
5170
5171 if (idx2 != std::string::npos) {
5172 ver.m_date = std::stol(line.substr(idx1, idx2 - idx1));
5173 ver.m_comment = line.substr(idx2 + 1);
5174 }
5175 }
5176 }
5177
5178 if (!ver.m_comment.empty())
5179 found = true;
5180 else {
5181 std::ostringstream text;
5182 text << "unexpected line \"" << line << "\" in output of oks-log.sh:\n" << output;
5183 throw RepositoryOperationFailed("log", text.str());
5184 }
5185 } else {
5186 if (line.empty()) {
5187 found = false;
5188
5189 if (skip_irrelevant && check_relevant(loaded_files, ver) == false)
5190 continue;
5191
5192 vec.emplace_back(ver);
5193 } else {
5194 ver.m_files.push_back(line);
5195 }
5196 }
5197 }
5198
5199 if (found) {
5200 if (skip_irrelevant == false || check_relevant(loaded_files, ver))
5201 vec.emplace_back(ver);
5202 }
5203
5204 return vec;
5205}
static bool check_relevant(const std::set< std::string > &loaded_files, const OksRepositoryVersion &ver)
Definition kernel.cpp:5093

◆ get_repository_versions_by_date()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions_by_date ( bool skip_irrelevant = true,
const std::string & since = "",
const std::string & until = "" )

Return repository versions between timestamps.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
sincelimit the versions committed on-or-after the specified date/time
untillimit the versions committed on-or-before the specified date/time
Exceptions
Throwoks::exception in case of problems.

Definition at line 5238 of file kernel.cpp.

5239{
5240 std::string command_line;
5241
5242 if (!since.empty()) {
5243 command_line.append(" --since ");
5244 command_line.append(replace_datetime_spaces(since));
5245 }
5246
5247 if (!until.empty()) {
5248 command_line.append(" --until ");
5249 command_line.append(replace_datetime_spaces(until));
5250 }
5251
5252 command_line.append(" origin/master");
5253
5254 return get_repository_versions(skip_irrelevant, command_line);
5255}
std::vector< OksRepositoryVersion > get_repository_versions(bool skip_irrelevant, const std::string &command_line)
Return repository versions.
Definition kernel.cpp:5103
static std::string replace_datetime_spaces(const std::string &in)
Definition kernel.cpp:5230

◆ get_repository_versions_by_hash()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions_by_hash ( bool skip_irrelevant = true,
const std::string & sha1 = "",
const std::string & sha2 = "" )

Return repository versions between hash keys.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
sha1limit the versions committed on-or-after the specified hash key; if empty, start from earliest available
sha2limit the versions committed on-or-before the specified hash key; if empty, retrieve all versions until "origin/master"
Exceptions
Throwoks::exception in case of problems.

Definition at line 5208 of file kernel.cpp.

5209{
5210 std::string command_line;
5211
5212 if (!since.empty() && !until.empty()) {
5213 command_line.push_back(' ');
5214 command_line.append(since);
5215 command_line.append("..");
5216 command_line.append(until);
5217 } else if (!since.empty()) {
5218 command_line.push_back(' ');
5219 command_line.append(since);
5220 command_line.append("..origin/master");
5221 } else if (!until.empty()) {
5222 command_line.append(" ..");
5223 command_line.append(until);
5224 }
5225
5226 return get_repository_versions(skip_irrelevant, command_line);
5227}

◆ get_repository_versions_diff()

std::list< std::string > dunedaq::oks::OksKernel::get_repository_versions_diff ( const std::string & sha1,
const std::string & sha2 )

Return names of files updated between revisions.

Exceptions
Throwoks::exception in case of problems.

Definition at line 5026 of file kernel.cpp.

5027{
5028 std::unique_lock lock(p_kernel_mutex);
5029
5030 if (OksKernel::get_repository_root().empty())
5031 throw RepositoryOperationFailed("diff",
5032 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5033
5034 if (get_user_repository_root().empty())
5036 "diff", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5037
5038 std::string cmd("oks-diff.sh");
5039
5040 if (get_verbose_mode())
5041 cmd.append(" -v");
5042
5043 cmd.append(" -u ");
5044 cmd.append(get_user_repository_root());
5045
5046 if (!sha1.empty() && !sha2.empty()) {
5047 cmd.append(" --sha ");
5048 cmd.append(sha1);
5049 cmd.push_back(' ');
5050 cmd.append(sha2);
5051 } else {
5052 cmd.append(" --unmerged");
5053 }
5054
5055 CommandOutput cmd_out("oks-diff", this, cmd);
5056 cmd_out.check_command_status(system(cmd.c_str()));
5057
5058 std::string output = cmd_out.cat2str();
5059
5060 if (!p_silence) {
5061 std::lock_guard lock(p_parallel_out_mutex);
5062 std::cout << output << "[OKS get_diff] => done" << std::endl;
5063 }
5064
5065 std::istringstream s(output);
5066
5067 std::string line;
5068 bool found = false;
5069
5070 const char* diff_pattern = "git diff --name-only ";
5071
5072 while (std::getline(s, line))
5073 if (line.find(diff_pattern) == 0) {
5074 found = true;
5075 break;
5076 }
5077
5078 if (found == false) {
5079 std::ostringstream text;
5080 text << "cannot find \"" << diff_pattern << "\" pattern in output of oks-diff.sh:\n" << output;
5081 throw RepositoryOperationFailed("get_diff", text.str());
5082 }
5083
5084 std::list<std::string> result;
5085
5086 while (std::getline(s, line))
5087 result.push_back(line);
5088
5089 return result;
5090}

◆ get_silence_mode()

bool dunedaq::oks::OksKernel::get_silence_mode ( ) const
inline

Get status of silence mode. The method returns true, if the silence mode is switched 'On'. In such case the OKS will not print any info, warnings and error messages.

Definition at line 719 of file kernel.hpp.

719{ return p_silence; }

◆ get_skip_string_range()

bool dunedaq::oks::OksKernel::get_skip_string_range ( )
inlinestatic

Get status of string range validator.

The method returns true, if the check is switched 'Off'. If the check is switched 'On', OKS will validate string value using regexp regular expression, if it is defined for related attribute.

Definition at line 822 of file kernel.hpp.

822{ return p_skip_string_range; }

◆ get_test_duplicated_objects_via_inheritance_mode()

bool dunedaq::oks::OksKernel::get_test_duplicated_objects_via_inheritance_mode ( ) const
inline

Get status of test inherited duplicated objects mode. The method returns true, if the mode is switched 'On'. In such case the OKS will throw exception when there are objects with equal IDs within class inheritance hierarchy.

Definition at line 791 of file kernel.hpp.

◆ get_tmp_file()

std::string dunedaq::oks::OksKernel::get_tmp_file ( const std::string & file_name)
static

Generates temporal file name.

Method generates temporal file name by adding numeric suffix to the file_name and testing the file existence.

Returns
Return name of temporal file.

The method is not thread-safe.

Definition at line 611 of file kernel.cpp.

612{
613 unsigned int j = 0;
614 std::string s2;
615 std::ostringstream s;
616
617 while (j++ < 1000000) {
618 s.str("");
619 s << file << '.' << get_user_name() << ':' << get_host_name() << ':' << getpid() << ':' << j;
620
621 s2 = s.str();
622
623 std::ofstream f(s2.c_str(), std::ios::in);
624
625 if (!f)
626 return s2;
627 }
628
629 std::string s3(file);
630 s3 += ".tmp";
631
632 return s3;
633}

◆ get_updated_repository_files()

void dunedaq::oks::OksKernel::get_updated_repository_files ( std::set< std::string > & updated,
std::set< std::string > & added,
std::set< std::string > & removed )

Get repository modified schema files.

The method returns those schema files which corresponding repository files were modified or removed by an external process. The method checks file system status of all OKS schema files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified schema files
removedpointer to the list of removed schema files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 5296 of file kernel.cpp.

5299{
5300 std::unique_lock lock(p_kernel_mutex);
5301
5302 if (OksKernel::get_repository_root().empty())
5303 throw RepositoryOperationFailed("status",
5304 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5305
5306 if (get_user_repository_root().empty())
5308 "status", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5309
5310 std::string cmd("oks-status.sh");
5311
5312 cmd.append(" -u ");
5313 cmd.append(get_user_repository_root());
5314
5315 CommandOutput cmd_out("oks-status", this, cmd);
5316 cmd_out.check_command_status(system(cmd.c_str()));
5317
5318 std::string output = cmd_out.cat2str();
5319
5320 if (p_verbose) {
5321 std::lock_guard lock(p_parallel_out_mutex);
5322 std::cout << output << "[OKS get_status] => done" << std::endl;
5323 }
5324
5325 std::istringstream s(output);
5326
5327 std::string line;
5328 bool found = false;
5329
5330 const char* diff_pattern = "git status --porcelain";
5331
5332 while (std::getline(s, line))
5333 if (line.find(diff_pattern) == 0) {
5334 found = true;
5335 break;
5336 }
5337
5338 if (found == false) {
5339 std::ostringstream text;
5340 text << "cannot find \"" << diff_pattern << "\" pattern in output of oks-status.sh:\n" << output;
5341 throw RepositoryOperationFailed("status", text.str());
5342 }
5343
5344 std::list<std::string> result;
5345
5346 while (std::getline(s, line)) {
5347 if (line.find(" D ") == 0)
5348 removed.insert(line.substr(3));
5349 else if (line.find(" M ") == 0)
5350 updated.insert(line.substr(3));
5351 else if (line.find("?? ") == 0)
5352 added.insert(line.substr(3));
5353 else {
5354 std::ostringstream text;
5355 text << "unexpected output \"" << line << "\" in output of oks-status.sh:\n" << output;
5356 throw RepositoryOperationFailed("status", text.str());
5357 }
5358 }
5359}

◆ get_user_name()

std::string & dunedaq::oks::OksKernel::get_user_name ( )
static

Get username of given process.

Definition at line 427 of file kernel.cpp.

428{
429 static std::string s_user_name;
430 static std::once_flag flag;
431
432 std::call_once(flag, []() {
433 OksSystem::User myself;
434 s_user_name = myself.name_safe();
435
436 if (s_user_name.empty())
437 s_user_name = "unknown.user";
438 });
439
440 return s_user_name;
441}
const std::string & name_safe() const
username - no exception
Definition User.cpp:228

◆ get_user_repository_root()

const std::string & dunedaq::oks::OksKernel::get_user_repository_root ( ) const

Get user OKS repository root.

The user repository root is defined by the TDAQ_DB_USER_REPOSITORY environment variable. The method returns an empty string, if the variable is not set or its value is empty.

Definition at line 335 of file kernel.cpp.

336{
337 if (p_allow_repository) {
338 OksKernel* k(const_cast<OksKernel*>(this));
340 if (const char* s = getenv("TDAQ_DB_USER_REPOSITORY")) {
341 if (s[0] != 0) {
342 k->set_user_repository_root(s);
343 }
344 }
345 k->p_user_repository_root_inited = true;
346 }
347 }
348
350}
OksKernel(bool silence_mode=false, bool verbose_mode=false, bool profiling_mode=false, bool allow_repository=true, const char *version=nullptr, std::string branch_name="")
Constructor to build OksKernel object.
Definition kernel.cpp:675

◆ get_verbose_mode()

bool dunedaq::oks::OksKernel::get_verbose_mode ( ) const
inline

Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.

Definition at line 700 of file kernel.hpp.

700{ return p_verbose; }

◆ GetOksProfiler()

OksProfiler * dunedaq::oks::OksKernel::GetOksProfiler ( ) const
inline

Definition at line 655 of file kernel.hpp.

655{ return profiler; }

◆ GetVersion()

const char * dunedaq::oks::OksKernel::GetVersion ( )
static

Get OKS version. The method returns string containing CVS tag and date of OKS build.

Definition at line 274 of file kernel.cpp.

275{
276 return "862f2957270";
277}

◆ insert_repository_dir()

std::string dunedaq::oks::OksKernel::insert_repository_dir ( const std::string & dir,
bool push_back = true )

Insert repository search directory.

The method trues to insert new repository search directory. If no such directory exists, then the method inserts new directory and returns its fully qualified name. Otherwise method does nothing and return empty string.

The method is not thread-safe.

Parameters
dirdirectory name
push_backif true, push new directory back; otherwise push directory front

Definition at line 1264 of file kernel.cpp.

1265{
1266 std::unique_lock lock(p_kernel_mutex);
1267
1268 std::string s(dir);
1270
1271 try {
1272 Oks::real_path(s, false);
1273
1274 if (std::find(p_repository_dirs.begin(), p_repository_dirs.end(), s) == p_repository_dirs.end()) {
1275 if (push_back)
1276 p_repository_dirs.push_back(s);
1277 else
1278 p_repository_dirs.push_front(s);
1279 if (p_verbose) {
1280 std::cout << " * push " << (push_back ? "back" : "front") << " repository search directory \'" << s << "\'\n";
1281 }
1282 return s;
1283 }
1284 } catch (exception& ex) {
1285 TLOG_DEBUG(1) << "Cannot insert repository dir \'" << dir << "\':\n\tcaused by: " << ex;
1286 }
1287
1288 return "";
1289}

◆ is_dangling() [1/2]

bool dunedaq::oks::OksKernel::is_dangling ( OksClass * class_ptr) const

Check pointer on oks class.

A pointer on class becomes dangling if such class was destroyed, or the schema file which contains it was closed. The method scans through all oks classes and checks if given pointer is valid, i.e. points to an oks class.

If the method is used in the multi-threaded environment, it may be necessary to set read kernel lock before calling the method, in case if another threads can to create or to destroy classes or to open or to close oks schema files.

Parameters
class_ptra pointer to the oks class to be tested
Returns
Return true if the pointer on class is not valid.

Definition at line 4415 of file kernel.cpp.

4416{
4418 OSK_VERBOSE_REPORT("Enter OksKernel::is_dangling(OksClass *)")
4419
4420 bool not_found = true;
4421
4422 {
4423 if (!p_classes.empty()) {
4424 for (OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
4425 if (i->second == c) {
4426 not_found = false;
4427 break;
4428 }
4429 }
4430 }
4431 }
4432
4433 if (p_verbose) {
4434 std::string fname("OksKernel::is_dangling(");
4435
4436 if (not_found)
4437 fname += "?class?) returns true";
4438 else {
4439 fname += '\"';
4440 fname += c->get_name();
4441 fname += "\") returns false";
4442 }
4443
4444 OSK_VERBOSE_REPORT("LEAVE " << fname.c_str())
4445 }
4446
4447 return not_found;
4448}

◆ is_dangling() [2/2]

bool dunedaq::oks::OksKernel::is_dangling ( OksObject * obj_ptr) const

Check pointer on oks object.

A pointer on object becomes dangling if such object was destroyed, or the data file which contains it was closed. The method scans through all oks objects and checks if given pointer is valid, i.e. points to an oks object.

If the method is used in the multi-threaded environment, it may be necessary to set read kernel lock before calling the method, in case if another threads can to create or to destroy objects or to open or to close oks data files.

Parameters
obj_ptra pointer to the oks object to be tested
Returns
Return true if the pointer on object is not valid.

Definition at line 4385 of file kernel.cpp.

4386{
4388 OSK_VERBOSE_REPORT("Enter OksKernel::is_dangling(OksObject *)")
4389
4390 bool not_found;
4391
4392 {
4393 std::lock_guard lock(p_objects_mutex);
4394 not_found = (p_objects.find(o) == p_objects.end());
4395 }
4396
4397 if (p_verbose) {
4398 std::string fname("OksKernel::is_dangling(");
4399
4400 if (not_found)
4401 fname += "?object?) returns true";
4402 else {
4403 fname += '\"';
4404 fname += o->GetId();
4405 fname += "\") returns false";
4406 }
4407
4408 OSK_VERBOSE_REPORT("LEAVE " << fname.c_str())
4409 }
4410
4411 return not_found;
4412}

◆ is_user_repository_created()

bool dunedaq::oks::OksKernel::is_user_repository_created ( ) const
inline

Definition at line 952 of file kernel.hpp.

◆ k_add()

void dunedaq::oks::OksKernel::k_add ( OksClass * c)
private

Definition at line 4231 of file kernel.cpp.

4232{
4233 TLOG_DEBUG(4) << "enter for class \"" << c->get_name() << '\"';
4234
4235 if (p_active_schema == 0) {
4236 throw CannotAddClass(*c, "no active schema");
4237 }
4238
4239 if (p_classes.find(c->get_name().c_str()) != p_classes.end()) {
4240 throw CannotAddClass(*c, "class already exists");
4241 }
4242
4243 c->p_kernel = this;
4244 c->p_file = p_active_schema;
4245 c->p_file->p_is_updated = true;
4246
4247 p_classes[c->get_name().c_str()] = c;
4248
4249 try {
4251 } catch (exception& ex) {
4252 throw CannotAddClass(*c, ex);
4253 }
4254
4256 (*OksClass::create_notify_fn)(c);
4257}
CannotAddClass(const OksClass &c, const exception &reason) noexcept
Definition kernel.hpp:331
void registrate_all_classes(bool skip_registered=false)
The method rebuilds all classes taking into account inheritance.
Definition kernel.cpp:4271

◆ k_bind_objects()

void dunedaq::oks::OksKernel::k_bind_objects ( )
private

Definition at line 4145 of file kernel.cpp.

4146{
4147 TLOG_DEBUG(4) << "enter";
4148
4149 p_bind_objects_status.clear();
4150
4151 if (!p_objects.empty()) {
4152 for (OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4153 try {
4154 (*i)->bind_objects();
4155 } catch (ObjectBindError& ex) {
4156 if (ex.p_is_error) {
4157 throw;
4158 } else {
4159 const std::string error_text(strchr(ex.what(), '\n') + 1);
4160 if (!p_bind_objects_status.empty())
4161 p_bind_objects_status.push_back('\n');
4162 p_bind_objects_status.append(error_text);
4163
4164 TLOG_DEBUG(1) << error_text;
4165 }
4166 }
4167 }
4168 }
4169
4170 if (!p_silence && !p_bind_objects_status.empty()) {
4171 ers::warning(kernel::BindError(ERS_HERE, p_bind_objects_status));
4172 }
4173
4174 TLOG_DEBUG(4) << "exit with status:\n" << p_bind_objects_status;
4175}
void warning(const Issue &issue)
Definition ers.hpp:150

◆ k_check_bind_classes_status()

void dunedaq::oks::OksKernel::k_check_bind_classes_status ( ) const
privatenoexcept

Definition at line 5459 of file kernel.cpp.

5460{
5461 std::ostringstream out;
5462
5463 for (auto& c : p_classes)
5464 c.second->check_relationships(out, true);
5465
5466 p_bind_classes_status = out.str();
5467}
FELIX Initialization std::string initerror FELIX queue timed out

◆ k_checkout_repository()

void dunedaq::oks::OksKernel::k_checkout_repository ( const std::string & param,
const std::string & val,
const std::string & branch )
private

Check out repository files into local user directory.

The method checks out GIT repository files into local user directory. The files have to be loaded from repository defined by TDAQ_DB_REPOSITORY environment. The TDAQ_DB_USER_REPOSITORY environment defines user directory and must be set.

Parameters
paramforward parameter to oks-git-checkout.sh
valforward value of above parameter to oks-git-checkout.sh
branchname of the branch to check out
Exceptions
Throwoks::exception in case of problems.

Definition at line 4643 of file kernel.cpp.

4644{
4645 if (get_repository_root().empty())
4646 throw RepositoryOperationFailed("checkout", "the repository root is not set");
4647
4648 ReposDirs reps("checkout", s_cwd, this);
4649
4650 std::string cmd("oks-checkout.sh");
4651
4652 if (get_verbose_mode()) {
4653 cmd += " -v";
4654 }
4655
4656 cmd.append(" -u ");
4657 cmd.append(get_user_repository_root());
4658
4659 if (!param.empty()) {
4660 cmd.append(" --");
4661 cmd.append(param);
4662 cmd.push_back(' ');
4663 cmd.push_back('\"');
4664 cmd.append(val);
4665 cmd.push_back('\"');
4666 }
4667
4668 if (!branch_name.empty()) {
4669 cmd.append(" -b ");
4670 cmd.append(branch_name);
4671 }
4672
4673 auto start_usage = std::chrono::steady_clock::now();
4674
4675 if (!p_silence) {
4676 std::lock_guard lock(p_parallel_out_mutex);
4677 log_timestamp() << "[OKS checkout] => " << cmd << std::endl;
4678 }
4679
4680 CommandOutput cmd_out("oks-checkout", this, cmd);
4681 cmd_out.check_command_status(system(cmd.c_str()));
4682
4684
4685 if (!p_silence) {
4686 std::lock_guard lock(p_parallel_out_mutex);
4687 std::cout << cmd_out.cat2str();
4689 << "[OKS checkout] => done in "
4690 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4691 1000.
4692 << " ms" << std::endl;
4693 }
4694
4695 static std::string version_prefix("checkout oks version ");
4696 std::string version = cmd_out.last_str();
4697 std::string::size_type pos = version.find(version_prefix);
4698
4699 if (pos == 0)
4700 p_repository_version = version.substr(version_prefix.size());
4701 else
4702 throw RepositoryOperationFailed("checkout", "cannot read oks version");
4703}

◆ k_close_dangling_includes()

void dunedaq::oks::OksKernel::k_close_dangling_includes ( )

Close files which lost their parent.

When a file is closed or an include is removed, some files may lost their parent and needs to be closed.

The method is not thread-safe.

Definition at line 1800 of file kernel.cpp.

1801{
1802 // build inclusion graph
1803
1804 OksFile::IMap igraph;
1805
1806 for (OksFile::Map::iterator i = p_schema_files.begin(); i != p_schema_files.end(); ++i) {
1807 for (std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin();
1808 x != i->second->p_list_of_include_files.end();
1809 ++x) {
1810 std::string f = get_file_path(*x, i->second);
1811 OksFile::Map::const_iterator it = p_schema_files.find(&f);
1812 if (it != p_schema_files.end()) {
1813 igraph[i->second].insert(it->second);
1814 } else {
1815 std::cerr << "cannot find schema " << *x << " included by " << i->second->get_full_file_name() << std::endl;
1816 }
1817 }
1818 }
1819
1820 for (OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
1821 for (std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin();
1822 x != i->second->p_list_of_include_files.end();
1823 ++x) {
1824 std::string f = get_file_path(*x, i->second);
1825 OksFile::Map::const_iterator it = p_data_files.find(&f);
1826 if (it != p_data_files.end()) {
1827 igraph[i->second].insert(it->second);
1828 } else {
1829 it = p_schema_files.find(&f);
1830
1831 if (it != p_schema_files.end()) {
1832 igraph[i->second].insert(it->second);
1833 } else {
1834 std::cerr << "cannot find file " << *x << " included by " << i->second->get_full_file_name() << std::endl;
1835 }
1836 }
1837 }
1838 }
1839
1840 const size_t num_of_schema_files(schema_files().size());
1841
1842 // calculate files to be closed
1843
1844 while (true) {
1845 std::list<OksFile*> schema_files, data_files; // files to be closed
1846
1847 OksFile::Map* files[2] = { &p_schema_files, &p_data_files };
1848 std::list<OksFile*> to_be_closed[2];
1849
1850 for (int c = 0; c < 2; ++c) {
1851 for (OksFile::Map::iterator i = files[c]->begin(); i != files[c]->end(); ++i) {
1852 if (OksFile* p = const_cast<OksFile*>(i->second->p_included_by)) {
1853 bool found_parent = false;
1854
1855 // check, the parent is valid
1856
1857 if (igraph.find(p) != igraph.end()) {
1858 OksFile::IMap::iterator j = igraph.find(p);
1859 if (test_parent(i->second, j)) {
1860 continue;
1861 }
1862 }
1863
1864 TLOG_DEBUG(1) << "the parent of file " << i->second->get_full_file_name() << " is not valid";
1865
1866 // try to find new parent
1867
1868 for (OksFile::IMap::iterator j = igraph.begin(); j != igraph.end(); ++j) {
1869 if (test_parent(i->second, j)) {
1870 found_parent = true;
1871 break;
1872 }
1873 }
1874
1875 if (found_parent == false) {
1876 TLOG_DEBUG(1) << "the file " << i->second->get_full_file_name()
1877 << " is not included by any other file and will be closed";
1878 to_be_closed[c].push_back(i->second);
1879 }
1880 }
1881 }
1882 }
1883
1884 int num = 0;
1885
1886 for (std::list<OksFile*>::const_iterator i = to_be_closed[1].begin(); i != to_be_closed[1].end(); ++i) {
1887 num += (*i)->p_list_of_include_files.size();
1888 k_close_data(*i, true);
1889 igraph.erase(*i);
1890 }
1891
1892 for (std::list<OksFile*>::const_iterator i = to_be_closed[0].begin(); i != to_be_closed[0].end(); ++i) {
1893 num += (*i)->p_list_of_include_files.size();
1894 k_close_schema(*i);
1895 igraph.erase(*i);
1896 }
1897
1898 if (num > 0) {
1899 TLOG_DEBUG(1) << "go into recursive call, number of potentially closed includes is " << num;
1900 } else {
1901 TLOG_DEBUG(1) << "break loop";
1902 break;
1903 }
1904 }
1905
1906 if (num_of_schema_files != schema_files().size()) {
1907 TLOG_DEBUG(1) << "rebuild classes since number of schema files has been changed from " << num_of_schema_files
1908 << " to " << schema_files().size();
1910 }
1911}
std::unordered_map< OksFile *, Set, oks::hash_file_ptr, oks::equal_file_ptr > IMap
Definition file.hpp:385
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1472
bool test_parent(OksFile *file, OksFile::IMap::iterator &i)
Definition kernel.cpp:1782
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1211

◆ k_close_data()

void dunedaq::oks::OksKernel::k_close_data ( OksFile * fp,
bool unbind )
private

Definition at line 3975 of file kernel.cpp.

3976{
3977 const char _fname[] = "k_close_data";
3978 std::string fname = make_fname(_fname, sizeof(_fname) - 1, fp->p_full_name, &unbind, nullptr);
3979
3981 OSK_VERBOSE_REPORT("ENTER " << fname)
3982
3983 try {
3984 fp->unlock();
3985 } catch (exception& ex) {
3986 Oks::error_msg(fname) << ex.what() << std::endl;
3987 }
3988
3989 if (!p_silence) {
3990 std::lock_guard lock(p_parallel_out_mutex);
3991 std::cout << (fp->p_included_by ? " * c" : "C") << "lose OKS data \"" << fp->p_full_name << "\"..." << std::endl;
3992 }
3993
3994 if (unbind) {
3995 for (OksObject::Set::const_iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
3996 OksObject* o = *i;
3997 if (o->file != fp)
3998 o->unbind_file(fp);
3999 }
4000 }
4001
4002 if (p_close_all == false) {
4003 std::list<OksObject*>* olist = create_list_of_data_objects(fp);
4004
4005 if (olist) {
4006 while (!olist->empty()) {
4007 OksObject* o = olist->front();
4008 olist->pop_front();
4009 if (!is_dangling(o))
4010 delete o;
4011 }
4012
4013 delete olist;
4014 }
4015 }
4016
4017 remove_data_file(fp);
4018 delete fp;
4019
4020 if (p_active_data == fp)
4021 p_active_data = 0;
4022
4023 OSK_VERBOSE_REPORT("LEAVE " << fname)
4024}
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
Definition kernel.cpp:4415
std::list< OksObject * > * create_list_of_data_objects(OksFile *) const
Creates list of objects which belong to given file.
Definition kernel.cpp:4106
void remove_data_file(OksFile *)
Definition kernel.cpp:3558

◆ k_close_schema()

void dunedaq::oks::OksKernel::k_close_schema ( OksFile * pf)
private

Definition at line 2625 of file kernel.cpp.

2626{
2628
2629 if (!pf) {
2630 TLOG_DEBUG(1) << "enter for file (null)";
2631 return;
2632 } else {
2633 TLOG_DEBUG(2) << "enter for file " << pf->p_full_name;
2634 }
2635
2636 if (p_active_schema == pf)
2637 p_active_schema = 0;
2638
2639 try {
2640 pf->unlock();
2641 } catch (exception& ex) {
2642 Oks::error_msg("OksKernel::k_close_schema()") << ex.what() << std::endl;
2643 }
2644
2645 if (!p_silence)
2646 std::cout << (pf->p_included_by ? " * c" : "C") << "lose OKS schema \"" << pf->p_full_name << "\"..." << std::endl;
2647
2648 if (!p_classes.empty()) {
2649
2650 //
2651 // The fastest way to delete classes is delete
2652 // them in order of superclasses descreasing
2653 // because this reduces amount of work to restructure
2654 // child classes when their parent was deleted and
2655 // there will be no dangling classes
2656 //
2657
2658 std::set<OksClass*> sorted;
2659
2660 for (OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2661 OksClass* c = i->second;
2662 if (pf == c->p_file)
2663 sorted.insert(c);
2664 c->p_to_be_deleted = true;
2665 }
2666
2667 for (std::set<OksClass*>::iterator j = sorted.begin(); j != sorted.end(); ++j) {
2668 delete *j;
2669 }
2670 }
2671
2673 delete pf;
2674
2675 TLOG_DEBUG(4) << "exit for file " << (void*)pf;
2676}
std::string p_full_name
Definition file.hpp:723
void remove_schema_file(OksFile *)
Definition kernel.cpp:3564

◆ k_copy_repository()

void dunedaq::oks::OksKernel::k_copy_repository ( const std::string & source,
const std::string & destination )
private

Definition at line 4723 of file kernel.cpp.

4724{
4725 std::string cmd("oks-copy.sh");
4726
4727 if (get_verbose_mode())
4728 cmd.append(" -v");
4729
4730 cmd.append(" -s ");
4731 cmd.append(source);
4732
4733 cmd.append(" -d ");
4734 cmd.append(destination);
4735
4736 cmd.append(" -c ");
4737 cmd.append(get_repository_version());
4738
4739 auto start_usage = std::chrono::steady_clock::now();
4740
4741 if (!p_silence) {
4742 std::lock_guard lock(p_parallel_out_mutex);
4743 log_timestamp() << "[OKS copy] => " << cmd << std::endl;
4744 }
4745
4746 CommandOutput cmd_out("oks-copy", this, cmd);
4747 cmd_out.check_command_status(system(cmd.c_str()));
4748
4749 if (!p_silence) {
4750 std::lock_guard lock(p_parallel_out_mutex);
4751 std::cout << cmd_out.cat2str();
4753 << "[OKS copy] => done in "
4754 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4755 1000.
4756 << " ms" << std::endl;
4757 }
4758}

◆ k_load_data() [1/2]

OksFile * dunedaq::oks::OksKernel::k_load_data ( const std::string & short_file_name,
bool bind,
const OksFile * parent_h,
OksPipeline * pipeline )
private

Definition at line 3356 of file kernel.cpp.

3357{
3358 const char _fname[] = "k_load_data";
3359 std::string fname = make_fname(_fname, sizeof(_fname) - 1, short_file_name, &bind, &parent_h);
3360
3361 OSK_VERBOSE_REPORT("ENTER " << fname)
3362
3363 std::string full_file_name;
3364
3365 try {
3366 full_file_name = get_file_path(short_file_name, parent_h);
3367 } catch (std::exception& e) {
3368 throw CanNotOpenFile("k_load_data", short_file_name, e.what());
3369 }
3370
3371 try {
3372
3373 OksFile* fp = find_data_file(full_file_name);
3374
3375 if (fp != 0) {
3376 if (p_verbose) {
3377 std::lock_guard lock(p_parallel_out_mutex);
3378 Oks::warning_msg(fname) << " The file \'" << full_file_name << "\' was already loaded";
3379 }
3380 return fp->check_parent(parent_h);
3381 }
3382
3383 {
3384 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
3385
3386 if (!f->good()) {
3387 throw std::runtime_error("k_load_data(): cannot open file");
3388 }
3389
3390 long file_length(get_file_length(*f));
3391
3392 if (!file_length) {
3393 throw std::runtime_error("k_load_data(): file is empty");
3394 }
3395
3396 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
3397
3398 fp = new OksFile(xmls, short_file_name, full_file_name, this);
3399
3400 if (fp->p_oks_format.empty()) {
3401 throw std::runtime_error("k_load_data(): failed to read header of file");
3402 }
3403
3404 char format;
3405
3406 if (fp->p_oks_format.size() == 4 && cmp_str4n(fp->p_oks_format.c_str(), "data"))
3407 format = 'n';
3408 else if (fp->p_oks_format.size() == 8 && cmp_str8n(fp->p_oks_format.c_str(), "extended"))
3409 format = 'X';
3410 else if (fp->p_oks_format.size() == 7 && cmp_str7n(fp->p_oks_format.c_str(), "compact"))
3411 format = 'c';
3412 else {
3413 throw std::runtime_error("k_load_data(): file is not an oks data file");
3414 }
3415
3416 k_load_data(fp, format, xmls, file_length, bind, parent_h, pipeline);
3417
3418 OSK_VERBOSE_REPORT("LEAVE " << fname)
3419
3420 return fp;
3421 }
3422 } catch (FailedLoadFile&) {
3423 throw;
3424 } catch (exception& e) {
3425 throw(FailedLoadFile("data file", full_file_name, e));
3426 } catch (std::exception& e) {
3427 throw(FailedLoadFile("data file", full_file_name, e.what()));
3428 }
3429}
CanNotOpenFile(const char *prefix, const std::string &name, const std::string &reason) noexcept
Definition kernel.hpp:148
OksFile * k_load_data(const std::string &, bool, const OksFile *, OksPipeline *)
Definition kernel.cpp:3356
static std::ostream & warning_msg(const char *)
Definition kernel.cpp:518
bool cmp_str8n(const char *s1, const char s2[9])
Definition cstring.hpp:99
bool cmp_str7n(const char *s1, const char s2[8])
Definition cstring.hpp:87
static long get_file_length(std::ifstream &f)
Definition kernel.cpp:446
bool cmp_str4n(const char *s1, const char s2[4])
Definition cstring.hpp:51

◆ k_load_data() [2/2]

void dunedaq::oks::OksKernel::k_load_data ( OksFile * fp,
char format,
std::shared_ptr< OksXmlInputStream > xmls,
long file_length,
bool bind,
const OksFile * parent_h,
OksPipeline * pipeline )
private

Definition at line 3432 of file kernel.cpp.

3439{
3441
3442 fp->p_included_by = parent_h;
3443 check_read_only(fp);
3444
3445 try {
3446 if (!p_silence) {
3447 std::lock_guard lock(p_parallel_out_mutex);
3448 std::cout << (parent_h ? " * r" : "R") << "eading data file \"" << fp->get_full_file_name() << "\" in "
3449 << (format == 'n' ? "normal" : (format == 'X' ? "extended" : "compact")) << " format (" << file_length
3450 << " bytes)...\n";
3451 if (parent_h == 0 && fp->get_full_file_name() != fp->get_short_file_name()) {
3452 std::cout << "(non-fully-qualified filename was \"" << fp->get_short_file_name() << "\")\n";
3453 }
3454 }
3455
3456 fp->update_status_of_file();
3457 add_data_file(fp);
3458
3459 {
3460 std::unique_ptr<OksPipeline> pipeline_guard(pipeline ? 0 : new OksPipeline(p_threads_pool_size));
3461
3462 OksPipeline* m_pipeline;
3463
3464 if (pipeline) {
3465 m_pipeline = pipeline;
3466 } else {
3467 m_pipeline = pipeline_guard.get();
3469 }
3470
3471 k_load_includes(*fp, m_pipeline);
3472
3473 if (p_threads_pool_size > 1) {
3474 m_pipeline->addJob(new OksLoadObjectsJob(this, fp, xmls, format));
3475 } else {
3476 OksLoadObjectsJob job(this, fp, xmls, format);
3477 job.run();
3478 }
3479 }
3480
3481 if (!pipeline) {
3482 if (!p_load_errors.is_empty()) {
3483 throw(FailedLoadFile("data file", fp->get_full_file_name(), p_load_errors.get_text()));
3484 }
3485
3486 if (bind) {
3488 }
3489 }
3490 } catch (FailedLoadFile&) {
3491 throw;
3492 } catch (exception& e) {
3493 throw(FailedLoadFile("data file", fp->get_full_file_name(), e));
3494 } catch (std::exception& e) {
3495 throw(FailedLoadFile("data file", fp->get_full_file_name(), e.what()));
3496 }
3497}
friend struct OksLoadObjectsJob
Definition kernel.hpp:620
void add_data_file(OksFile *)
Definition kernel.cpp:3546
void k_load_includes(const OksFile &, OksPipeline *)
Definition kernel.cpp:1711
std::string get_text()
Definition kernel.cpp:2880
OksLoadObjectsJob(OksKernel *kernel, OksFile *fp, std::shared_ptr< OksXmlInputStream > xmls, char format)
Definition kernel.cpp:2906

◆ k_load_file()

OksFile * dunedaq::oks::OksKernel::k_load_file ( const std::string & name,
bool bind,
const OksFile * parent,
OksPipeline * pipeline )
private

Definition at line 1634 of file kernel.cpp.

1635{
1636 const char _fname[] = "k_load_file";
1637 std::string fname = make_fname(_fname, sizeof(_fname) - 1, short_file_name, &bind, &parent_h);
1638
1639 OSK_VERBOSE_REPORT("ENTER " << fname)
1640
1641 std::string full_file_name;
1642
1643 try {
1644 full_file_name = get_file_path(short_file_name, parent_h);
1645 } catch (std::exception& e) {
1646 throw CanNotOpenFile("k_load_file", short_file_name, e.what());
1647 }
1648
1649 try {
1650
1651 // check if the file is already loaded
1652
1653 OksFile::Map::const_iterator i = p_schema_files.find(&full_file_name);
1654 if (i != p_schema_files.end())
1655 return i->second->check_parent(parent_h);
1656
1657 i = p_data_files.find(&full_file_name);
1658 if (i != p_data_files.end())
1659 return i->second->check_parent(parent_h);
1660
1661 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
1662
1663 if (f->good()) {
1664 long file_length(get_file_length(*f));
1665
1666 if (!file_length) {
1667 throw std::runtime_error("k_load_file(): file is empty");
1668 }
1669
1670 // read file header and decide what to load
1671
1672 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1673
1674 OksFile* file_h = new OksFile(xmls, short_file_name, full_file_name, this);
1675
1676 if (file_h->p_oks_format.size() == 6 && cmp_str6n(file_h->p_oks_format.c_str(), "schema")) {
1677 k_load_schema(file_h, xmls, parent_h);
1678 } else {
1679 char format;
1680
1681 if (file_h->p_oks_format.size() == 4 && cmp_str4n(file_h->p_oks_format.c_str(), "data"))
1682 format = 'n';
1683 else if (file_h->p_oks_format.size() == 8 && cmp_str8n(file_h->p_oks_format.c_str(), "extended"))
1684 format = 'X';
1685 else if (file_h->p_oks_format.size() == 7 && cmp_str7n(file_h->p_oks_format.c_str(), "compact"))
1686 format = 'c';
1687 else {
1688 delete file_h;
1689 throw std::runtime_error("k_load_file(): failed to parse header");
1690 }
1691
1692 k_load_data(file_h, format, xmls, file_length, bind, parent_h, pipeline);
1693 }
1694
1695 OSK_VERBOSE_REPORT("LEAVE " << fname)
1696
1697 return file_h;
1698 } else {
1699 throw std::runtime_error("k_load_file(): cannot open file");
1700 }
1701 } catch (exception& e) {
1702 throw FailedLoadFile("file", full_file_name, e);
1703 } catch (std::exception& e) {
1704 throw FailedLoadFile("file", full_file_name, e.what());
1705 } catch (...) {
1706 throw FailedLoadFile("file", full_file_name, "caught unknown exception");
1707 }
1708}
OksFile * k_load_schema(const std::string &, const OksFile *)
Definition kernel.cpp:2138
bool cmp_str6n(const char *s1, const char s2[6])
Definition cstring.hpp:75

◆ k_load_includes()

void dunedaq::oks::OksKernel::k_load_includes ( const OksFile & f,
OksPipeline * pipeline )
private

Definition at line 1711 of file kernel.cpp.

1712{
1713 for (std::list<std::string>::const_iterator i = f.p_list_of_include_files.begin();
1714 i != f.p_list_of_include_files.end();
1715 ++i) {
1716 if (!(*i).empty()) {
1717 // if(f.get_repository() != OksFile::NoneRepository) {
1718 if (!get_user_repository_root().empty()) {
1719 if ((*i)[0] == '/') {
1720 throw FailedLoadFile("include",
1721 *i,
1722 "inclusion of files with absolute pathname (like \"/foo/bar\") is not allowed by "
1723 "repository files; include files relative to repository root (like \"foo/bar\")");
1724 } else if ((*i)[0] == '.') {
1725 throw FailedLoadFile(
1726 "include",
1727 *i,
1728 "inclusion of files with file-related relative pathnames (like \"../foo/bar\" or \"./bar\") is not "
1729 "supported by repository files; include files relative to repository root (like \"foo/bar\")");
1730 } else if ((*i).find('/') == std::string::npos) {
1731 throw FailedLoadFile("include",
1732 *i,
1733 "inclusion of files with file-related local pathnames (like \"bar\") is not supported "
1734 "by repository files; include files relative to repository root (like \"foo/bar\")");
1735 }
1736 }
1737
1738 try {
1739 k_load_file(*i, false, &f, pipeline);
1740 } catch (exception& e) {
1741 throw FailedLoadFile("include", *i, e);
1742 } catch (std::exception& e) {
1743 throw FailedLoadFile("include", *i, e.what());
1744 }
1745 } else {
1746 throw FailedLoadFile("include", *i, "empty filename");
1747 }
1748 }
1749}
OksFile * k_load_file(const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
Definition kernel.cpp:1634

◆ k_load_schema() [1/2]

OksFile * dunedaq::oks::OksKernel::k_load_schema ( const std::string & short_file_name,
const OksFile * parent_h )
private

Definition at line 2138 of file kernel.cpp.

2139{
2140 const char _fname[] = "k_load_schema";
2141 std::string fname = make_fname(_fname, sizeof(_fname) - 1, short_file_name, nullptr, &parent_h);
2142
2143 OSK_VERBOSE_REPORT("ENTER " << fname)
2144
2145 std::string full_file_name;
2146
2147 try {
2148 full_file_name = get_file_path(short_file_name, parent_h);
2149 } catch (std::exception& e) {
2150 throw CanNotOpenFile("k_load_schema", short_file_name, e.what());
2151 }
2152
2153 try {
2154 OksFile* fp = find_schema_file(full_file_name);
2155
2156 if (fp != 0) {
2157 if (p_verbose) {
2158 std::lock_guard lock(p_parallel_out_mutex);
2159 Oks::warning_msg(fname) << " The file was already loaded\n";
2160 }
2161 return fp->check_parent(parent_h);
2162 }
2163
2164 {
2165 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
2166
2167 if (!f->good()) {
2168 throw std::runtime_error("k_load_schema(): cannot open file");
2169 }
2170
2171 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
2172
2173 fp = new OksFile(xmls, short_file_name, full_file_name, this);
2174
2175 if (fp->p_oks_format.empty()) {
2176 throw std::runtime_error("k_load_schema(): failed to read header of file");
2177 } else if (fp->p_oks_format != "schema") {
2178 throw std::runtime_error("k_load_schema(): file is not oks schema file");
2179 }
2180
2181 k_load_schema(fp, xmls, parent_h);
2182
2183 OSK_VERBOSE_REPORT("LEAVE " << fname)
2184
2185 return fp;
2186 }
2187 } catch (FailedLoadFile&) {
2188 throw; // forward
2189 } catch (exception& e) {
2190 throw FailedLoadFile("schema file", full_file_name, e);
2191 } catch (std::exception& e) {
2192 throw FailedLoadFile("schema file", full_file_name, e.what());
2193 } catch (...) {
2194 throw FailedLoadFile("schema file", full_file_name, "caught unknown exception");
2195 }
2196}

◆ k_load_schema() [2/2]

void dunedaq::oks::OksKernel::k_load_schema ( OksFile * fp,
std::shared_ptr< OksXmlInputStream > xmls,
const OksFile * parent_h )
private

Definition at line 2199 of file kernel.cpp.

2200{
2202
2203 fp->p_included_by = parent_h;
2204 check_read_only(fp);
2205
2206 try {
2207 if (!p_silence) {
2208 std::lock_guard lock(p_parallel_out_mutex);
2209 std::cout << (parent_h ? " * loading " : "Loading ") << fp->p_number_of_items << " classes from file \""
2210 << fp->get_full_file_name() << "\"...\n";
2211 if (parent_h == 0 && fp->get_full_file_name() != fp->get_short_file_name()) {
2212 std::cout << "(non-fully-qualified filename was \"" << fp->get_short_file_name() << "\")\n";
2213 }
2214 }
2215
2216 k_load_includes(*fp, 0);
2217
2218 add_schema_file(fp);
2219
2220 std::list<OksClass*> set;
2221
2222 while (true) {
2223 OksClass* c = 0;
2224
2225 try {
2226 c = new OksClass(*xmls, this);
2227 } catch (EndOfXmlStream&) {
2228 delete c;
2229 break;
2230 }
2231
2232 if (c->get_name().empty()) {
2233 throw std::runtime_error("k_load_schema(): failed to read a class");
2234 }
2235
2236 OksClass::Map::const_iterator ic = p_classes.find(c->get_name().c_str());
2237 if (ic != p_classes.end()) {
2238 bool are_different = (*ic->second != *c);
2239
2240 c->p_transient = true;
2241 delete c;
2242 c = ic->second;
2243 if (p_allow_duplicated_classes && !are_different) {
2244 static bool ers_report = (getenv("OKS_KERNEL_ERS_REPORT_DUPLICATED_CLASSES") != nullptr);
2245 if (ers_report) {
2246 ers::warning(kernel::ClassAlreadyDefined(
2247 ERS_HERE, c->get_name(), fp->get_full_file_name(), c->p_file->get_full_file_name()));
2248 } else {
2249 const char _fname[] = "k_load_schema";
2250 std::lock_guard lock(p_parallel_out_mutex);
2251 Oks::warning_msg(make_fname(_fname, sizeof(_fname) - 1, fp->get_full_file_name(), nullptr, &parent_h))
2252 << " Class \"" << c->get_name() << "\" was already loaded from file \'"
2253 << c->get_file()->get_full_file_name() << "\'\n";
2254 }
2255 } else {
2256 std::stringstream text;
2257 text << (are_different ? "different " : "") << "class \"" << c->get_name()
2258 << "\" was already loaded from file \'" << c->get_file()->get_full_file_name() << '\'';
2259 throw std::runtime_error(text.str().c_str());
2260 }
2261 } else {
2262 {
2263 std::unique_lock lock(p_schema_mutex); // protect schema and all objects from changes
2264 p_classes[c->get_name().c_str()] = c;
2265 }
2266 c->p_file = fp;
2268 set.push_back(c);
2269 }
2270 }
2271
2272 fp->p_size = xmls->get_position();
2273
2275
2277 for (std::list<OksClass*>::iterator i2 = set.begin(); i2 != set.end(); ++i2)
2278 (*OksClass::create_notify_fn)(*i2);
2279
2281 std::set<OksClass*> set2;
2282
2283 for (std::list<OksClass*>::iterator i2 = set.begin(); i2 != set.end(); ++i2) {
2284 OksClass* c = *i2;
2285 if (c->p_all_sub_classes && !c->p_all_sub_classes->empty()) {
2286 for (OksClass::FList::iterator i3 = c->p_all_sub_classes->begin(); i3 != c->p_all_sub_classes->end(); ++i3) {
2287 if (set2.find(*i3) == set2.end()) {
2288 (*OksClass::change_notify_fn)(*i3, OksClass::ChangeSuperClassesList, (const void*)(&(c->p_name)));
2289 set2.insert(*i3);
2290 }
2291 }
2292 }
2293 }
2294 }
2295
2296 fp->update_status_of_file();
2297 } catch (exception& e) {
2298 throw FailedLoadFile("schema file", fp->get_full_file_name(), e);
2299 } catch (std::exception& e) {
2300 throw FailedLoadFile("schema file", fp->get_full_file_name(), e.what());
2301 } catch (...) {
2302 throw FailedLoadFile("schema file", fp->get_full_file_name(), "caught unknown exception");
2303 }
2304}
void add_schema_file(OksFile *)
Definition kernel.cpp:3552
std::shared_mutex p_schema_mutex
Definition kernel.hpp:1968
std::unordered_set< std::string > set
Definition set.hpp:16

◆ k_preload_includes()

bool dunedaq::oks::OksKernel::k_preload_includes ( OksFile * file_h,
std::set< OksFile * > & new_files,
bool allow_schema_extension )
private

Definition at line 1914 of file kernel.cpp.

1915{
1916 bool found_include_changes(false);
1917
1918 try {
1919 std::shared_ptr<std::ifstream> file(new std::ifstream(fp->get_full_file_name().c_str()));
1920
1921 if (!file->good()) {
1922 throw std::runtime_error(std::string("k_preload_includes(): cannot open file \"") + fp->get_full_file_name() +
1923 '\"');
1924 }
1925
1926 // keep included files
1927
1928 std::set<std::string> included;
1929
1930 if (fp->p_list_of_include_files.size()) {
1931 for (std::list<std::string>::iterator i = fp->p_list_of_include_files.begin();
1932 i != fp->p_list_of_include_files.end();
1933 ++i) {
1934 included.insert(*i);
1935 }
1936 }
1937
1938 // get size of file and check that it is not empty
1939
1940 file->seekg(0, std::ios::end);
1941
1942 long file_length = static_cast<std::streamoff>(file->tellg());
1943
1944 if (file_length == 0) {
1945 throw std::runtime_error(std::string("k_preload_includes(): file \"") + fp->get_full_file_name() + "\" is empty");
1946 }
1947
1948 file->seekg(0, std::ios::beg);
1949
1950 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(file));
1951
1952 {
1953 OksFile fp2(xmls, fp->get_short_file_name(), fp->get_full_file_name(), this);
1954 fp2.p_included_by = fp->p_included_by;
1955 p_preload_file_info[fp] = new OksFile(*fp);
1956 *fp = fp2;
1957
1958 if (fp->p_oks_format.empty()) {
1959 throw std::runtime_error(std::string("k_preload_includes(): failed to read header of file \"") +
1960 fp->get_full_file_name() + '\"');
1961 } else if (fp->p_oks_format == "schema") {
1962 TLOG_DEBUG(2) << "skip reload of schema file \'" << fp->get_full_file_name() << '\'';
1963 return false;
1964 } else if (fp->p_oks_format != "data" && fp->p_oks_format != "extended" && fp->p_oks_format != "compact") {
1965 throw std::runtime_error(std::string("k_preload_includes(): file \"") + fp->get_full_file_name() +
1966 "\" is not valid oks file");
1967 }
1968 }
1969
1970 if (fp->p_list_of_include_files.size()) {
1971 TLOG_DEBUG(3) << "check \'include\' of the file \'" << fp->get_full_file_name() << '\'';
1972
1973 if (included.size() != fp->p_list_of_include_files.size())
1974 found_include_changes = true;
1975
1976 for (std::list<std::string>::iterator i = fp->p_list_of_include_files.begin();
1977 i != fp->p_list_of_include_files.end();
1978 ++i) {
1979 std::set<std::string>::const_iterator x = included.find(*i);
1980 if (x != included.end()) {
1981 TLOG_DEBUG(3) << "include \'" << *i << "\' already exists, skip...";
1982 } else {
1983 TLOG_DEBUG(3) << "the file \'" << *i << "\' was not previously included by \'" << fp->get_full_file_name()
1984 << '\'';
1985
1986 found_include_changes = true;
1987
1988 std::string full_file_name;
1989
1990 try {
1991 full_file_name = get_file_path(*i, fp);
1992 } catch (std::exception& e) {
1993 throw CanNotOpenFile("k_preload_includes", *i, e.what());
1994 }
1995
1996 OksFile::Map::const_iterator j = p_schema_files.find(&full_file_name);
1997 if (j != p_schema_files.end()) {
1998 TLOG_DEBUG(3) << "the include \'" << *i << "\' is already loaded schema file \'" << j->first << '\'';
1999 continue;
2000 }
2001
2002 j = p_data_files.find(&full_file_name);
2003 if (j != p_data_files.end()) {
2004 TLOG_DEBUG(3) << "the include \'" << *i << "\' is already loaded data file \'" << j->first << '\'';
2005 continue;
2006 }
2007
2008 if (OksFile* f = create_file_info(*i, full_file_name)) {
2009 if (f->p_oks_format == "schema") {
2010 std::string new_schema_full_file_name = f->get_full_file_name();
2011 delete f;
2012 if (p_schema_files.find(&new_schema_full_file_name) != p_schema_files.end()) {
2013 TLOG_DEBUG(3) << "the include \'" << *i << "\' is a schema file, that was already loaded";
2014 continue;
2015 } else {
2016 if (allow_schema_extension) {
2017 TLOG_DEBUG(3) << "the include \'" << *i << "\' is new schema file, loading...";
2018 k_load_schema(*i, fp);
2019 continue;
2020 } else {
2021 std::ostringstream text;
2022 text << "k_preload_includes(): include of new schema file (\'" << *i
2023 << "\') is not allowed on data reload";
2024 throw std::runtime_error(text.str().c_str());
2025 }
2026 }
2027 } else if (f->p_oks_format == "data" || f->p_oks_format == "extended" || f->p_oks_format == "compact") {
2028 TLOG_DEBUG(3) << "the include \'" << *i << "\' is new data file, pre-loading...";
2029 add_data_file(f);
2030 p_preload_added_files.push_back(f);
2031 new_files_h.insert(f);
2032 f->p_list_of_include_files.clear();
2033 if (k_preload_includes(f, new_files_h, allow_schema_extension))
2034 found_include_changes = true;
2035 f->p_included_by = fp;
2036 f->update_status_of_file();
2037 } else {
2038 delete f;
2039 std::ostringstream text;
2040 text << "k_preload_includes(): failed to parse header of included \'" << full_file_name << "\' file";
2041 throw std::runtime_error(text.str().c_str());
2042 }
2043 } else {
2044 throw std::runtime_error("k_load_file(): cannot open file");
2045 }
2046 }
2047 }
2048 }
2049 } catch (exception& e) {
2050 throw FailedLoadFile("data file", fp->get_full_file_name(), e);
2051 } catch (std::exception& e) {
2052 throw FailedLoadFile("data file", fp->get_full_file_name(), e.what());
2053 }
2054
2055 return found_include_changes;
2056}
OksFile * create_file_info(const std::string &short_file_name, const std::string &file_name)
Creates OKS file descriptor.
Definition kernel.cpp:1428
bool k_preload_includes(OksFile *file_h, std::set< OksFile * > &new_files, bool allow_schema_extension)
Definition kernel.cpp:1914

◆ k_remove()

void dunedaq::oks::OksKernel::k_remove ( OksClass * c)
private

Definition at line 4260 of file kernel.cpp.

4261{
4262 TLOG_DEBUG(4) << "enter for class \"" << c->get_name() << '\"';
4263
4265 (*OksClass::delete_notify_fn)(c);
4266
4267 p_classes.erase(c->get_name().c_str());
4268}

◆ k_rename_data()

void dunedaq::oks::OksKernel::k_rename_data ( OksFile * pf,
const std::string & short_name,
const std::string & long_name )
private

Definition at line 3898 of file kernel.cpp.

3899{
3900 remove_data_file(pf);
3901 pf->rename(short_name, long_name);
3902 add_data_file(pf);
3903}

◆ k_rename_repository_file()

void dunedaq::oks::OksKernel::k_rename_repository_file ( OksFile * file_h,
const std::string & new_name )
private

Definition at line 4629 of file kernel.cpp.

4630{
4631 if (file_h->p_oks_format == "schema") {
4632 remove_schema_file(file_h);
4633 file_h->rename(new_name);
4634 add_schema_file(file_h);
4635 } else {
4636 remove_data_file(file_h);
4637 file_h->rename(new_name);
4638 add_data_file(file_h);
4639 }
4640}

◆ k_rename_schema()

void dunedaq::oks::OksKernel::k_rename_schema ( OksFile * pf,
const std::string & short_name,
const std::string & long_name )
private

Definition at line 2550 of file kernel.cpp.

2551{
2553 pf->rename(short_name, long_name);
2554 add_schema_file(pf);
2555}

◆ k_save_data()

void dunedaq::oks::OksKernel::k_save_data ( OksFile * pf,
bool ignoreBadObjects = false,
OksFile * fh = nullptr,
const OksObject::FSet * objects = nullptr,
bool force_defaults = false )
private

Definition at line 3619 of file kernel.cpp.

3624{
3625 const char _fname[] = "k_save_data";
3626 std::string fname = make_fname(_fname, sizeof(_fname) - 1, pf->p_full_name, nullptr, nullptr);
3627
3629 OSK_VERBOSE_REPORT("ENTER " << fname)
3630
3631 std::string tmp_file_name;
3632
3633 if (!fh)
3634 fh = pf;
3635
3636 try {
3637
3638 // calculate number of objects in file and check objects
3639
3640 size_t numberOfObjects = 0;
3641
3642 if (objects) {
3643 numberOfObjects = objects->size();
3644
3645 if (!ignoreBadObjects) {
3646 std::string errors;
3647
3648 for (OksObject::FSet::const_iterator i = objects->begin(); i != objects->end(); ++i) {
3649 errors += (*i)->report_dangling_references();
3650 }
3651
3652 if (!errors.empty()) {
3653 std::ostringstream text;
3654 text << "the file contains objects with dangling references:\n" << errors;
3655 throw std::runtime_error(text.str().c_str());
3656 }
3657 }
3658 } else {
3659 // get list of all includes
3660
3661 std::set<OksFile*> includes;
3662 pf->get_all_include_files(this, includes);
3663
3664 OSK_VERBOSE_REPORT("Test consistency of objects in file \"" << pf->p_full_name << '\"')
3665
3666 bool found_bad_object = false;
3667
3668 for (OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
3669 if ((*i)->file == fh) {
3670 numberOfObjects++;
3671 if (!ignoreBadObjects || !p_silence) {
3672 if ((*i)->is_consistent(includes, "WARNING") == false) {
3673 found_bad_object = true;
3674 }
3675 if ((*i)->is_duplicated() == true) {
3676 if (!p_silence) {
3677 Oks::error_msg(fname) << " The file contains duplicated object " << *i << std::endl;
3678 }
3679 found_bad_object = true;
3680 }
3681 }
3682 }
3683 }
3684
3685 if (found_bad_object && ignoreBadObjects == false) {
3686 throw std::runtime_error("the file contains inconsistent/duplicated objects or misses includes");
3687 }
3688 }
3689
3690 // lock the file, if it is not locked already
3691
3692 if (pf->is_locked() == false) {
3693 pf->lock();
3694 }
3695
3696 // check if it possible to open the non-existent file in write mode
3697
3698 {
3699 // check first if file already exists
3700
3701 std::fstream f(pf->p_full_name.c_str(), std::ios::in);
3702
3703 if (!f) {
3704
3705 // no check for non-existent file
3706
3707 std::fstream f2(pf->p_full_name.c_str(), std::ios::out);
3708
3709 if (!f2) {
3710 std::ostringstream text;
3711 text << "cannot open file \'" << pf->p_full_name << "\' for writing";
3712 throw std::runtime_error(text.str().c_str());
3713 }
3714 }
3715 }
3716
3717 tmp_file_name = get_tmp_file(pf->p_full_name);
3718
3719 long file_len = 0;
3720
3721 {
3722 std::ofstream f(tmp_file_name.c_str());
3723
3724 f.exceptions(std::ostream::failbit | std::ostream::badbit);
3725
3726 if (!f) {
3727 std::ostringstream text;
3728 text << "cannot create temporal file \'" << tmp_file_name << "\' to save data";
3729 throw std::runtime_error(text.str().c_str());
3730 } else {
3731 if (!p_silence) {
3732 std::lock_guard lock(p_parallel_out_mutex);
3733 std::cout << "Saving " << numberOfObjects << " objects "
3734 << (force_defaults ? "with enforced default values " : "") << "to data file \"" << pf->p_full_name
3735 << "\"...\n";
3736 }
3737 }
3738
3739 // set header parameters
3740
3741 OksXmlOutputStream xmls(f);
3742
3743 pf->p_number_of_items = numberOfObjects;
3744 pf->p_oks_format = "data";
3745
3746 pf->write(xmls);
3747
3748 if (!p_objects.empty()) {
3749 for (OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end() && f.good(); ++i) {
3750 OksObject::SMap sorted;
3751
3752 for (OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end();
3753 ++j) {
3754 if (j->second->file == fh || (objects && (objects->find(j->second) != objects->end()))) {
3755 sorted[j->first] = j->second;
3756 }
3757 }
3758
3759 for (OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3760 j->second->put(xmls, force_defaults);
3761 xmls.put_raw('\n');
3762 }
3763 }
3764 }
3765
3766 xmls.put_last_tag("oks-data", sizeof("oks-data") - 1);
3767 file_len = f.tellp();
3768
3769 f.close();
3770 }
3771
3772 // check that the written file is OK
3773 // FIXME: can be removed later, if exceptions work well enough
3774
3775 {
3776 long written_len = 0;
3777
3778 std::shared_ptr<std::ifstream> f(new std::ifstream(tmp_file_name.c_str()));
3779
3780 if (*f) {
3781 f->seekg(0, std::ios::end);
3782 written_len = static_cast<std::streamoff>(f->tellg());
3783 }
3784
3785 if (written_len != file_len) {
3786 unlink(tmp_file_name.c_str());
3787 std::ostringstream text;
3788 text << "write error in file \'" << tmp_file_name << "\': " << written_len << " bytes been written instead of "
3789 << file_len;
3790 throw std::runtime_error(text.str().c_str());
3791 }
3792 }
3793
3794 // remember file's mode
3795
3796 struct stat buf;
3797 if (int code = stat(pf->p_full_name.c_str(), &buf)) {
3798 std::ostringstream text;
3799 text << "cannot get information about file \'" << pf->p_full_name << "\': stat() failed with code " << code
3800 << ", reason = \'" << strerror(errno) << '\'';
3801 throw std::runtime_error(text.str().c_str());
3802 }
3803
3804 // rename temporal file
3805
3806 if (int code = rename(tmp_file_name.c_str(), pf->p_full_name.c_str())) {
3807 std::ostringstream text;
3808 text << "cannot rename file \'" << tmp_file_name << "\' to \'" << pf->p_full_name
3809 << "\': rename() failed with code " << code << ", reason = \'" << strerror(errno) << '\'';
3810 throw std::runtime_error(text.str().c_str());
3811 }
3812
3813 tmp_file_name.erase(0);
3814
3815 if (pf != p_active_data) {
3816 try {
3817 pf->unlock();
3818 } catch (exception& ex) {
3819 throw std::runtime_error(ex.what());
3820 }
3821 }
3822 pf->p_is_updated = false;
3823 pf->update_status_of_file();
3824
3825 // get mode for new file
3826
3827 struct stat buf2;
3828 if (int code = stat(pf->p_full_name.c_str(), &buf2)) {
3829 std::ostringstream text;
3830 text << "cannot get information about file \'" << pf->p_full_name << "\': stat() failed with code " << code
3831 << ", reason = \'" << strerror(errno) << '\'';
3832 throw std::runtime_error(text.str().c_str());
3833 }
3834
3835 // set file's mode if needed
3836
3837 if (buf.st_mode != buf2.st_mode) {
3838 if (int code = chmod(pf->p_full_name.c_str(), buf.st_mode) != 0) {
3839 std::ostringstream text;
3840 text << "cannot set protection mode for file \'" << pf->p_full_name << "\': chmod() failed with code " << code
3841 << ", reason = \'" << strerror(errno) << '\'';
3842 throw std::runtime_error(text.str().c_str());
3843 }
3844 }
3845
3846 // set file's group if needed (in case of problems report error, but do not throw exception)
3847
3848 if (buf.st_gid != buf2.st_gid) {
3849 if (int code = chown(pf->p_full_name.c_str(), (gid_t)(-1), buf.st_gid) != 0) {
3850 ers::warning(kernel::SetGroupIdFailed(ERS_HERE, buf.st_gid, pf->p_full_name.c_str(), code, strerror(errno)));
3851 }
3852 }
3853
3854 }
3855
3856 catch (exception& e) {
3857 if (pf != p_active_data) {
3858 try {
3859 pf->unlock();
3860 } catch (...) {
3861 }
3862 }
3863 if (!tmp_file_name.empty()) {
3864 unlink(tmp_file_name.c_str());
3865 }
3866 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, e);
3867 } catch (std::exception& e) {
3868 if (pf != p_active_data) {
3869 try {
3870 pf->unlock();
3871 } catch (...) {
3872 }
3873 }
3874 if (!tmp_file_name.empty()) {
3875 unlink(tmp_file_name.c_str());
3876 }
3877 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, e.what());
3878 } catch (...) {
3879 if (pf != p_active_data) {
3880 try {
3881 pf->unlock();
3882 } catch (...) {
3883 }
3884 }
3885 if (!tmp_file_name.empty()) {
3886 unlink(tmp_file_name.c_str());
3887 }
3888 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, "unknown");
3889 }
3890
3891 OSK_VERBOSE_REPORT("LEAVE " << fname)
3892}
CanNotWriteToFile(const char *prefix, const char *item, const std::string &name, const exception &reason) noexcept
Definition kernel.hpp:219
const OksObject::Set & objects() const
Get objects.
Definition kernel.hpp:1732
static std::string get_tmp_file(const std::string &file_name)
Generates temporal file name.
Definition kernel.cpp:611
std::map< const std::string *, OksObject *, SortById > SMap
Definition object.hpp:1166
Unknown serialization type<< t,((char) t)) template< typename T > inline std::string datatype_to_string() { return "Unknown";} namespace serialization { template< typename T > struct is_serializable :std::false_type {};enum SerializationType { kMsgPack };inline SerializationType from_string(const std::string s) { if(s=="msgpack") return kMsgPack;throw UnknownSerializationTypeString(ERS_HERE, s);} constexpr uint8_t serialization_type_byte(SerializationType stype) { switch(stype) { case kMsgPack:return 'M';default:throw UnknownSerializationTypeEnum(ERS_HERE);} } constexpr SerializationType DEFAULT_SERIALIZATION_TYPE=kMsgPack;template< class T > std::vector< uint8_t > serialize(const T &obj, SerializationType stype=DEFAULT_SERIALIZATION_TYPE) { switch(stype) { case kMsgPack:{ msgpack::sbuffer buf;msgpack::pack(buf, obj);std::vector< uint8_t > ret(buf.size()+1);ret[0]=serialization_type_byte(stype);std::copy(buf.data(), buf.data()+buf.size(), ret.begin()+1);return ret;} default:throw UnknownSerializationTypeEnum(ERS_HERE);} } template< class T, typename CharType=unsigned char > T deserialize(const std::vector< CharType > &v) { switch(v[0]) { case serialization_type_byte(kMsgPack):{ try { msgpack::object_handle oh=msgpack::unpack(const_cast< char * >(reinterpret_cast< const char * >(v.data()+1)), v.size() - 1,[](msgpack::type::object_type, std::size_t, void *) -> bool

◆ k_save_schema()

void dunedaq::oks::OksKernel::k_save_schema ( OksFile * pf,
bool force = false,
OksFile * fh = 0,
const OksClass::Map * classes = 0 )
private

Definition at line 2403 of file kernel.cpp.

2404{
2405 const char _fname[] = "k_save_schema";
2406 std::string fname = make_fname(_fname, sizeof(_fname) - 1, pf->p_full_name, nullptr, nullptr);
2407
2409 OSK_VERBOSE_REPORT("ENTER " << fname)
2410
2411 std::string tmp_file_name;
2412
2413 if (!fh)
2414 fh = pf;
2415
2416 try {
2417
2418 // lock the file, if it is not locked already
2419
2420 if (pf->is_locked() == false) {
2421 pf->lock();
2422 }
2423
2424 // calculate number of classes, going into the schema file
2425
2426 size_t numberOfClasses = 0;
2427
2428 if (classes) {
2429 numberOfClasses = classes->size();
2430 } else if (!p_classes.empty()) {
2431 for (OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2432 if (i->second->p_file == fh)
2433 numberOfClasses++;
2434 }
2435 }
2436
2437 // create temporal file to store the schema
2438
2439 tmp_file_name = get_tmp_file(pf->p_full_name);
2440
2441 {
2442 std::ofstream f(tmp_file_name.c_str());
2443 f.exceptions(std::ostream::failbit | std::ostream::badbit);
2444
2445 if (!f) {
2446 std::ostringstream text;
2447 text << "cannot create temporal file \'" << tmp_file_name << "\' to save schema";
2448 throw std::runtime_error(text.str().c_str());
2449 } else {
2450 if (!p_silence)
2451 std::cout << "Saving " << numberOfClasses << " classes to schema file \"" << pf->p_full_name << "\"...\n";
2452 }
2453
2454 OksXmlOutputStream xmls(f);
2455
2456 // write oks xml file header
2457
2458 pf->p_number_of_items = numberOfClasses;
2459 pf->p_oks_format = "schema";
2460
2461 pf->write(xmls);
2462
2463 // write oks classes
2464
2465 std::ostringstream errors;
2466 bool found_errors = false;
2467
2468 if (classes) {
2469 for (auto& i : *classes) {
2470 found_errors |= i.second->check_relationships(errors, false);
2471 i.second->save(xmls);
2472 }
2473 } else {
2474 for (auto& i : p_classes) {
2475 if (i.second->p_file == fh) {
2476 found_errors |= i.second->check_relationships(errors, false);
2477 i.second->save(xmls);
2478 }
2479 }
2480 }
2481
2482 if (found_errors) {
2483 kernel::BindError ex(ERS_HERE, errors.str());
2484
2485 if (force == false) {
2486 throw std::runtime_error(ex.what());
2487 } else if (p_silence == false) {
2488 ers::warning(ex);
2489 }
2490 }
2491
2492 // close oks xml file
2493
2494 xmls.put_last_tag("oks-schema", sizeof("oks-schema") - 1);
2495
2496 // flush the buffers
2497
2498 f.close();
2499 }
2500
2501 if (rename(tmp_file_name.c_str(), pf->p_full_name.c_str())) {
2502 std::ostringstream text;
2503 text << "cannot rename \'" << tmp_file_name << "\' to \'" << pf->p_full_name << '\'';
2504 throw std::runtime_error(text.str().c_str());
2505 }
2506
2507 tmp_file_name.erase(0);
2508
2509 if (pf != p_active_schema) {
2510 try {
2511 pf->unlock();
2512 } catch (exception& ex) {
2513 throw std::runtime_error(ex.what());
2514 }
2515 }
2516 pf->p_is_updated = false;
2517 pf->update_status_of_file();
2518
2519 } catch (exception& ex) {
2520 if (pf != p_active_schema) {
2521 try {
2522 pf->unlock();
2523 } catch (...) {
2524 }
2525 }
2526 if (!tmp_file_name.empty()) {
2527 unlink(tmp_file_name.c_str());
2528 }
2529 throw CanNotWriteToFile("k_save_schema", "schema file", pf->p_full_name, ex);
2530 } catch (std::exception& ex) {
2531 if (pf != p_active_schema) {
2532 try {
2533 pf->unlock();
2534 } catch (...) {
2535 }
2536 }
2537 if (!tmp_file_name.empty()) {
2538 unlink(tmp_file_name.c_str());
2539 }
2540 throw CanNotWriteToFile("k_save_schema", "schema file", pf->p_full_name, ex.what());
2541 }
2542
2543 OSK_VERBOSE_REPORT("LEAVE " << fname)
2544}
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1711

◆ k_set_active_data()

void dunedaq::oks::OksKernel::k_set_active_data ( OksFile * fp)

Set active OKS data file.

Non thread-safe version of the set_active_data() method;

Exceptions
Throwoks::exception in case of problems.

Definition at line 4069 of file kernel.cpp.

4070{
4071 TLOG_DEBUG(4) << "enter for file " << (void*)fp;
4072
4073 // check if active data is different from given file
4074
4075 if (p_active_data == fp)
4076 return;
4077
4078 // first unlock current active data
4079
4080 if (p_active_data && p_active_data->is_updated() == false) {
4081 try {
4083 } catch (exception& ex) {
4084 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4085 }
4086 }
4087
4088 // exit, if file is (null)
4089
4090 if (!fp) {
4091 p_active_data = 0;
4092 return;
4093 }
4094
4095 try {
4096 fp->lock();
4097 p_active_data = fp;
4098 } catch (exception& ex) {
4099 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4100 }
4101
4102 TLOG_DEBUG(4) << "leave for file " << (void*)fp;
4103}
CanNotSetActiveFile(const char *item, const std::string &name, const exception &reason) noexcept
Definition kernel.hpp:272
void unlock()
Unlock OKS file.
Definition file.cpp:1110
bool is_updated() const
Return update status of OKS file.
Definition file.hpp:619

◆ k_set_active_schema()

void dunedaq::oks::OksKernel::k_set_active_schema ( OksFile * file_h)

Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.

Exceptions
Throwoks::exception in case of problems.

Definition at line 2706 of file kernel.cpp.

2707{
2708 TLOG_DEBUG(4) << "enter for file " << (void*)f;
2709
2710 // check if active schema is different from given file
2711
2712 if (p_active_schema == f)
2713 return;
2714
2715 // unlock current active schema, if it was saved
2716
2717 if (p_active_schema && p_active_schema->is_updated() == false) {
2718 try {
2720 } catch (exception& ex) {
2721 throw CanNotSetActiveFile("schema", f->get_full_file_name(), ex);
2722 }
2723 }
2724
2725 // exit, if file is (null)
2726
2727 if (!f) {
2728 p_active_schema = 0;
2729 return;
2730 }
2731
2732 try {
2733 f->lock();
2735 } catch (exception& ex) {
2736 throw CanNotSetActiveFile("schema", f->get_full_file_name(), ex);
2737 }
2738
2739 TLOG_DEBUG(4) << "exit for file " << (void*)f;
2740}

◆ load_data()

OksFile * dunedaq::oks::OksKernel::load_data ( const std::string & name,
bool bind = true )

Load OKS data file.

The method loads OKS data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

By default, after the the data file is loaded, the kernel tries to resolve links between objects. This can be rather cpu consuming operation and it is not scalable for sequential load of many files. In this case it is recommended to change the default bind parameter to false for all but last loading data file.

Parameters
namename of the file to be loaded
bindif true (by default), resolve links between objects
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 3347 of file kernel.cpp.

3348{
3349 std::unique_lock lock(p_kernel_mutex);
3350 return k_load_data(short_file_name, bind, 0, 0);
3351}

◆ load_file()

OksFile * dunedaq::oks::OksKernel::load_file ( const std::string & name,
bool bind = true )

Load OKS database file.

The method loads OKS schema or data xml file. It parses the file's xml header to detect the file type and calls appropriate load_schema() or load_data() method.

The method is thread-safe. The user may not have the OKS kernel lock set in the thread which calls this method.

The parameters of the method are:

Parameters
namename of the file to be loaded
bindif true, bind objects after load (applicable to data files only)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 1625 of file kernel.cpp.

1626{
1627 std::unique_lock lock(p_kernel_mutex);
1628 return k_load_file(short_file_name, bind, 0, 0);
1629}

◆ load_schema()

OksFile * dunedaq::oks::OksKernel::load_schema ( const std::string & name,
const OksFile * parent = 0 )

Load OKS schema file.

The method loads OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method parameters are:

Parameters
namename of the file to be loaded
parentdescriptor of the parent file (if defined, the name can be relative to the parent file)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 2129 of file kernel.cpp.

2130{
2131 std::unique_lock lock(p_kernel_mutex);
2132 return k_load_schema(short_file_name, parent_h);
2133}

◆ new_data()

OksFile * dunedaq::oks::OksKernel::new_data ( const std::string & name,
const std::string & logical_name = "",
const std::string & type = "" )

Create OKS data file.

The method creates new OKS data file and makes it active.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method parameters are:

Parameters
namename of the new data file
logical_nameuser-defined logical name of the file (any string passed to the OKS file xml header)
typeuser-defined type of the file (any string passed to the OKS file xml header)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 3500 of file kernel.cpp.

3501{
3502 const char _fname[] = "new_data";
3503 std::string fname = make_fname(_fname, sizeof(_fname) - 1, s, nullptr, nullptr);
3504 OSK_VERBOSE_REPORT("ENTER " << fname)
3505
3506 if (!s.length()) {
3507 throw CanNotOpenFile("new_data", s, "file name is empty");
3508 }
3509
3510 std::string file_name(s);
3511
3512 try {
3513
3514 Oks::substitute_variables(file_name);
3515
3516 test_file_existence(file_name, p_silence, fname, "data");
3517
3518 file_name = get_file_path(s, nullptr, false);
3519
3520 std::unique_lock lock(p_kernel_mutex);
3521
3522 if (find_data_file(file_name) != 0) {
3523 throw std::runtime_error("the file is already loaded");
3524 }
3525
3526 OksFile* file_h = new OksFile(file_name, logical_name, type, "data", this);
3527
3528 file_h->p_short_name = s;
3529
3530 k_set_active_data(file_h);
3531
3533
3534 } catch (exception& e) {
3535 throw CanNotCreateFile("new_data", "data file", file_name, e);
3536 } catch (std::exception& e) {
3537 throw CanNotCreateFile("new_data", "data file", file_name, e.what());
3538 }
3539
3540 OSK_VERBOSE_REPORT("LEAVE " << fname)
3541
3542 return p_active_data;
3543}
CanNotCreateFile(const char *prefix, const char *item, const std::string &name, const exception &reason) noexcept
Definition kernel.hpp:169
void k_set_active_data(OksFile *)
Set active OKS data file.
Definition kernel.cpp:4069
static void test_file_existence(const std::string &file_name, bool silence, const std::string &fname, const char *msg)
Definition kernel.cpp:1455

◆ new_schema()

OksFile * dunedaq::oks::OksKernel::new_schema ( const std::string & name)

Create OKS schema file.

The method creates new OKS schema file and makes it active.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
namename of the new schema file
Returns
Return pointer to the OKS file descriptor
Exceptions
Throwoks::exception in case of problems.

Definition at line 2307 of file kernel.cpp.

2308{
2309 const char _fname[] = "new_schema";
2310 std::string fname = make_fname(_fname, sizeof(_fname) - 1, s, nullptr, nullptr);
2311 OSK_VERBOSE_REPORT("ENTER " << fname)
2312
2313 if (!s.length()) {
2314 throw CanNotOpenFile("new_schema", s, "file name is empty");
2315 }
2316
2317 std::string file_name(s);
2318
2319 try {
2320
2321 Oks::substitute_variables(file_name);
2322
2323 test_file_existence(file_name, p_silence, fname, "schema");
2324
2325 file_name = get_file_path(s, nullptr, false);
2326
2327 std::unique_lock lock(p_kernel_mutex);
2328
2329 if (find_schema_file(file_name) != 0) {
2330 throw std::runtime_error("the file is already loaded");
2331 }
2332
2333 OksFile* file_h = new OksFile(file_name, "", "", "schema", this);
2334
2335 file_h->p_short_name = s;
2336
2337 k_set_active_schema(file_h);
2338
2340
2342
2343 } catch (std::exception& e) {
2344 throw CanNotCreateFile("new_schema", "schema file", file_name, e.what());
2345 } catch (...) {
2346 throw CanNotCreateFile("new_schema", "schema file", file_name, "caught unknown exception");
2347 }
2348
2349 OSK_VERBOSE_REPORT("LEAVE " << fname)
2350
2351 return p_active_schema;
2352}
void k_set_active_schema(OksFile *file_h)
Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.
Definition kernel.cpp:2706

◆ number_of_classes()

size_t dunedaq::oks::OksKernel::number_of_classes ( ) const
inline

Get number of classes.

Returns
The method returns number of classes loaded in-memory.

Definition at line 1719 of file kernel.hpp.

1719{ return p_classes.size(); }

◆ number_of_objects()

size_t dunedaq::oks::OksKernel::number_of_objects ( ) const
inline

Get number of objects.

The method returns number of objects loaded in-memory.

Definition at line 1740 of file kernel.hpp.

1740{ return p_objects.size(); }

◆ objects()

const OksObject::Set & dunedaq::oks::OksKernel::objects ( ) const
inline

Get objects.

In multi-threaded environment to iterate through the set it could be necessary to acquire at least read oks kernel lock before calling the method to be sure that another thread does not modify the set of objects (i.e. destroy or create objects, open or close oks data files).

Returns
The method returns const reference on set of all objects loaded in-memory.

Definition at line 1732 of file kernel.hpp.

1732{ return p_objects; }

◆ read_repository_version()

std::string dunedaq::oks::OksKernel::read_repository_version ( )

Read and return current repository version.

Exceptions
Throwoks::exception in case of problems.

Definition at line 5258 of file kernel.cpp.

5259{
5260 std::unique_lock lock(p_kernel_mutex);
5261
5262 if (OksKernel::get_repository_root().empty())
5263 throw RepositoryOperationFailed("status",
5264 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5265
5266 if (get_user_repository_root().empty())
5268 "status", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5269
5270 std::string cmd("oks-version.sh");
5271
5272 cmd.append(" -u ");
5273 cmd.append(get_user_repository_root());
5274
5275 CommandOutput cmd_out("oks-status", this, cmd);
5276 cmd_out.check_command_status(system(cmd.c_str()));
5277
5278 std::string output = cmd_out.cat2str();
5279
5280 static std::string version_prefix("oks version ");
5281 std::string version = cmd_out.last_str();
5282 std::string::size_type pos = version.find(version_prefix);
5283
5284 if (pos == 0)
5285 p_repository_version = version.substr(version_prefix.size());
5286 else {
5287 std::ostringstream text;
5288 text << "cannot read oks version from oks-version.sh output: \"" << output << '\"';
5289 throw RepositoryOperationFailed("get version", text.str().c_str());
5290 }
5291
5292 return p_repository_version;
5293}

◆ registrate_all_classes()

void dunedaq::oks::OksKernel::registrate_all_classes ( bool skip_registered = false)

The method rebuilds all classes taking into account inheritance.

Parameters
skip_registeredskip registration of already processed classes (used to improve performance)
Exceptions
Throwoks::exception in case of problems.

Definition at line 4271 of file kernel.cpp.

4272{
4273 std::unique_lock lock(p_schema_mutex); // protect schema and all objects from changes
4274
4275 if (size_t num_of_classes = p_classes.size()) {
4276 OksClass** table = new OksClass*[num_of_classes];
4277 size_t array_size =
4278 num_of_classes * sizeof(OksClass*) / sizeof(wchar_t); // is used by wmemset() to init above array with NULLs
4279
4280 OksClass::Map::iterator i = p_classes.begin();
4281 unsigned long idx(0);
4282
4283 for (; i != p_classes.end(); ++i)
4284 i->second->registrate_class(skip_registered);
4285
4286 // create lists of sub-classes
4287 // note: do not use unscalable OksClass::create_sub_classes()
4288 for (i = p_classes.begin(); i != p_classes.end(); ++i) {
4289 OksClass* c(i->second);
4290
4291 if (!c->p_all_sub_classes)
4292 c->p_all_sub_classes = new OksClass::FList();
4293 else
4294 c->p_all_sub_classes->clear();
4295
4296 c->p_id = idx++;
4297 }
4298
4299 for (i = p_classes.begin(); i != p_classes.end(); ++i) {
4300 OksClass* c(i->second);
4301 if (const OksClass::FList* scl = c->p_all_super_classes) {
4302 for (OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
4303 (*j)->p_all_sub_classes->push_back(c);
4304 }
4305 }
4306 }
4307
4309 for (i = p_classes.begin(); i != p_classes.end(); ++i) {
4310 OksClass* c(i->second);
4311 if (!c->get_is_abstract()) {
4312 if (const OksClass::FList* spc = c->all_super_classes()) {
4313 if (!spc->empty()) {
4314 wmemset(reinterpret_cast<wchar_t*>(table), 0, array_size); // [re-]set table by NULLs
4315 for (OksClass::FList::const_iterator j1 = spc->begin(); j1 != spc->end(); ++j1) {
4316 if (const OksClass::FList* sbc = (*j1)->all_sub_classes()) {
4317 for (OksClass::FList::const_iterator j2 = sbc->begin(); j2 != sbc->end(); ++j2) {
4318 OksClass* c2(*j2);
4319 if ((c2 != c) && !c2->get_is_abstract()) {
4320 table[c2->p_id] = c2;
4321 }
4322 }
4323 }
4324 }
4325
4326 unsigned int count(0);
4327 for (unsigned int x = 0; x < num_of_classes; ++x) {
4328 if (table[x])
4329 count++;
4330 }
4331
4332 if (count) {
4333 std::vector<OksClass*>* cih;
4334 if (!c->p_inheritance_hierarchy) {
4335 cih = c->p_inheritance_hierarchy = new std::vector<OksClass*>();
4336 } else {
4337 cih = c->p_inheritance_hierarchy;
4338 cih->clear();
4339 }
4340
4341 cih->reserve(count);
4342
4343 for (unsigned int x = 0; x < num_of_classes; ++x) {
4344 if (table[x])
4345 cih->push_back(table[x]);
4346 }
4347 }
4348 }
4349 }
4350 }
4351 }
4352
4353#ifndef ERS_NO_DEBUG
4354 if (ers::debug_level() >= 2) {
4355 std::ostringstream s;
4356
4357 for (i = p_classes.begin(); i != p_classes.end(); ++i) {
4358 if (std::vector<OksClass*>* cis = i->second->p_inheritance_hierarchy) {
4359 s << " - class \'" << i->second->get_name() << "\' shares IDs with " << cis->size() << " classes: ";
4360 OksClass::Set sorted;
4361 for (std::vector<OksClass*>::const_iterator j = cis->begin(); j != cis->end(); ++j) {
4362 sorted.insert(*j);
4363 }
4364 for (OksClass::Set::const_iterator j = sorted.begin(); j != sorted.end(); ++j) {
4365 if (j != sorted.begin())
4366 s << ", ";
4367 s << '\'' << (*j)->get_name() << '\'';
4368 }
4369 s << std::endl;
4370 }
4371 }
4372
4373 TLOG_DEBUG(2) << "Schema inheritance hierarchy used to test objects with equal IDs:\n" << s.str();
4374 }
4375#endif
4376 }
4377
4378 delete[] table;
4379
4381 }
4382}
std::set< OksClass *, SortByName > Set
Definition class.hpp:243
void k_check_bind_classes_status() const noexcept
Definition kernel.cpp:5459
bool get_test_duplicated_objects_via_inheritance_mode() const
Get status of test inherited duplicated objects mode. The method returns true, if the mode is switche...
Definition kernel.hpp:791
bool get_allow_duplicated_objects_mode() const
Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is swi...
Definition kernel.hpp:768
int debug_level()
Definition ers.hpp:80

◆ reload_data()

void dunedaq::oks::OksKernel::reload_data ( std::set< OksFile * > & files,
bool allow_schema_extension = true )

Reload OKS data files.

The method reloads data files. The non-modified objects are not changed in-memory. The objects which were removed in the file are removed in-memory. New objects created in the file are created in-memory. The values of an object' relationships and attributes changed in the file are changed in memory, the address of such object in-memory is not changed.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method invokes notification on changes if there is an appropriate subscription.

The method parameters are:

Parameters
filesset of pointer to the OKS data file descriptors returned by a kernel method
allow_schema_extensionif true, new schema files can be included in modified data files
Exceptions
Throwoks::exception in case of problems.

Definition at line 3000 of file kernel.cpp.

3001{
3002 std::map<OksFile*, std::vector<std::string>> included;
3003
3004 std::set<OksFile*>::const_iterator i;
3005
3006 bool check_includes(false);
3007 bool found_schema_files(false);
3008 std::string file_names;
3009
3010 std::unique_lock lock(p_kernel_mutex);
3011
3012 for (std::set<OksFile*>::const_iterator fi = files_h.begin(); fi != files_h.end();) {
3013 if (_find_file(p_schema_files, *fi)) {
3014 found_schema_files = true;
3015 } else if (!_find_file(p_data_files, *fi)) {
3016 Oks::error_msg("OksKernel::reload_data")
3017 << "file " << (void*)(*fi) << " is not OKS data or schema file, skip..." << std::endl;
3018 files_h.erase(fi++);
3019 continue;
3020 }
3021
3022 if (fi != files_h.begin())
3023 file_names.append(", ");
3024 file_names.push_back('\"');
3025 file_names.append((*fi)->get_full_file_name());
3026 file_names.push_back('\"');
3027 ++fi;
3028 }
3029
3030 try {
3031
3032 // throw exception on schema_files
3033
3034 if (found_schema_files) {
3035 throw std::runtime_error("Reload of modified schema files is not supported");
3036 }
3037
3038 // exit, if there are no files to reload (e.g. dangling refs.)
3039
3040 if (files_h.empty())
3041 return;
3042
3043 // unlock any locked file
3044 // build container of objects which can be updated (and removed, if not reloaded)
3045
3046 ReloadObjects reload_objects;
3047
3048 for (i = files_h.begin(); i != files_h.end(); ++i) {
3049 if ((*i)->is_locked()) {
3050 if (p_active_data == (*i)) {
3051 p_active_data = 0;
3052 }
3053 (*i)->unlock();
3054 }
3055
3056 for (OksObject::Set::const_iterator oi = p_objects.begin(); oi != p_objects.end(); ++oi) {
3057 if ((*oi)->file == *i)
3058 reload_objects.put(*oi);
3059 }
3060 }
3061
3062 // preload includes of modified files
3063
3064 {
3065 std::set<OksFile*> new_files;
3066
3067 for (i = files_h.begin(); i != files_h.end(); ++i) {
3068 try {
3069 check_includes |= k_preload_includes(*i, new_files, allow_schema_extension);
3070 } catch (...) {
3072 throw;
3073 }
3074 }
3075
3077
3078 if (!new_files.empty()) {
3079 TLOG_DEBUG(2) << new_files.size() << " new files will be loaded";
3080 }
3081
3082 for (i = new_files.begin(); i != new_files.end(); ++i) {
3083 files_h.insert(*i);
3084 }
3085 }
3086
3087 // build list of files to be closed:
3088 // close files which are no more referenced by others
3089 // this may happen if there are changes in the list of includes
3090
3091 std::set<OksFile*> files_to_be_closed;
3092
3093 if (check_includes) {
3094 size_t num_of_closing_files = 0;
3095
3096 while (true) {
3097
3098 // build list of good (i.e. "included") files
3099 // rebuild the list, if at least one file was excluded
3100
3101 std::map<std::string, OksFile*> good_files;
3102
3103 for (OksFile::Map::iterator j = p_data_files.begin(); j != p_data_files.end(); ++j) {
3104 if (files_to_be_closed.find(j->second) == files_to_be_closed.end()) {
3105 for (std::list<std::string>::iterator l = j->second->p_list_of_include_files.begin();
3106 l != j->second->p_list_of_include_files.end();
3107 ++l) {
3108 try {
3109 good_files[get_file_path(*l, j->second)] = j->second;
3110 } catch (...) {
3111 }
3112 }
3113 }
3114 }
3115
3116 for (OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end();) {
3117 if (i->second->p_included_by && files_to_be_closed.find(i->second) == files_to_be_closed.end()) {
3118 TLOG_DEBUG(3) << "check the file \'" << i->second->get_full_file_name() << "\' is included";
3119 const std::string& s = i->second->get_full_file_name();
3120 OksFile* f2 = i->second;
3121 ++i;
3122
3123 f2->p_included_by = 0;
3124
3125 // search for a file which could include given one
3126
3127 std::map<std::string, OksFile*>::const_iterator j = good_files.find(s);
3128
3129 if (j != good_files.end()) {
3130 f2->p_included_by = j->second;
3131 } else {
3132 files_to_be_closed.insert(f2);
3133
3134 for (OksObject::Set::const_iterator oi = p_objects.begin(); oi != p_objects.end(); ++oi) {
3135 if ((*oi)->file == f2) {
3136 reload_objects.put(*oi);
3137 }
3138 }
3139
3140 if (files_h.erase(f2)) {
3141 TLOG_DEBUG(2) << "skip reload of updated file \'" << f2->get_full_file_name()
3142 << " since it will be closed";
3143 }
3144
3145 TLOG_DEBUG(3) << "file \'" << f2->get_full_file_name() << " will be closed";
3146 }
3147 } else {
3148 ++i;
3149 }
3150 }
3151
3152 if (num_of_closing_files == files_to_be_closed.size()) {
3153 break;
3154 } else {
3155 num_of_closing_files = files_to_be_closed.size();
3156 }
3157 }
3158 } else {
3159 TLOG_DEBUG(2) << "no changes in the list of includes";
3160 }
3161
3162 // remove exclusive RCRs (will be restored when read, if object was not changed)
3163
3164 {
3165 for (std::map<const OksClass*, map_str_t<OksObject*>*>::const_iterator cx = reload_objects.data.begin();
3166 cx != reload_objects.data.end();
3167 ++cx) {
3168 const OksClass* c(cx->first);
3169 if (c->p_all_relationships && !c->p_all_relationships->empty()) {
3170 const unsigned int atts_num(c->number_of_all_attributes());
3171 for (map_str_t<OksObject*>::const_iterator j = cx->second->begin(); j != cx->second->end(); ++j) {
3172 OksObject* obj = j->second;
3173 OksData* d(obj->data + atts_num);
3174
3175 for (std::list<OksRelationship*>::iterator i = c->p_all_relationships->begin();
3176 i != c->p_all_relationships->end();
3177 ++i, ++d) {
3178 OksRelationship* r = *i;
3179 if (r->get_is_composite() && r->get_is_exclusive()) {
3180 if (d->type == OksData::object_type && d->data.OBJECT) {
3181 if (!is_dangling(d->data.OBJECT)) {
3182 d->data.OBJECT->remove_RCR(obj, r);
3183 }
3184 } else if (d->type == OksData::list_type && d->data.LIST) {
3185 for (OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
3186 OksData* d2(*i2);
3187 if (d2->type == OksData::object_type && d2->data.OBJECT) {
3188 if (!is_dangling(d2->data.OBJECT)) {
3189 d2->data.OBJECT->remove_RCR(obj, r);
3190 }
3191 }
3192 }
3193 }
3194 }
3195 }
3196 }
3197 }
3198 }
3199 }
3200
3201 // need to allow "duplicated_objects_via_inheritance_mode", since the objects with the same ID can be created and
3202 // removed
3203
3204 bool duplicated_objs_mode = get_test_duplicated_objects_via_inheritance_mode();
3206
3207 // read objects
3208
3209 for (i = files_h.begin(); i != files_h.end(); ++i) {
3210 std::shared_ptr<std::ifstream> f(new std::ifstream((*i)->get_full_file_name().c_str()));
3211
3212 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
3213
3214 OksFile fp(xmls, (*i)->get_short_file_name(), (*i)->get_full_file_name(), this);
3215 char format = (fp.p_oks_format == "data" ? 'n' : ((fp.p_oks_format == "extended") ? 'X' : 'c'));
3216
3217 if (!p_silence) {
3218 std::lock_guard lock(p_parallel_out_mutex);
3219 std::cout << " * reading data file \"" << (*i)->get_full_file_name() << "\"..." << std::endl;
3220 }
3221
3222 {
3223 OksAliasTable alias_table;
3224 ReadFileParams read_params(*i, *xmls, ((format == 'X') ? 0 : &alias_table), this, format, &reload_objects);
3225
3226 try {
3227 while (OksObject::read(read_params)) {
3228 ;
3229 }
3230 } catch (FailedCreateObject& ex) {
3232 throw ex;
3233 }
3234 }
3235
3236 (*i)->update_status_of_file();
3237 (*i)->p_is_updated = false;
3238 }
3239
3241
3242 // remove objects which were not re-read
3243
3244 OksObject::FSet oset;
3245
3246 {
3247 for (std::map<const OksClass*, map_str_t<OksObject*>*>::const_iterator cx = reload_objects.data.begin();
3248 cx != reload_objects.data.end();
3249 ++cx) {
3250 for (map_str_t<OksObject*>::const_iterator ox = cx->second->begin(); ox != cx->second->end(); ++ox) {
3251 oset.insert(ox->second);
3252 }
3253 }
3254
3255#ifndef ERS_NO_DEBUG
3256 if (ers::debug_level() >= 3) {
3257 std::ostringstream text;
3258 text << "there are " << oset.size() << " removed objects:\n";
3259
3260 for (OksObject::FSet::iterator x = oset.begin(); x != oset.end(); ++x) {
3261 text << " - object " << *x << std::endl;
3262 TLOG_DEBUG(3) << text.str();
3263 }
3264 }
3265#endif
3266
3267 {
3268 OksObject::FSet refs;
3269 unbind_all_rels(oset, refs);
3271 for (OksObject::FSet::const_iterator x2 = refs.begin(); x2 != refs.end(); ++x2) {
3272 TLOG_DEBUG(3) << "*** add object " << *x2 << " to the list of updated *** ";
3273 (*p_change_object_notify_fn)(*x2, p_change_object_notify_param);
3274 }
3275 }
3276 }
3277 }
3278
3279 for (OksObject::FSet::iterator ox = oset.begin(); ox != oset.end(); ++ox) {
3280 OksObject* o = *ox;
3281
3282 if (is_dangling(o)) {
3283 TLOG_DEBUG(4) << "skip dangling object " << (void*)o;
3284 continue;
3285 }
3286
3287 TLOG_DEBUG(3) << "*** remove non-reloaded object " << o << " => " << (void*)o << " ***";
3288
3289 delete o;
3290 }
3291
3292 for (std::set<OksFile*>::const_iterator x = files_to_be_closed.begin(); x != files_to_be_closed.end(); ++x) {
3293 k_close_data(*x, true);
3294 }
3295
3297
3298 // check that created objects do not have duplicated IDs within inheritance hierarchy
3299
3300 if (duplicated_objs_mode == true) {
3301 for (auto& o : reload_objects.created) {
3302 o->check_ids();
3303 }
3304 }
3305 } catch (exception& e) {
3306 throw FailedReloadFile(file_names, e);
3307 } catch (std::exception& e) {
3308 throw FailedReloadFile(file_names, e.what());
3309 }
3310}
FailedReloadFile(const std::string &names, const exception &reason) noexcept
Definition kernel.hpp:92
std::map< std::string, T > map_str_t
Definition kernel.hpp:624
void set_test_duplicated_objects_via_inheritance_mode(const bool b)
Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter...
Definition kernel.hpp:782
void unbind_all_rels(const OksObject::FSet &rm_objs, OksObject::FSet &updated) const
Unbind all references on given oks objects. The method unbinds all relationships referencing given ob...
Definition kernel.cpp:4178
std::unordered_set< OksObject *, oks::hash_obj_ptr, oks::equal_obj_ptr > FSet
Definition object.hpp:1171
static OksObject * read(const oks::ReadFileParams &)
Definition object.cpp:357
static bool _find_file(const OksFile::Map &files, const OksFile *f)
Definition kernel.cpp:2954
msgpack::object obj

◆ remove_data_file()

void dunedaq::oks::OksKernel::remove_data_file ( OksFile * f)
private

Definition at line 3558 of file kernel.cpp.

3559{
3560 p_data_files.erase(&f->p_full_name);
3561}

◆ remove_repository_dir()

void dunedaq::oks::OksKernel::remove_repository_dir ( const std::string & dir)

Remove repository search directory.

The method removes from the search list directory with given name. The method is not thread-safe.

Parameters
dirdirectory name (must be fully qualified name)

Definition at line 1292 of file kernel.cpp.

1293{
1294 std::unique_lock lock(p_kernel_mutex);
1295
1296 std::list<std::string>::iterator i = std::find(p_repository_dirs.begin(), p_repository_dirs.end(), dir);
1297 if (i != p_repository_dirs.end()) {
1298 if (p_verbose) {
1299 std::cout << " * remove repository search directory \'" << dir << "\'\n";
1300 }
1301 p_repository_dirs.erase(i);
1302 }
1303}

◆ remove_schema_file()

void dunedaq::oks::OksKernel::remove_schema_file ( OksFile * f)
private

Definition at line 3564 of file kernel.cpp.

3565{
3566 p_schema_files.erase(&f->p_full_name);
3567}

◆ remove_user_repository_dir()

void dunedaq::oks::OksKernel::remove_user_repository_dir ( )
private

Definition at line 4706 of file kernel.cpp.

4707{
4712 }
4713}
static void remove(const std::string &path)
Definition kernel.cpp:81
void erase(const std::string &path)
Definition kernel.cpp:97

◆ reset_cwd()

void dunedaq::oks::OksKernel::reset_cwd ( )
inlinestatic

Reset current working dir in case of chdir() call.

Definition at line 1666 of file kernel.hpp.

1666{ s_cwd = 0; }

◆ restore_preload_file_info()

void dunedaq::oks::OksKernel::restore_preload_file_info ( )
private

Definition at line 3325 of file kernel.cpp.

3326{
3327 for (std::vector<OksFile*>::iterator j = p_preload_added_files.begin(); j != p_preload_added_files.end(); ++j) {
3328 TLOG_DEBUG(1) << "remove file " << (*j)->get_full_file_name();
3329 remove_data_file(*j);
3330 delete *j;
3331 }
3332
3333 for (OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
3334 std::map<const OksFile*, OksFile*>::iterator j = p_preload_file_info.find(i->second);
3335 if (j != p_preload_file_info.end()) {
3336 TLOG_DEBUG(1) << "restore file " << i->second->get_full_file_name();
3337 (*i->second) = (*j->second);
3338 }
3339 }
3340
3342}

◆ save_all_data()

void dunedaq::oks::OksKernel::save_all_data ( bool force_defaults = false)

Save all OKS data files.

The method saves all OKS data files which were created or loaded by the OKS kernel. The files are saved in the same format (extended or compact), in which they were saved last time.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Exceptions
Throwoks::exception in case of problems.

Definition at line 3944 of file kernel.cpp.

3945{
3946 TLOG_DEBUG(4) << "enter";
3947
3948 {
3949 std::shared_lock lock(p_kernel_mutex);
3950
3951 for (OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
3952 if (check_read_only(i->second) == false) {
3953 k_save_data(i->second, false, nullptr, nullptr, force_defaults);
3954 } else {
3955 TLOG_DEBUG(2) << "skip read-only data file \'" << *(i->first) << '\'';
3956 }
3957 }
3958 }
3959
3960 TLOG_DEBUG(4) << "exit";
3961}

◆ save_all_schema()

void dunedaq::oks::OksKernel::save_all_schema ( )

Save all OKS schema files.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method saves all OKS schema files which were created or loaded by the OKS kernel.

Exceptions
Throwoks::exception in case of problems.

Definition at line 2594 of file kernel.cpp.

2595{
2596 OSK_VERBOSE_REPORT("ENTER OksKernel::save_all_schema()")
2597
2598 {
2599 std::shared_lock lock(p_kernel_mutex);
2600
2601 for (OksFile::Map::iterator i = p_schema_files.begin(); i != p_schema_files.end(); ++i) {
2602 if (check_read_only(i->second) == false) {
2603 k_save_schema(i->second);
2604 } else {
2605 TLOG_DEBUG(2) << "skip read-only schema file \'" << *(i->first) << '\'';
2606 }
2607 }
2608 }
2609
2610 OSK_VERBOSE_REPORT("LEAVE OksKernel::save_all_schema()")
2611}

◆ save_as_data()

void dunedaq::oks::OksKernel::save_as_data ( const std::string & new_name,
OksFile * file_h )

Save OKS data file under new name.

The method changes the name of given OKS data file and saves it.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
new_namenew name of the data file
file_ha pointer to the OKS data file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 3906 of file kernel.cpp.

3907{
3908 const char _fname[] = "save_as_data";
3909 std::string fname = make_fname(_fname, sizeof(_fname) - 1, new_name, nullptr, &pf);
3910 OSK_VERBOSE_REPORT("ENTER " << fname)
3911
3912 try {
3913
3914 if (!new_name.length()) {
3915 throw std::runtime_error("the new filename is empty");
3916 }
3917
3918 std::unique_lock lock(p_kernel_mutex);
3919
3920 std::string old_short_name = pf->p_short_name;
3921 std::string old_full_name = pf->p_full_name;
3922 std::string old_format = pf->p_oks_format;
3923
3924 k_rename_data(pf, new_name, new_name);
3925
3926 try {
3927 k_save_data(pf);
3928 } catch (...) {
3929 k_rename_data(pf, old_short_name, old_full_name);
3930 pf->p_oks_format = old_format;
3931 throw;
3932 }
3933
3934 } catch (exception& ex) {
3935 throw CanNotWriteToFile("k_save_as_data", "data file", new_name, ex);
3936 } catch (std::exception& ex) {
3937 throw CanNotWriteToFile("k_save_as_data", "data file", new_name, ex.what());
3938 }
3939
3940 OSK_VERBOSE_REPORT("LEAVE " << fname)
3941}
void k_rename_data(OksFile *, const std::string &short_name, const std::string &long_name)
Definition kernel.cpp:3898

◆ save_as_schema()

void dunedaq::oks::OksKernel::save_as_schema ( const std::string & name,
OksFile * file_h )

Save OKS schema file under new name.

The method changes the name of given OKS schema file and saves it.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
namenew name of the schema file
file_ha pointer to the OKS schema file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 2558 of file kernel.cpp.

2559{
2560 const char _fname[] = "save_as_schema";
2561 std::string fname = make_fname(_fname, sizeof(_fname) - 1, new_name, nullptr, &pf);
2562 OSK_VERBOSE_REPORT("ENTER " << fname)
2563
2564 try {
2565
2566 if (!new_name.length()) {
2567 throw std::runtime_error("the new filename is empty");
2568 }
2569
2570 std::string old_short_name = pf->p_short_name;
2571 std::string old_full_name = pf->p_full_name;
2572
2573 std::unique_lock lock(p_kernel_mutex);
2574
2575 k_rename_schema(pf, new_name, new_name);
2576
2577 try {
2578 k_save_schema(pf);
2579 } catch (...) {
2580 k_rename_schema(pf, old_short_name, old_full_name);
2581 throw;
2582 }
2583
2584 } catch (exception& ex) {
2585 throw CanNotWriteToFile("k_save_as_schema", "schema file", pf->p_full_name, ex);
2586 } catch (std::exception& ex) {
2587 throw CanNotWriteToFile("k_save_as_schema", "schema file", pf->p_full_name, ex.what());
2588 }
2589
2590 OSK_VERBOSE_REPORT("LEAVE " << fname)
2591}
void k_rename_schema(OksFile *, const std::string &short_name, const std::string &long_name)
Definition kernel.cpp:2550

◆ save_data() [1/2]

void dunedaq::oks::OksKernel::save_data ( OksFile * file_h,
bool ignore_bad_objects = false,
OksFile * true_file_h = nullptr,
bool force_defaults = false )

Save OKS data file.

The method saves given OKS data file. By default the format of data file is compact. To save the file in the extended format set parameter extended_format to true.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
ignore_bad_objectssave the file if it has inconsistent objects or misses includes
true_file_ha pointer to the real OKS data file descriptor owning objects (used for backup)
Exceptions
Throwoks::exception in case of problems.

Definition at line 3572 of file kernel.cpp.

3573{
3574 std::shared_lock lock(p_kernel_mutex);
3575 k_save_data(pf, ignoreBadObjects, true_file_h, nullptr, force_defaults);
3576}

◆ save_data() [2/2]

void dunedaq::oks::OksKernel::save_data ( OksFile * file_h,
const OksObject::FSet & objects )

Save objects into given OKS data file.

The method saves explicitly mentioned objects into given OKS data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to an external OKS data file descriptor
objectsset of objects to be saved into this data file
Exceptions
Throwoks::exception in case of problems.

Definition at line 3579 of file kernel.cpp.

3580{
3581 std::shared_lock lock(p_kernel_mutex);
3582 k_save_data(file_h, false, 0, &objects);
3583}

◆ save_schema() [1/2]

void dunedaq::oks::OksKernel::save_schema ( OksFile * file_h,
bool force,
const OksClass::Map & classes )

Save classes into given OKS schema file.

The method saves explicit set of classes into given OKS schema file. This is used to merge schema files by RDB server.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to an external OKS schema file descriptor
forceif true, ignore problems if possible (e.g. dangling references)
classesset of classes to be saved
Exceptions
Throwoks::exception in case of problems.

Definition at line 2364 of file kernel.cpp.

2365{
2366 std::shared_lock lock(p_kernel_mutex);
2367 k_save_schema(file_h, force, 0, &classes);
2368}

◆ save_schema() [2/2]

void dunedaq::oks::OksKernel::save_schema ( OksFile * file_h,
bool force = false,
OksFile * true_file_h = 0 )

Save OKS schema file.

The method saves given OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
forceif true, ignore problems if possible (e.g. dangling references)
true_file_ha pointer to the real OKS data file descriptor owning classes (used for backup)
Exceptions
Throwoks::exception in case of problems.

Definition at line 2357 of file kernel.cpp.

2358{
2359 std::shared_lock lock(p_kernel_mutex);
2360 k_save_schema(pf, force, fh);
2361}

◆ schema_files()

const OksFile::Map & dunedaq::oks::OksKernel::schema_files ( ) const
inline

Get all schema files.

The method returns all schema files which were created or loaded by the OKS kernel.

Returns
Return const reference on map of the OKS schema file descriptors.

The method is thread-safe.

Definition at line 1211 of file kernel.hpp.

1211{ return p_schema_files; }

◆ set_active_data()

void dunedaq::oks::OksKernel::set_active_data ( OksFile * file_h)

Set active OKS data file.

The method makes given OKS data file active. Any created object will go to the active data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 4062 of file kernel.cpp.

4063{
4064 std::unique_lock lock(p_kernel_mutex);
4066}

◆ set_active_schema()

void dunedaq::oks::OksKernel::set_active_schema ( OksFile * file_h)

Set active OKS schema file.

The method makes given OKS schema file active. Any created class will go to the active schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 2699 of file kernel.cpp.

2700{
2701 std::unique_lock lock(p_kernel_mutex);
2703}

◆ set_allow_duplicated_classes_mode()

void dunedaq::oks::OksKernel::set_allow_duplicated_classes_mode ( const bool b)
inline

Set status of duplicated classes mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The duplicated classes mode can also be switched 'On' using the "OKS_KERNEL_ALLOW_DUPLICATED_CLASSES" environment variable set to any value except 'no'.

Definition at line 802 of file kernel.hpp.

◆ set_allow_duplicated_objects_mode()

void dunedaq::oks::OksKernel::set_allow_duplicated_objects_mode ( const bool b)
inline

Set status of duplicated objects mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The duplicated objects mode can also be switched 'On' using the "OKS_KERNEL_ALLOW_DUPLICATED_OBJECTS" environment variable set to any value except 'no'.

Definition at line 813 of file kernel.hpp.

◆ set_profiling_mode()

void dunedaq::oks::OksKernel::set_profiling_mode ( const bool b)

Set status of profiling mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The profiling mode can also be switched 'On' using the "OKS_KERNEL_PROFILING" environment variable set to any value except 'no'.

Definition at line 1306 of file kernel.cpp.

1307{
1308 if (p_profiling == b)
1309 return;
1310
1311 p_profiling = b;
1312
1313#ifndef ERS_NO_DEBUG
1314 if (p_profiling == true) {
1315 if (!profiler)
1316 profiler = new OksProfiler();
1317 } else {
1318 if (profiler) {
1319 delete profiler;
1320 profiler = 0;
1321 }
1322 }
1323#endif
1324}

◆ set_silence_mode()

void dunedaq::oks::OksKernel::set_silence_mode ( const bool b)
inline

Set status of silence mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The silence mode can also be switched 'On' using the "OKS_KERNEL_SILENCE" environment variable set to any value except 'no'.

Definition at line 730 of file kernel.hpp.

730{ p_silence = b; }

◆ set_skip_string_range()

void dunedaq::oks::OksKernel::set_skip_string_range ( const bool b)
inlinestatic

Set status of string range validator. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' (i.e. to bypass the test) or 'false' to switch 'Off' (i.e. to force the test).

The skip max length check mode can also be switched 'On' using the "OKS_KERNEL_SKIP_STRING_RANGE" environment variable set to any value except 'no'.

Definition at line 834 of file kernel.hpp.

834{ p_skip_string_range = b; }

◆ set_test_duplicated_objects_via_inheritance_mode()

void dunedaq::oks::OksKernel::set_test_duplicated_objects_via_inheritance_mode ( const bool b)
inline

Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

When the mode is switched 'On', the OKS kernel does not allow objects with equal IDs withing the same class inheritance hierarchy.

The test inherited duplicated objects mode can also be switched 'On' using the "OKS_KERNEL_TEST_DUPLICATED_OBJECTS_VIA_INHERITANCE" environment variable set to any value except 'no'.

Definition at line 782 of file kernel.hpp.

◆ set_use_strict_repository_paths()

void dunedaq::oks::OksKernel::set_use_strict_repository_paths ( bool flag)
inlinestatic

Set flag to use strict-repository-paths check.

Definition at line 1672 of file kernel.hpp.

◆ set_user_repository_root()

void dunedaq::oks::OksKernel::set_user_repository_root ( const std::string & path,
const std::string & version = "" )

Set user OKS repository root.

Used by OKS and RDB tools only!

Definition at line 353 of file kernel.cpp.

354{
355 if (get_repository_root().empty()) {
356 TLOG_DEBUG(1) << "Failed to set user-repository-root:\n\tcaused by: repository-root is not set";
358 return;
359 }
360
361 if (path.empty()) {
363 return;
364 }
365
366 std::string s;
367 s = path;
368
369 try {
370 Oks::real_path(s, false);
371 } catch (exception& ex) {
372 TLOG_DEBUG(1) << "Failed to set user-repository-root = \'" << s << "\':\n\tcaused by: " << ex.what();
373 }
374
375 for (std::string::size_type idx = s.size() - 1; idx > 0 && s[idx] == '/'; idx--) {
376 s.erase(idx);
377 }
378
379 p_allow_repository = true;
380
383
384 // is used for backup restore by RDB
385 if (!version.empty())
387}

◆ set_verbose_mode()

void dunedaq::oks::OksKernel::set_verbose_mode ( const bool b)
inline

Set status of verbose mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The verbose mode can also be switched 'On' using the "OKS_KERNEL_VERBOSE" environment variable set to any value except 'no'.

Definition at line 711 of file kernel.hpp.

711{ p_verbose = b; }

◆ subscribe_change_class()

void dunedaq::oks::OksKernel::subscribe_change_class ( void(* f )(OksClass *, OksClass::ChangeType, const void *))
inline

Subscribe on class changing.

The method subscribes user-provided callback function on changes of existing oks class. The callback function is called when a class is changed and its arguments are the pointer to the changed class, the type of change and the change parameter.

Parameters
fuser callback function

Definition at line 2137 of file kernel.hpp.

2138{
2140}

◆ subscribe_change_object()

void dunedaq::oks::OksKernel::subscribe_change_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object changing.

The method subscribes user-provided callback function on changing of existing oks object. The callback function is called when an object is changed.

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Definition at line 2117 of file kernel.hpp.

◆ subscribe_create_class()

void dunedaq::oks::OksKernel::subscribe_create_class ( void(* f )(OksClass *))
inline

Subscribe on class creation.

The method subscribes user-provided callback function on creation of new oks class. The callback function is called when a new class is created and its argument is the pointer to the new class.

Parameters
fuser callback function

Definition at line 2131 of file kernel.hpp.

2132{
2134}

◆ subscribe_create_object()

void dunedaq::oks::OksKernel::subscribe_create_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object creation.

The method subscribes user-provided callback function on creation of new oks object. The callback function is called when a new object is created (except when it is read from file using load_data() method).

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Inline methods for class OksKernel

Definition at line 2110 of file kernel.hpp.

◆ subscribe_delete_class()

void dunedaq::oks::OksKernel::subscribe_delete_class ( void(* f )(OksClass *))
inline

Subscribe on class destroying.

The method subscribes user-provided callback function on destroying of existing oks class. The callback function is called when a class is destroying (e.g. schema file containing the class is closed) and its argument is the pointer to the destroying class.

Parameters
fuser callback function

Definition at line 2143 of file kernel.hpp.

2144{
2146}

◆ subscribe_delete_object()

void dunedaq::oks::OksKernel::subscribe_delete_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object deleting.

The method subscribes user-provided callback function on destroying of existing oks object. The callback function is called when an object is destroying (e.g. data file containing the object is closed) and its argument is the pointer to the destroying object.

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Definition at line 2124 of file kernel.hpp.

◆ tag_repository()

void dunedaq::oks::OksKernel::tag_repository ( const std::string & tag)

Tag current state of repository.

The method assigns a tag to current state of repository.

Parameters
tagthe tag
Exceptions
Throwoks::exception in case of problems.

Definition at line 4975 of file kernel.cpp.

4976{
4977 std::unique_lock lock(p_kernel_mutex);
4978
4979 if (OksKernel::get_repository_root().empty())
4980 throw RepositoryOperationFailed("tag",
4981 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4982
4983 if (get_user_repository_root().empty())
4985 "tag", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4986
4987 std::string cmd("oks-tag.sh");
4988
4989 if (get_verbose_mode())
4990 cmd.append(" -v");
4991
4992 cmd.append(" -u ");
4993 cmd.append(get_user_repository_root());
4994
4995 if (tag.empty() || std::all_of(tag.begin(), tag.end(), [](char c) { return std::isspace(c); }))
4996 throw RepositoryOperationFailed("tag", "the tag may not be empty");
4997
4998 cmd.append(" -t \'");
4999 cmd.append(tag);
5000 cmd.append("\' -c \'");
5001 cmd.append(get_repository_version());
5002 cmd.push_back('\'');
5003
5004 auto start_usage = std::chrono::steady_clock::now();
5005
5006 if (!p_silence) {
5007 std::lock_guard lock(p_parallel_out_mutex);
5008 log_timestamp() << "[OKS tag] => " << cmd << std::endl;
5009 }
5010
5011 CommandOutput cmd_out("oks-tag", this, cmd);
5012 cmd_out.check_command_status(system(cmd.c_str()));
5013
5014 if (!p_silence) {
5015 std::lock_guard lock(p_parallel_out_mutex);
5016 std::cout << cmd_out.cat2str();
5018 << "[OKS tag] => done in "
5019 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
5020 1000.
5021 << " ms" << std::endl;
5022 }
5023}

◆ test_parent()

bool dunedaq::oks::OksKernel::test_parent ( OksFile * file,
OksFile::IMap::iterator & i )
private

Definition at line 1782 of file kernel.cpp.

1783{
1784 OksFile* parent(i->first);
1785 OksFile::Set& includes(i->second);
1786
1787 if (includes.find(file) != includes.end()) {
1788 if (file->p_included_by != parent) {
1789 TLOG_DEBUG(1) << "new parent of file " << file->get_full_file_name() << " is " << parent->get_full_file_name();
1790 file->p_included_by = parent;
1791 }
1792
1793 return true;
1794 }
1795
1796 return false;
1797}
std::unordered_set< OksFile *, oks::hash_file_ptr, oks::equal_file_ptr > Set
Definition file.hpp:384

◆ unbind_all_rels()

void dunedaq::oks::OksKernel::unbind_all_rels ( const OksObject::FSet & rm_objs,
OksObject::FSet & updated ) const
private

Unbind all references on given oks objects. The method unbinds all relationships referencing given objects.

Parameters
rm_objsobjects to be destroyed
updatedreturn updated objects (i.e. containing unbind references)

Definition at line 4178 of file kernel.cpp.

4179{
4180 const OksClass::Map& all_classes(classes());
4181
4182 for (OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
4183 OksClass* c(i->second);
4184 if (const OksObject::Map* objs = i->second->objects()) {
4185 for (OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
4186 OksObject* o(j->second);
4187 unsigned short l1 = c->number_of_all_attributes();
4188 unsigned short l2 = l1 + c->number_of_all_relationships();
4189
4190 while (l1 < l2) {
4191 OksDataInfo odi(l1, (OksRelationship*)0);
4192 OksData* d(o->GetRelationshipValue(&odi));
4193
4194 if (d->type == OksData::object_type) {
4195 if (rm_objs.find(d->data.OBJECT) != rm_objs.end()) {
4196 updated.insert(o);
4197 const OksClass* __c(d->data.OBJECT->GetClass());
4198 const OksString& __id(d->data.OBJECT->GetId());
4199 d->Set(__c, __id);
4200 TLOG_DEBUG(5) << "set relationship of " << o << ": " << *d;
4201 }
4202 } else if (d->type == OksData::list_type) {
4203 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
4204 OksData* lid(*li);
4205 if (lid->type == OksData::object_type) {
4206 if (rm_objs.find(lid->data.OBJECT) != rm_objs.end()) {
4207 updated.insert(o);
4208 const OksClass* __c(lid->data.OBJECT->GetClass());
4209 const OksString& __id(lid->data.OBJECT->GetId());
4210 lid->Set(__c, __id);
4211 TLOG_DEBUG(5) << "set relationship of " << o << ": " << *d;
4212 }
4213 }
4214 }
4215 }
4216 ++l1;
4217 }
4218 }
4219 }
4220 }
4221}
std::map< const char *, OksClass *, SortStr > Map
Definition class.hpp:252

◆ undefine()

void dunedaq::oks::OksKernel::undefine ( OksObject * o)
inlineprivate

Definition at line 2080 of file kernel.hpp.

2081 {
2082 if (!p_objects.empty()) {
2083 std::lock_guard lock(p_objects_mutex);
2084 p_objects.erase(o);
2085 }
2086 }

◆ unset_repository_created()

void dunedaq::oks::OksKernel::unset_repository_created ( )

Set repository created flag to false to avoid created repository removal in destructor;.

Definition at line 4716 of file kernel.cpp.

◆ update_repository() [1/2]

void dunedaq::oks::OksKernel::update_repository ( const std::string & hash_val,
RepositoryUpdateType update_type )
inline

Update user repository files from origin by hash.

The method performs GIT update of files in local user directory.

Parameters
hash_valSHA or "origin/master"
update_typeaction in case of conflicts (discard changes, try to merge changes, cancel)
Exceptions
Throwoks::exception in case of problems.

Definition at line 1573 of file kernel.hpp.

1574 {
1575 update_repository("hash", hash_val, update_type);
1576 }
void update_repository(const std::string &hash_val, RepositoryUpdateType update_type)
Update user repository files from origin by hash.
Definition kernel.hpp:1573

◆ update_repository() [2/2]

void dunedaq::oks::OksKernel::update_repository ( const std::string & param,
const std::string & val,
RepositoryUpdateType update_type )

Update user repository files from origin.

The method performs GIT update of files in local user directory. Pass parameters to the oks-git-update.sh script.

Parameters
param"tag", "date" or "hash"
valSHA or "origin/master"
update_typeaction in case of conflicts (discard changes, try to merge changes, cancel)
Exceptions
Throwoks::exception in case of problems.

Definition at line 4761 of file kernel.cpp.

4762{
4763 std::unique_lock lock(p_kernel_mutex);
4764
4765 if (OksKernel::get_repository_root().empty())
4766 throw RepositoryOperationFailed("update",
4767 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4768
4769 if (get_user_repository_root().empty())
4771 "update", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4772
4773 std::string cmd("oks-update.sh");
4774
4775 if (get_verbose_mode())
4776 cmd.append(" -v");
4777
4778 cmd.append(" -u ");
4779 cmd.append(get_user_repository_root());
4780
4781 if (update_type == OksKernel::DiscardChanges)
4782 cmd.append(" --force");
4783 else if (update_type == OksKernel::MergeChanges)
4784 cmd.append(" --merge");
4785
4786 if (!param.empty()) {
4787 cmd.append(" --");
4788 cmd.append(param);
4789 cmd.push_back(' ');
4790 cmd.push_back('\"');
4791 cmd.append(val);
4792 cmd.push_back('\"');
4793 }
4794
4795 auto start_usage = std::chrono::steady_clock::now();
4796
4797 if (!p_silence) {
4798 std::lock_guard lock(p_parallel_out_mutex);
4799 log_timestamp() << "[OKS update] => " << cmd << std::endl;
4800 }
4801
4802 CommandOutput cmd_out("oks-update", this, cmd);
4803 cmd_out.check_command_status(system(cmd.c_str()));
4804
4805 p_repository_update_ts = std::time(0);
4806
4807 static std::string version_prefix("update oks version ");
4808 std::string version = cmd_out.last_str();
4809 std::string::size_type pos = version.find(version_prefix);
4810
4811 if (pos == 0)
4812 p_repository_version = version.substr(version_prefix.size());
4813 else
4814 throw RepositoryOperationFailed("commit", "cannot read oks version");
4815
4816 if (!p_silence) {
4817 std::lock_guard lock(p_parallel_out_mutex);
4818 std::cout << cmd_out.cat2str();
4820 << "[OKS update] => done in "
4821 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4822 1000.
4823 << " ms" << std::endl;
4824 }
4825}

◆ OksClass

friend class OksClass
friend

Definition at line 618 of file kernel.hpp.

◆ OksData

friend struct OksData
friend

Definition at line 621 of file kernel.hpp.

◆ OksFile

friend class OksFile
friend

Definition at line 617 of file kernel.hpp.

◆ OksLoadObjectsJob

friend struct OksLoadObjectsJob
friend

Definition at line 620 of file kernel.hpp.

◆ OksObject

friend class OksObject
friend

Definition at line 619 of file kernel.hpp.

◆ operator<<

std::ostream & operator<< ( std::ostream & s,
OksKernel & k )
friend

Definition at line 1358 of file kernel.cpp.

1360{
1362
1363 s << "OKS KERNEL DUMP:\n" << "OKS VERSION: " << k.GetVersion() << std::endl;
1364
1365 if (!k.p_schema_files.empty()) {
1366 s << " Loaded schema:\n";
1367
1368 for (const auto& i : k.p_schema_files)
1369 s << " " << i.second->get_full_file_name() << std::endl;
1370
1371 if (!k.p_data_files.empty()) {
1372 s << " Loaded data:\n";
1373
1374 for (const auto& j : k.p_data_files)
1375 s << " " << j.second->get_full_file_name() << std::endl;
1376 } else
1377 s << " No loaded data files\n";
1378
1379 if (!k.p_classes.empty()) {
1380 s << " The classes:\n";
1381
1382 for (const auto& j : k.p_classes)
1383 s << *j.second;
1384 }
1385 } else
1386 s << " No loaded schema files\n";
1387
1388 s << "END OF OKS KERNEL DUMP.\n";
1389
1390 return s;
1391}

Member Data Documentation

◆ p_active_data

OksFile* dunedaq::oks::OksKernel::p_active_data
private

Definition at line 1977 of file kernel.hpp.

◆ p_active_schema

OksFile* dunedaq::oks::OksKernel::p_active_schema
private

Definition at line 1976 of file kernel.hpp.

◆ p_allow_duplicated_classes

bool dunedaq::oks::OksKernel::p_allow_duplicated_classes
private

Definition at line 1947 of file kernel.hpp.

◆ p_allow_duplicated_objects

bool dunedaq::oks::OksKernel::p_allow_duplicated_objects
private

Definition at line 1948 of file kernel.hpp.

◆ p_allow_repository

bool dunedaq::oks::OksKernel::p_allow_repository
private

Definition at line 1946 of file kernel.hpp.

◆ p_bind_classes_status

std::string dunedaq::oks::OksKernel::p_bind_classes_status
mutableprivate

Definition at line 1998 of file kernel.hpp.

◆ p_bind_objects_status

std::string dunedaq::oks::OksKernel::p_bind_objects_status
private

Definition at line 1997 of file kernel.hpp.

◆ p_change_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_change_object_notify_fn
private

Definition at line 2098 of file kernel.hpp.

◆ p_change_object_notify_param

void* dunedaq::oks::OksKernel::p_change_object_notify_param
private

Definition at line 2099 of file kernel.hpp.

◆ p_classes

OksClass::Map dunedaq::oks::OksKernel::p_classes
private

Definition at line 1987 of file kernel.hpp.

◆ p_close_all

bool dunedaq::oks::OksKernel::p_close_all
private

Definition at line 1979 of file kernel.hpp.

◆ p_count

unsigned long dunedaq::oks::OksKernel::p_count = 0
staticprivate

Definition at line 1989 of file kernel.hpp.

◆ p_create_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_create_object_notify_fn
private

Definition at line 2095 of file kernel.hpp.

◆ p_create_object_notify_param

void* dunedaq::oks::OksKernel::p_create_object_notify_param
private

Definition at line 2096 of file kernel.hpp.

◆ p_data_files

OksFile::Map dunedaq::oks::OksKernel::p_data_files
private

Definition at line 1974 of file kernel.hpp.

◆ p_delete_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_delete_object_notify_fn
private

Definition at line 2101 of file kernel.hpp.

◆ p_delete_object_notify_param

void* dunedaq::oks::OksKernel::p_delete_object_notify_param
private

Definition at line 2102 of file kernel.hpp.

◆ p_kernel_mutex

std::shared_mutex dunedaq::oks::OksKernel::p_kernel_mutex
mutableprivate

Definition at line 1965 of file kernel.hpp.

◆ p_load_errors

LoadErrors dunedaq::oks::OksKernel::p_load_errors
private

Definition at line 2000 of file kernel.hpp.

◆ p_objects

OksObject::Set dunedaq::oks::OksKernel::p_objects
private

Definition at line 1993 of file kernel.hpp.

◆ p_objects_mutex

std::mutex dunedaq::oks::OksKernel::p_objects_mutex
mutableprivate

Definition at line 1966 of file kernel.hpp.

◆ p_objects_refs_mutex

std::mutex dunedaq::oks::OksKernel::p_objects_refs_mutex
private

Definition at line 1967 of file kernel.hpp.

◆ p_parallel_out_mutex

std::mutex dunedaq::oks::OksKernel::p_parallel_out_mutex
staticprivate

Definition at line 1969 of file kernel.hpp.

◆ p_preload_added_files

std::vector<OksFile*> dunedaq::oks::OksKernel::p_preload_added_files
private

Definition at line 2003 of file kernel.hpp.

◆ p_preload_file_info

std::map<const OksFile*, OksFile*> dunedaq::oks::OksKernel::p_preload_file_info
private

Definition at line 2002 of file kernel.hpp.

◆ p_profiling

bool dunedaq::oks::OksKernel::p_profiling
private

Definition at line 1945 of file kernel.hpp.

◆ p_repository_checkout_ts

std::time_t dunedaq::oks::OksKernel::p_repository_checkout_ts
private

Definition at line 1960 of file kernel.hpp.

◆ p_repository_dirs

std::list<std::string> dunedaq::oks::OksKernel::p_repository_dirs
private

Definition at line 1983 of file kernel.hpp.

◆ p_repository_mapping_dir

std::string dunedaq::oks::OksKernel::p_repository_mapping_dir
staticprivate

Definition at line 1955 of file kernel.hpp.

◆ p_repository_root

std::string dunedaq::oks::OksKernel::p_repository_root
staticprivate

Definition at line 1954 of file kernel.hpp.

◆ p_repository_update_ts

std::time_t dunedaq::oks::OksKernel::p_repository_update_ts
private

Definition at line 1961 of file kernel.hpp.

◆ p_repository_version

std::string dunedaq::oks::OksKernel::p_repository_version
private

Definition at line 1959 of file kernel.hpp.

◆ p_schema_files

OksFile::Map dunedaq::oks::OksKernel::p_schema_files
private

Definition at line 1973 of file kernel.hpp.

◆ p_schema_mutex

std::shared_mutex dunedaq::oks::OksKernel::p_schema_mutex
private

Definition at line 1968 of file kernel.hpp.

◆ p_silence

bool dunedaq::oks::OksKernel::p_silence
private

Definition at line 1943 of file kernel.hpp.

◆ p_skip_string_range

bool dunedaq::oks::OksKernel::p_skip_string_range = false
staticprivate

Definition at line 1951 of file kernel.hpp.

◆ p_test_duplicated_objects_via_inheritance

bool dunedaq::oks::OksKernel::p_test_duplicated_objects_via_inheritance
private

Definition at line 1949 of file kernel.hpp.

◆ p_threads_pool_size

int dunedaq::oks::OksKernel::p_threads_pool_size = 0
staticprivate

Definition at line 1995 of file kernel.hpp.

◆ p_use_strict_repository_paths

bool dunedaq::oks::OksKernel::p_use_strict_repository_paths = true
staticprivate

Definition at line 1952 of file kernel.hpp.

◆ p_user_repository_root

std::string dunedaq::oks::OksKernel::p_user_repository_root
private

Definition at line 1956 of file kernel.hpp.

◆ p_user_repository_root_created

bool dunedaq::oks::OksKernel::p_user_repository_root_created
private

Definition at line 1958 of file kernel.hpp.

◆ p_user_repository_root_inited

bool dunedaq::oks::OksKernel::p_user_repository_root_inited
private

Definition at line 1957 of file kernel.hpp.

◆ p_verbose

bool dunedaq::oks::OksKernel::p_verbose
private

Definition at line 1944 of file kernel.hpp.

◆ profiler

OksProfiler* dunedaq::oks::OksKernel::profiler
private

Definition at line 1991 of file kernel.hpp.

◆ s_cwd

char * dunedaq::oks::OksKernel::s_cwd = nullptr
staticprivate

Definition at line 1985 of file kernel.hpp.


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