123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- // snfGBUdbmgr.cpp
- // Copyright (C) 2006 - 2020 ARM Research Labs, LLC.
- // See www.armresearch.com for the copyright terms.
- //
- // See snfGBUdbmgr.hpp for details.
-
- #include "snfGBUdbmgr.hpp"
- #include <unistd.h>
-
- namespace cd = codedweller;
-
- const cd::ThreadType snfGBUdbmgr::Type("snfGBUdbmgr"); // The thread's type.
-
- snfGBUdbmgr::snfGBUdbmgr() : // Clean init and start thread.
- Thread(snfGBUdbmgr::Type, "GBUdb Manager"), // XCI Manager type and Name.
- MyGBUdb(NULL), // NULL our links to avoid
- MyLOGmgr(NULL), // any errors when the thread starts.
- Configured(false), // Not configured yet.
- TimeToStop(false), // It is not time to stop ;-)
- CondenseGuardTime(600000), // 10 minute guard time by default.
- TimeTriggerOnOff(true), // By default, condense once per day.
- TimeTrigger(86400000),
- PostsTriggerOnOff(false), // By default do not trigger on posts.
- PostsTriggerValue(262144), // but if we do, use a quarter million.
- RecordsTriggerOnOff(false), // By default do not trigger on records.
- RecordsTriggerValue(150000), // but if we do, use 150K.
- SizeTriggerOnOff(true), // By default trigger on size as a
- SizeTriggerValue(150), // safety valve at 150Mbytes.
- CheckpointOnOff(true), // By default save a snapshot once
- CheckpointTrigger(3600000) { // every hour.
- run(); // Start our thread.
- }
-
- snfGBUdbmgr::~snfGBUdbmgr() { // Clean shutdown & stop thread.
- stop(); // Stop the thread if it's not already.
- MyGBUdb = NULL; // NULL our links and false our
- MyLOGmgr = NULL; // configuration for safety.
- Configured = false;
- }
-
- void snfGBUdbmgr::linkGBUdb(GBUdb& G) { // Connect to our GBUdb
- cd::ScopeMutex JustMe(MyMutex); // Lock for the config change.
- MyGBUdb = &G; // Set the new link.
- }
-
- void snfGBUdbmgr::linkLOGmgr(snfLOGmgr& L) { // Connect to our LOGmgr
- cd::ScopeMutex JustMe(MyMutex); // Lock for the config change.
- MyLOGmgr = &L; // Set the new link.
- }
-
- const int SECsASms = 1000; // How to convert seconds to milliseconds.
- cd::msclock toDuration(int Configuration_Integer) { // Convert int Seconds to timer duration.
- return (Configuration_Integer * SECsASms); // Do the math and send it back.
- }
-
- void snfGBUdbmgr::configure(snfCFGData& CFGData) { // Establish or change our CFG.
- cd::ScopeMutex JustMe(MyMutex); // Only when we're not busy.
-
- // Set up our configuration from the CFGData provided.
-
- // Being careful not to muck with running timers unless their
- // configuration values have actually changed...
-
- if(CondenseGuardTime.getDuration() != // If the condensation guard time is
- toDuration(CFGData.gbudb_database_condense_minimum_seconds_between)) { // new and different then set the
- CondenseGuardTime.setDuration( // condensation guard timer to the
- toDuration(CFGData.gbudb_database_condense_minimum_seconds_between) // new value.
- );
- }
-
- TimeTriggerOnOff = CFGData.gbudb_database_condense_time_trigger_on_off; // Time-Trigger On?
-
- if(TimeTrigger.getDuration() != // Time-Trigger different?
- toDuration(CFGData.gbudb_database_condense_time_trigger_seconds)) {
- TimeTrigger.setDuration( // If it is then adopt the new value.
- toDuration(CFGData.gbudb_database_condense_time_trigger_seconds)
- );
- }
-
- PostsTriggerOnOff = CFGData.gbudb_database_condense_posts_trigger_on_off; // Posts trigger on?
- PostsTriggerValue = CFGData.gbudb_database_condense_posts_trigger_posts; // What is the posts trigger threshold?
-
- RecordsTriggerOnOff = CFGData.gbudb_database_condense_records_trigger_on_off; // Records trigger on?
- RecordsTriggerValue = CFGData.gbudb_database_condense_records_trigger_records; // What is the records trigger threshold?
-
- SizeTriggerOnOff = CFGData.gbudb_database_condense_size_trigger_on_off; // Size trigger on?
- SizeTriggerValue = CFGData.gbudb_database_condense_size_trigger_megabytes; // What is the size trigger threshold?
-
- // Checkpoint
-
- CheckpointOnOff = CFGData.gbudb_database_checkpoint_on_off; // Checkpoint on?
-
- if(CheckpointTrigger.getDuration() != // If the Checkpoint time is
- toDuration(CFGData.gbudb_database_checkpoint_secs)) { // new and different then
- CheckpointTrigger.setDuration( // adopt the new value.
- toDuration(CFGData.gbudb_database_checkpoint_secs)
- );
- }
-
- // GBUdb file name
-
- std::string GBUdbFileName; // Formulate the correct GBUdb file name
- GBUdbFileName = CFGData.paths_workspace_path + // using the CFGData.
- CFGData.node_licenseid + ".gbx";
-
- if( // If the file name for our GBUdb
- NULL == (*MyGBUdb).FileName() || // is not yet set, or
- 0 != GBUdbFileName.compare((*MyGBUdb).FileName()) // if it is different than the
- ) { // formulated file name we have then
- (*MyGBUdb).FileName(GBUdbFileName.c_str()); // set the GBUdb file name.
- }
-
- // Safety check to set the Configured bit.
-
- if(NULL != MyGBUdb && NULL != MyLOGmgr) { // If we have all of our parts
- Configured = true; // then set our configured flag.
- } else { // If anything is missing then
- Configured = false; // make sure the flag is false.
- }
- }
-
- //// The snfGBUdbmgr::load() method isn't exactly what you would expect. It
- // will load the rulebase file if that file exists, but if not it does nothing.
- // The intention is that a new GBUdb will alread have been created. If a
- // pre-existing GBUdb is available then that one will be loaded for use. If
- // it does not exist, then the new, empty GBUdb will be used instead and will
- // eventually be saved for later re-use.
-
- void snfGBUdbmgr::load() { // Load the GBUdb as configured.
- cd::ScopeMutex JustMe(MyMutex); // Just me while I do this.
- if( // Perform some sanity checks.
- NULL != MyGBUdb && // If we have a GBUdb and
- 0 < std::string(MyGBUdb->FileName()).length() && // it has a file name and
- 0 == access(MyGBUdb->FileName(),R_OK) // the file can be accessed
- ) { // then we can proceed:
- MyGBUdb->load(); // Load the GBUdb from disk.
- } // If that didn't work we'll assume
- } // we're starting up a new gbx file ;-)
-
- // DoMaintenanceWork encapsulates all of our maintenance functions. It runs
- // with the mutex locked so that the configuration is stable during each pass.
-
- void snfGBUdbmgr::DoMaintenanceWork() { // Do our watchdog work.
-
- if(!Configured) return; // Do nothing if we're not configured.
-
- cd::ScopeMutex JustMe(MyMutex); // No CFG changes while I'm busy.
-
- if(CondenseGuardTime.isExpired()) { // If we are allowed to condense
- bool CondenseTriggered = false; // check to see if we should.
-
- // time-trigger
-
- if(
- TimeTriggerOnOff && // If the time-trigger is on
- TimeTrigger.isExpired() // and the time has expired
- ) { // then it is time to condense.
- CondenseTriggered = true; // Set the condense flag and
- TimeTrigger.restart(); // restart the timer.
- }
-
- // posts-trigger
-
- if(
- PostsTriggerOnOff && // If posts-trigger is on
- (*MyGBUdb).Posts() >= PostsTriggerValue // and the Posts() count is high
- ) { // enough then trigger the
- CondenseTriggered = true; // condense operation.
- }
-
- // records-trigger
-
- if(
- RecordsTriggerOnOff && // If records-trigger is on
- (*MyGBUdb).IPCount() >= RecordsTriggerValue // and the number of IPs is high
- ) { // enough then trigger the
- CondenseTriggered = true; // condense operation.
- }
-
- // size-trigger
-
- const int MByte = 1048576; // How big is a megabyte anyway?
-
- if(
- SizeTriggerOnOff && // If size-trigger is on
- ((*MyGBUdb).Size()/MByte) >= SizeTriggerValue // and the size of the db is high
- ) { // enough then trigger
- CondenseTriggered = true; // the condense operation.
- }
-
- if(CondenseTriggered) { // If we need to condense then
- (*MyGBUdb).reduce(); // reduce all counts in the db
- (*MyGBUdb).compress(); // and elminate any that drop to zero.
- CondenseGuardTime.restart(); // That done, reset the guard timer.
- (*MyLOGmgr).RecordCondenseEvent(); // Log the event.
- }
- }
-
- // Time to save a snapshot?
-
- if(
- CheckpointOnOff && // If checkpoints are turned on
- CheckpointTrigger.isExpired() // and it is time to create one
- ) {
- (*MyGBUdb).saveSnapshot(); // then save a snapshot and
- CheckpointTrigger.restart(); // restart the timer.
- (*MyLOGmgr).RecordSaveEvent(); // Log the event.
- }
- }
-
- // Stopping the thread...
-
- void snfGBUdbmgr::stop() { // To stop the manager thread we
- if(!TimeToStop) { // check to see we need to then
- TimeToStop = true; // set the time to stop flag
- join(); // and join the thread.
- }
- }
-
- // The thread's task is to call DoMaintenanceWork() once every second.
-
- void snfGBUdbmgr::myTask() { // This is what our thread does.
- cd::Sleeper WaitATic(1000); // We need a 1 second sleeper.
- while(!TimeToStop) { // While it's not time to stop
- WaitATic(); // wait a tic and then do work.
- DoMaintenanceWork();
- }
- }
-
- void snfGBUdbmgr::GetAlertsForSync(std::list<GBUdbAlert>& AlertList) { // Fill AlertList w/ outgoing alerts.
- (*MyGBUdb).GetAlerts(AlertList); // For now, just pass this through.
- }
-
- void snfGBUdbmgr::ProcessReflections(std::list<GBUdbAlert>& Reflections) { // Integrate returning reflections.
- (*MyGBUdb).ImportAlerts(Reflections); // For now, just pass this through.
- }
|