Fixing configuration change prediction engine.

This commit is contained in:
stephb9959
2021-10-31 11:37:47 -07:00
parent 5ef004932f
commit 2f2045c5c4
6 changed files with 71 additions and 32 deletions

2
build
View File

@@ -1 +1 @@
21
23

View File

@@ -194,7 +194,7 @@ namespace OpenWifi{
}
if(DB_.CreateRecord(NewObject)) {
SerialNumberCache()->AddSerialNumber(SerialNumber);
SerialNumberCache()->AddSerialNumber(SerialNumber,NewObject.deviceType);
if (!NewObject.venue.empty())
StorageService()->VenueDB().AddDevice("id",NewObject.venue,NewObject.info.id);
if (!NewObject.entity.empty())

View File

@@ -20,15 +20,25 @@ namespace OpenWifi {
}
void SerialNumberCache::AddSerialNumber(const std::string &S) {
void SerialNumberCache::AddSerialNumber(const std::string &S, const std::string &DeviceType) {
std::lock_guard G(M_);
auto Hint = DeviceTypeDictionary_.find(DeviceType);
int Index;
if(Hint == end(DeviceTypeDictionary_)) {
Index = DeviceTypeIndex_;
DeviceTypeDictionary_[DeviceType] = DeviceTypeIndex_++;
} else {
Index = Hint->second;
}
uint64_t SN = std::stoull(S,0,16);
if(std::find(SNs_.begin(),SNs_.end(),SN) == SNs_.end()) {
if(std::find_if(SNs_.begin(),SNs_.end(),[SN](DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; }) == SNs_.end()) {
auto NE = DeviceTypeCacheEntry{ .SerialNumber = SN, .DeviceType = Index };
if(SNs_.size()+1 == SNs_.capacity())
SNs_.resize(SNs_.capacity()+2000);
SNs_.push_back(SN);
std::sort(SNs_.begin(),SNs_.end());
SNs_.push_back(NE);
std::sort(SNs_.begin(),SNs_.end(), [](const DeviceTypeCacheEntry &E1, const DeviceTypeCacheEntry &E2) { return E1.SerialNumber < E2.SerialNumber ; });
}
}
@@ -36,7 +46,7 @@ namespace OpenWifi {
std::lock_guard G(M_);
uint64_t SN = std::stoull(S,0,16);
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
auto It = std::find_if(SNs_.begin(),SNs_.end(),[SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; });
if(It != SNs_.end()) {
SNs_.erase(It);
}
@@ -47,21 +57,21 @@ namespace OpenWifi {
if(S.length()==12) {
uint64_t SN = std::stoull(S,0,16);
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
auto It = std::find_if(SNs_.begin(),SNs_.end(), [SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; } );
if(It != SNs_.end()) {
A.push_back(*It);
A.push_back(It->SerialNumber);
}
} else if (S.length()<12){
std::string SS{S};
SS.insert(SS.end(), 12 - SS.size(), '0');
uint64_t SN = std::stoull(SS,0,16);
auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN);
auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN, [](const DeviceTypeCacheEntry &E1,uint64_t V) { return E1.SerialNumber < V ; });
if(LB!=SNs_.end()) {
for(;LB!=SNs_.end() && HowMany;++LB,--HowMany) {
std::string TSN = Utils::int_to_hex(*LB);
std::string TSN = Utils::int_to_hex(LB->SerialNumber);
if(S == TSN.substr(0,S.size())) {
A.emplace_back(*LB);
A.emplace_back(LB->SerialNumber);
} else {
break;
}
@@ -69,4 +79,18 @@ namespace OpenWifi {
}
}
}
bool SerialNumberCache::FindDevice(const std::string &SerialNumber, std::string & DeviceType) {
uint64_t SN = std::stoull(SerialNumber,0,16);
auto It = std::find_if(SNs_.begin(),SNs_.end(),[SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; });
if(It != SNs_.end()) {
for(const auto &i:DeviceTypeDictionary_)
if(i.second==It->DeviceType) {
DeviceType = i.first;
return true;
}
}
return false;
}
}

View File

@@ -11,6 +11,10 @@ namespace OpenWifi {
class SerialNumberCache : public SubSystemServer {
public:
struct DeviceTypeCacheEntry {
uint64_t SerialNumber;
int DeviceType;
};
static SerialNumberCache *instance() {
if (instance_ == nullptr) {
instance_ = new SerialNumberCache;
@@ -20,14 +24,17 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void AddSerialNumber(const std::string &S);
void AddSerialNumber(const std::string &SerialNumber, const std::string &DeviceType);
void DeleteSerialNumber(const std::string &S);
void FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A);
bool FindDevice(const std::string &SerialNumber, std::string & DeviceType);
private:
static SerialNumberCache * instance_;
int DeviceTypeIndex_=0;
uint64_t LastUpdate_ = 0 ;
std::vector<uint64_t> SNs_;
std::vector<DeviceTypeCacheEntry> SNs_;
std::map<std::string,int> DeviceTypeDictionary_;
std::mutex M_;
SerialNumberCache() noexcept:

View File

@@ -44,36 +44,43 @@ namespace OpenWifi {
ConfigurationDB::ConfigurationDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "configurations", ConfigurationDB_Fields, ConfigurationDB_Indexes, P, L, "cfg") {}
static bool AddDevicesFromVenue( const std::string & UUID, std::set<std::string> & Devices) {
static bool AddIfAffected( const std::string & UUID,const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices ) {
ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",UUID,T))
return false;
for(const auto &i:DeviceTypes) {
if(i=="*" || i==T.deviceType) {
Devices.insert(T.serialNumber);
return true;
}
}
return false;
}
static bool AddDevicesFromVenue( const std::string & UUID, const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices) {
ProvObjects::Venue V;
if(!StorageService()->VenueDB().GetRecord("id",UUID,V))
return false;
for(const auto &j:V.devices) {
ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",j,T))
continue;
Devices.insert(T.serialNumber);
AddIfAffected(j, DeviceTypes, Devices);
}
for(const auto &j:V.children)
AddDevicesFromVenue(j,Devices);
AddDevicesFromVenue(j,DeviceTypes,Devices);
return true;
}
static bool AddDevicesFromEntity( const std::string & UUID, std::set<std::string> & Devices) {
static bool AddDevicesFromEntity( const std::string & UUID, const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices) {
ProvObjects::Entity E;
if(!StorageService()->EntityDB().GetRecord("id",UUID,E))
return false;
for(const auto &j:E.devices) {
ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",j,T))
continue;
Devices.insert(T.serialNumber);
AddIfAffected(j, DeviceTypes, Devices);
}
for(const auto &j:E.children)
AddDevicesFromEntity(j, Devices);
AddDevicesFromEntity(j,DeviceTypes, Devices);
for(const auto &j:E.venues)
AddDevicesFromVenue(j, Devices);
AddDevicesFromVenue(j,DeviceTypes, Devices);
return true;
}
@@ -89,14 +96,15 @@ namespace OpenWifi {
return true;
std::set<std::string> SerialNumbers;
auto DeviceTypes = Config.deviceTypes;
for(const auto &i:Config.inUse) {
auto Tokens = Poco::StringTokenizer(i,":");
if(Tokens.count()!=2)
continue;
if(Tokens[0] == "ent") {
AddDevicesFromEntity(Tokens[1], SerialNumbers);
AddDevicesFromEntity(Tokens[1], DeviceTypes, SerialNumbers);
} else if (Tokens[0] == "ven") {
AddDevicesFromVenue(Tokens[1], SerialNumbers);
AddDevicesFromVenue(Tokens[1], DeviceTypes, SerialNumbers);
} else if (Tokens[0] == "inv") {
ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",Tokens[1],T))

View File

@@ -83,7 +83,7 @@ namespace OpenWifi {
}
if(CreateRecord(NewDevice)) {
SerialNumberCache()->AddSerialNumber(SerialNumber);
SerialNumberCache()->AddSerialNumber(SerialNumber, DeviceType);
std::string FullUUID;
if(!NewDevice.entity.empty()) {
StorageService()->EntityDB().AddDevice("id",NewDevice.entity,NewDevice.info.id);
@@ -219,7 +219,7 @@ namespace OpenWifi {
}
void InventoryDB::InitializeSerialCache() {
auto F = []( const ProvObjects::InventoryTag & T) ->bool { SerialNumberCache()->AddSerialNumber(T.serialNumber); return true;};
auto F = []( const ProvObjects::InventoryTag & T) ->bool { SerialNumberCache()->AddSerialNumber(T.serialNumber, T.deviceType); return true;};
Iterate(F);
}