Changeset 222


Ignore:
Timestamp:
06/08/10 13:14:10 (15 years ago)
Author:
ogrimm
Message:
History buffer contains also DIM service format
Location:
Evidence
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • Evidence/Edd/Edd.cc

    r221 r222  
    2727QWidget *OpenHistory(char *Service, int Index) {
    2828
    29   char *Name, *Format;
    30   DimBrowser Browser;
    31 
    32   // If status service displayed as text history
    33   if (strstr(Service, "/Message") != NULL) return new EddText(Service);
    34 
    35   // If service currently not available, default open as plot
    36   Browser.getServices(Service);
    37   if (Browser.getNextService(Name, Format) != DimSERVICE) return new EddPlot(Service, Index);
    38  
    39   // Otherwise, determine from format if plot or text history
    40   if (strlen(Format) == 1 && *Format != 'C') return new EddPlot(Service, Index);
     29  class EvidenceHistory *Hist = Handler->GetHistory(Service);
     30
     31  // Check if hitory service available
     32  if (Hist == NULL || Hist->GetFormat() == NULL) {
     33        QMessageBox::warning(NULL, "Edd Message", QString("Could not retrieve history for service ") + Service ,QMessageBox::Ok);
     34        Handler->DropHistory(Service);
     35        return NULL;
     36  }
     37
     38  QString Format = Hist->GetFormat();
     39  Handler->DropHistory(Service);
     40 
     41  //if (strlen(Hist->GetFormat()) == 1 && *Hist->GetFormat() != 'C') return new EddPlot(Service, Index);
     42  if (Format.size() == 1 && Format[0] != 'C') return new EddPlot(Service, Index);
    4143  else return new EddText(Service);
    4244}
     
    6668        QLineEdit(P), ServiceName(Name), Index(Index) {
    6769
    68  LastPlot = NULL;
     70 LastHist = NULL;
    6971 
    7072  // Widget properties
     
    135137  // Check if last history plot still open, then raise
    136138  foreach (QWidget *Widget, QApplication::allWidgets()) {
    137     if (Widget == LastPlot) {
     139    if (Widget == LastHist) {
    138140      Widget->activateWindow();
    139141      Widget->raise();
     
    177179void EddLineDisplay::MenuOpenHistory() {
    178180 
    179   LastPlot = OpenHistory(ServiceName.toAscii().data(), Index);
    180   if (LastPlot != NULL) LastPlot->show();
     181  LastHist = OpenHistory(ServiceName.toAscii().data(), Index);
     182  if (LastHist != NULL) LastHist->show();
    181183}
    182184
     
    295297                double Number=0;
    296298                while ((R=Hist->Next()) != NULL) {
    297                   switch (Format[0].toUpper().toAscii()) {
     299                  switch (*(Hist->GetFormat())) {
    298300                case 'I':
    299301                        case 'L':  Number = *((int *) R->Data + List[ItemNo].Index);   break;
     
    311313                if (SizeLimit < 2*Count) SizeLimit = 2*Count;
    312314          }
     315          Handler->DropHistory(List[ItemNo].Name);
    313316        }
    314317
     
    737740          }
    738741        }
     742        Handler->DropHistory(Name);
    739743  }
    740744
     
    876880}
    877881
    878 // Update throughput statistics
     882// Reduce history usage counter
     883void EddDim::DropHistory(QString Name) {
     884
     885  for (int i=0; i<HistoryList.size(); i++) {
     886        if (HistoryList[i].Name == Name) HistoryList[i].Count--;
     887  }
     888}
     889
     890// Update throughput statistics and clear up history memory
    879891void EddDim::UpdateStatistics() {
     892
     893  // Remove unused histories after not less than 5 seconds
     894  for (int i=0; i<HistoryList.size(); i++) {
     895        if ((HistoryList[i].Count <= 0) && (time(NULL)-HistoryList[i].LastUpdate) > 5) {
     896          delete HistoryList[i].HistClass;
     897          HistoryList.removeAt(i);
     898        }
     899  }
    880900
    881901  // Lock before accessing internal variables
     
    15341554  getServices("*");
    15351555  while ((Type = getNextService(Name, Format)) != 0) {
    1536     if (Type==DimSERVICE && strstr(Name, ".hist")==NULL) List.append(Name);
     1556    if (Type==DimSERVICE) List.append(Name);
    15371557  }
    15381558  List.sort();
     
    15431563  if (OK && !Result.isEmpty()) {
    15441564    Result = Result.trimmed();
    1545     if (Result.endsWith(".hist")) Result.chop(5);
    15461565    QWidget *Hist = OpenHistory(Result.toAscii().data(), 0);
    15471566    if (Hist != NULL) Hist->show();
  • Evidence/Edd/Edd.h

    r221 r222  
    9696    QMenu *Menu;
    9797    QPoint dragStart;
    98     QWidget *LastPlot;
     98    QWidget *LastHist;
    9999       
    100100        QString ServiceName;
     
    247247        void Unsubscribe (QString);
    248248        class EvidenceHistory *GetHistory(QString);
     249        void DropHistory(QString);
    249250
    250251  signals:
  • Evidence/Evidence.cc

    r221 r222  
    388388
    389389  memcpy(Buffer, R.getData(), BufferSize);
     390  DataStart = Buffer + strlen(Buffer) + 1;
    390391  Rewind();
    391392 
     
    399400
    400401  // Check for wrap around
    401   if (memcmp(Pointer, &WrapMark, sizeof(WrapMark)) == 0) Pointer = (struct Item *) (Buffer + 4);
    402  
     402  if (memcmp(Pointer, &WrapMark, sizeof(WrapMark)) == 0) Pointer = (struct Item *) (DataStart + sizeof(int));
    403403  // Check if at end of ring buffer
    404404  if (memcmp(Pointer, &EndMark, sizeof(EndMark)) == 0) return NULL;
    405405
    406406  const struct Item *Ret = Pointer;
    407   Pointer = (struct Item *) ((char *) (Pointer + 1) + Pointer->Size);
     407  Pointer = (struct Item *) ((char *) (Ret + 1) + Ret->Size);
    408408
    409409  return Ret;
     
    413413void EvidenceHistory::Rewind() {
    414414
    415   if (Buffer != NULL) Pointer = (struct Item *) (Buffer + (*(int *) Buffer));
    416 }
     415  if (Buffer != NULL) Pointer = (struct Item *) (DataStart + (*(int *) DataStart));
     416}
     417
     418// Return DIM format string of service (NULL if no data)
     419char *EvidenceHistory::GetFormat() {
     420
     421  return Buffer;
     422}
  • Evidence/Evidence.h

    r216 r222  
    8181          int Time;
    8282          int Size;
    83           char Data[]; // Size bytes
     83          char Data[]; // Size bytes follow
    8484        } __attribute__((packed));
    8585
     
    9191        char *Buffer;
    9292        int BufferSize;
     93        char *DataStart;
    9394        struct Item *Pointer;
    9495       
     
    9899
    99100        bool GetHistory();
     101        char *GetFormat();
    100102        const struct Item *Next();
    101103        void Rewind();
  • Evidence/History.cc

    r221 r222  
    2323
    2424#include <string>
    25 #include <sstream>
    2625#include <vector>
    2726#include <math.h>
     
    4241          double LastValue;
    4342          double MinAbsChange;
     43          string Format;
    4444        };
    4545        vector<struct Item> List;
     
    5151    void infoHandler();
    5252    void rpcHandler();
    53         void AddService(string);
     53        void AddService(string, const char *);
    5454        void RemoveService(string);
    5555        off_t FileSize(FILE *);
     
    9797        char *Token = strtok(I->getString(), "+-!@");   
    9898        while (Token != NULL) {
    99           AddService(string(Token)+"/SERVICE_LIST"); // 'add' also for '-' and '!'
     99          AddService(string(Token)+"/SERVICE_LIST", "C"); // 'add' also for '-' and '!'
    100100          Token = strtok(NULL, "|"); // Skip server IP address
    101101          Token = strtok(NULL, "@");
     
    104104  }
    105105
    106   // If service is SERVICE_LIST of any server, scan all services.
    107   // Subscribe to all services (but not to commands and RPCs)
     106  // If service is SERVICE_LIST, scan and subscribe/unsubscribe to services
    108107  if (strstr(I->getName(), "/SERVICE_LIST") != NULL) {
    109         char *Name = strtok(I->getString(), "+-!|");
     108        char *Type, *Name = strtok(I->getString(), "+-!|");
    110109        while (Name != NULL) {
    111           // Check if item is a service
    112           char *Type = strtok(NULL, "\n");
    113           if (Type == NULL) return; // for safety, should not happen
    114       if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) AddService(Name); // 'add' also for '-' and '!'
     110          // Only consider DIM services (not commands and RPCs)
     111      if (((Type = strtok(NULL, "\n")) != NULL) &&
     112                  (strstr(Type, "|CMD") == NULL) && (strstr(Type, "|RPC") == NULL)) {
     113            if (*I->getString() == '-' || *I->getString() == '!') RemoveService(Name);
     114                else {
     115                  Type[strlen(Type)-1] = '\0'; // Isolate service format
     116                  AddService(Name, Type);
     117                }
     118          }
    115119          Name = strtok(NULL, "|");
    116120        }
     
    161165  if (Next + Size >= List[Service].Buffer.size()) {
    162166    WrapPos = Buffer + Next;
    163     Next = 4;
     167    Next = sizeof(int);
    164168  }
    165169
     
    169173        // Check for wrap-around
    170174        if (memcmp(Buffer + Oldest, &EvidenceHistory::WrapMark, sizeof(EvidenceHistory::WrapMark)) == 0) {
    171           Oldest = 4;
     175          Oldest = sizeof(int);
    172176          continue;
    173177        }
     
    205209  for (int i=0; i<List.size(); i++) {
    206210    if (strcmp(List[i].DataItem->getName(), getString()) == 0) {
    207           setData((void *) &List[i].Buffer[0], List[i].Buffer.size());
     211          char *Buffer = new char [List[i].Format.size()+1+List[i].Buffer.size()];
     212          strcpy(Buffer, List[i].Format.c_str());
     213          memcpy(Buffer+List[i].Format.size()+1, &List[i].Buffer[0], List[i].Buffer.size());
     214//        setData((void *) &List[i].Buffer[0], List[i].Buffer.size());
     215          setData((void *) Buffer, List[i].Format.size()+1+List[i].Buffer.size());
     216          delete[] Buffer;
    208217          return;
    209218        }
     
    217226  }
    218227
    219   // Read history file
     228  // Read history file and send to client (data will contain format string and history)
    220229  off_t Size = FileSize(File);
    221230  if (Size != -1) {
    222231        char *Buffer = new char [Size-sizeof(int)];
    223         fseek(File, sizeof(int), SEEK_SET);
    224         fread(Buffer, sizeof(char), Size-sizeof(int), File);
    225         if (ferror(File) != 0) {
     232        fseek(File, sizeof(int), SEEK_SET); // Skip 'Next' pointer
     233        if ((fread(Buffer, sizeof(char), Size-sizeof(int), File) != Size-sizeof(int)) || (ferror(File) != 0)) {
    226234          Message(WARN, "Error reading history file '%s' in rpcHandler()", getString());
    227235          setData(NULL, 0);             // Default response
     
    238246// Add service to watch list
    239247//
    240 void History::AddService(string Name) {
     248void History::AddService(string Name, const char *Format) {
    241249
    242250  // Check if already subscribed to this service
     
    247255  struct Item New;
    248256  New.LastValue = DBL_MAX;
     257  New.Format = Format;
    249258
    250259  // Set minimum required change if given in configuratrion
     
    258267
    259268  if (File != NULL && (Size = FileSize(File)) != -1) {
     269
     270    // If current buffer too small, resize
    260271        if (Size > New.Buffer.size()) New.Buffer.resize(Size);
     272
     273        // Read next pointer
    261274    fread(&New.Next, sizeof(New.Next), 1, File);
     275        // Skip format string
     276        while (fgetc(File) != 0 && feof(File) == 0) {}
     277        // Read buffer
    262278    fread(&New.Buffer[0], sizeof(char), Size, File);
     279
    263280        if (ferror(File) != 0) {
    264281          Message(WARN, "Error reading history file '%s' in AddService()", Name.c_str());
     
    297314        FILE *File = OpenFile(Name, "wb");
    298315        if (File != NULL) {
    299       fwrite(&(*E).Next, sizeof((*E).Next), 1, File);
    300       fwrite(&(*E).Buffer[0], sizeof(char), (*E).Buffer.size(), File);
    301           if (ferror(File) != 0) Message(WARN, "Error writing history file '%s' in RemoveService()", Name.c_str());
     316      fwrite(&(*E).Next, sizeof((*E).Next), 1, File);                                   // Next pointer
     317      fwrite((*E).Format.c_str(), (*E).Format.size()+1, 1, File);               // Format
     318      fwrite(&(*E).Buffer[0], sizeof(char), (*E).Buffer.size(), File);  // Buffer
     319
     320          // If error, try to delete (possibly erroneous) file
     321          if (ferror(File) != 0) {
     322                if (remove(Name.c_str()) == -1) Message(WARN, "Error writing history file '%s' in RemoveService(), could also not delete file", Name.c_str());
     323                else Message(WARN, "Error writing history file '%s' in RemoveService(), deleted file", Name.c_str());
     324          }
    302325      if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in RemoveService()", Name.c_str());;
    303326        }
    304327       
    305         // Delete history service and free memory
    306     //delete[] (*E).Buffer;
    307328        List.erase(E);
    308329  }
     
    332353  if(mkdir(Directory, S_IRWXU|S_IRWXG)==-1 && errno!=EEXIST) return NULL;
    333354
    334   // Replace all '/' by '_' in string and open file
    335   for (int i=0; i<Service.size(); i++) if (Service[i] == '/') Service[i] = '_';
    336   return fopen((Directory + Service).c_str(), Mode);
     355  // Replace all '/' and non-graphical characters by '_' in string and open file
     356  for (int i=0; i<Service.size(); i++) {
     357        if (Service[i] == '/') Service[i] = '_';
     358        if (isgraph(Service[i]) == 0) Service[i] = '_';
     359  }
     360
     361  return fopen((string(Directory) + "/" + Service).c_str(), Mode);
    337362}
    338363
  • Evidence/readme.txt

    r221 r222  
    3636                        Service quality now also written to slow data file.
    373731/5/2010       Configuration file format now follows semi-standard INI format.
    38 7/6/2010        Separated History service from DColl.
     387/6/2010        Separated History service from DColl. History format changed, now includes
     39                        service format (allows history access also when service is unavailable).
    3940
    4041
Note: See TracChangeset for help on using the changeset viewer.