#include "UdpPacketTreeWriter.h"
#include "Glasses/UdpPacketSource.h"
#include "Glasses/ZLog.h"
#include "UdpPacketTreeWriter.c7"
#include "Stones/SUdpPacket.h"
#include "Gled/GThread.h"
#include "TFile.h"
#include "TTree.h"
#include "TSystem.h"
#include "TCint.h"
#include "TVirtualMutex.h"
ClassImp(UdpPacketTreeWriter);
void UdpPacketTreeWriter::_init()
{
  mWLThread = 0;
  mAutoSaveEntries  = 100000;
  mAutoSaveMinutes  = 60;
  mRotateMinutes    = 24 * 60;
  bRotateAtMidnight = true;
  bRunning = false;
  bForceAutoSave = bForceRotate = false;
  bFileIdxAlways = true;
  mFilePrefix    = "udp-tree-dump-";
  mTreeName      = "UdpPackets";
  mFileLastIdx   = -1;
  mFile   = 0;
  mTree   = 0;
  mBranch = 0;
}
UdpPacketTreeWriter::UdpPacketTreeWriter(const Text_t* n, const Text_t* t) :
  ZGlass(n, t)
{
  _init();
}
UdpPacketTreeWriter::~UdpPacketTreeWriter()
{}
void UdpPacketTreeWriter::open_file_create_tree()
{
  static const Exc_t _eh("UdpPacketTreeWriter::open_file_create_tree ");
  TString date     = GTime::Now().ToDateLocal();
  TString basename = mFilePrefix + date;
  if (date == mFileLastDate)
  {
    ++mFileLastIdx;
    mFileNameTrue = basename + TString::Format("-%d.root", mFileLastIdx);
  }
  else
  {
    if (mFileLastDate.IsNull())
    {
      
      Int_t i = 0;
      while (true)
      {
        mFileNameTrue = basename;
        if (bFileIdxAlways || i != 0) mFileNameTrue += TString::Format("-%d", i);
        mFileNameTrue += ".root";
        if (gSystem->AccessPathName(mFileNameTrue) == true)
        {
          
	  
	  TString hfn = GledNS::pathname_make_hidden_file(mFileNameTrue);
	  if (gSystem->AccessPathName(hfn) == true)
	  {
	    break;
	  }
          else if (*mLog)
          {
            mLog->Form(ZLog::L_Warning, _eh, "Hidden file '%s' found during start-up - it will be kept as is.", hfn.Data());
          }
        }
        ++i;
      }
      mFileLastIdx = i;
    }
    else
    {
      mFileNameTrue = basename;
      if (bFileIdxAlways) mFileNameTrue += "-0";
      mFileNameTrue += ".root";
      mFileLastIdx = 0;
    }
    mFileLastDate = date;
  }
  if (*mLog)
  {
    mLog->Form(ZLog::L_Message, _eh, "Opening tree file '%s' (kept hidden until closing).", mFileNameTrue.Data());
  }
  TString fn = GledNS::pathname_make_hidden_file(mFileNameTrue);
  {
    R__LOCKGUARD2(gCINTMutex);
    mFile = TFile::Open(fn, "recreate");
    if (mFile == 0)
    {
      throw _eh + "Opening of file '" + fn + "' failed.";
    }
    mTree = new TTree(mTreeName, "UDP packets");
    mTree->SetAutoFlush(10000);
    mTree->SetAutoSave(0);
    SUdpPacket *pup = 0;
    mBranch = mTree->Branch("P", &pup, 8 * 1024, 2);
  }
  mBranch->FindBranch("mAddr")->SetBasketSize(16 * 1024);
  mBranch->FindBranch("mBuff")->SetBasketSize(4096 * 1024);
  mBranch->GetListOfBranches()->Remove(mBranch->FindBranch("SRefCountedNV"));
  mBranch->GetListOfBranches()->Compress();
  mLastAutoSave  = GTime::ApproximateTime();
  bForceAutoSave = false;
  mLastFileOpen  = GTime::ApproximateTime();
  bForceRotate   = false;
}
void UdpPacketTreeWriter::write_tree_close_file()
{
  static const Exc_t _eh("UdpPacketTreeWriter::write_tree_close_file ");
  TString fn(mFile->GetName());
  mTree->Write();
  TNamed xx("WritingComplete", "");
  mFile->WriteTObject(&xx);
  mFile->Close();
  delete mFile;
  mFile = 0; mTree = 0; mBranch = 0;
  gSystem->Rename(fn, mFileNameTrue);
  if (*mLog)
  {
    mLog->Form(ZLog::L_Message, _eh, "Closed tree file '%s'.", mFileNameTrue.Data());
  }
  
  mFileNameTrue = "";
}
void UdpPacketTreeWriter::check_file_rotate()
{
  
  GTime at = GTime::ApproximateTime();
  if ((mRotateMinutes > 0 && at >= mLastFileOpen + GTime(60*mRotateMinutes, 0)) ||
      (bRotateAtMidnight && at - mLastFileOpen > at.TimeOfTheDayLocal()) ||
      bForceRotate)
  {
    mBranch->SetAddress(0);
    write_tree_close_file();
    open_file_create_tree();
    {
      GLensReadHolder _lck(this);
      Stamp(FID());
    }
  }
}
void UdpPacketTreeWriter::cu_WriteLoop(UdpPacketTreeWriter* w)
{
  w->mSource->UnregisterConsumer(&w->mUdpQueue);
  w->mUdpQueue.ClearQueueDecRefCount();
  w->write_tree_close_file();
  {
    GLensReadHolder _lck(w);
    w->mWLThread = 0;
    w->bRunning = false;
    w->Stamp(w->FID());
  }
}
void UdpPacketTreeWriter::WriteLoop()
{
  static const Exc_t _eh("UdpPacketTreeWriter::WriteLoop ");
  while (true)
  {
    SUdpPacket *p;
    {
      GThread::CancelEnabler _ce;
      p = mUdpQueue.PopFrontTimedWaitUntil(GTime::ApproximateTime() + GTime(10, 0));
    }
    check_file_rotate();
    if (p == 0)
      continue;
    mBranch->SetAddress(&p);
    mTree->Fill();
  if ((mAutoSaveEntries > 0 && mTree->GetEntries() % mAutoSaveEntries == 0) ||
      (mAutoSaveMinutes > 0 && GTime::ApproximateTime() >= mLastAutoSave + GTime(60*mAutoSaveMinutes, 0)) ||
      bForceAutoSave)
    if (mAutoSaveEntries > 0 && mTree->GetEntries() % mAutoSaveEntries == 0)
    {
      if (*mLog)
      {
        mLog->Form(ZLog::L_Info, _eh, "Auto-saving tree, N_entries=%lld.", mTree->GetEntries());
      }
      mTree->AutoSave("SaveSelf");
      {
        GLensReadHolder _lck(this);
        mLastAutoSave  = GTime::ApproximateTime();
        bForceAutoSave = false;
        Stamp(FID());
      }
    }
    p->DecRefCount();
  }
}
void UdpPacketTreeWriter::Start()
{
  
  static const Exc_t _eh("UdpPacketTreeWriter::Start ");
  {
    GLensReadHolder _lck(this);
    if (mWLThread)
      throw _eh + "already running.";
    mWLThread = GThread::Self();
    mWLThread->SetName("UdpPacketTreeWriter-WriteLoop");
    GThread::CancelOff();
    bRunning = true;
    Stamp(FID());
  }
  mFileNameTrue = "";
  mFileLastDate = "";
  mFileLastIdx  = -1;
  open_file_create_tree();
  mWLThread->CleanupPush((GThread_cu_foo) cu_WriteLoop, this);
  mSource->RegisterConsumer(&mUdpQueue);
  WriteLoop();
  mWLThread->CleanupPop(true);
}
void UdpPacketTreeWriter::Stop()
{
  static const Exc_t _eh("UdpPacketTreeWriter::Stop ");
  GThread *thr = 0;
  {
    GLensReadHolder _lck(this);
    if ( ! GThread::IsValidPtr(mWLThread))
      throw _eh + "not running.";
    thr = mWLThread;
    GThread::InvalidatePtr(mWLThread);
  }
  thr->Cancel();
  thr->Join();
  delete thr;
}
void UdpPacketTreeWriter::RotateTree()
{
  static const Exc_t _eh("UdpPacketTreeWriter::RotateTree ");
  if ( ! GThread::IsValidPtr(mWLThread))
    throw _eh + "not running.";
  bForceRotate = true;
}
void UdpPacketTreeWriter::AutoSaveTree()
{
  static const Exc_t _eh("UdpPacketTreeWriter::AutoSaveTree ");
  if ( ! GThread::IsValidPtr(mWLThread))
    throw _eh + "not running.";
  bForceAutoSave = true;
}
 UdpPacketTreeWriter.cxx:1  UdpPacketTreeWriter.cxx:2  UdpPacketTreeWriter.cxx:3  UdpPacketTreeWriter.cxx:4  UdpPacketTreeWriter.cxx:5  UdpPacketTreeWriter.cxx:6  UdpPacketTreeWriter.cxx:7  UdpPacketTreeWriter.cxx:8  UdpPacketTreeWriter.cxx:9  UdpPacketTreeWriter.cxx:10  UdpPacketTreeWriter.cxx:11  UdpPacketTreeWriter.cxx:12  UdpPacketTreeWriter.cxx:13  UdpPacketTreeWriter.cxx:14  UdpPacketTreeWriter.cxx:15  UdpPacketTreeWriter.cxx:16  UdpPacketTreeWriter.cxx:17  UdpPacketTreeWriter.cxx:18  UdpPacketTreeWriter.cxx:19  UdpPacketTreeWriter.cxx:20  UdpPacketTreeWriter.cxx:21  UdpPacketTreeWriter.cxx:22  UdpPacketTreeWriter.cxx:23  UdpPacketTreeWriter.cxx:24  UdpPacketTreeWriter.cxx:25  UdpPacketTreeWriter.cxx:26  UdpPacketTreeWriter.cxx:27  UdpPacketTreeWriter.cxx:28  UdpPacketTreeWriter.cxx:29  UdpPacketTreeWriter.cxx:30  UdpPacketTreeWriter.cxx:31  UdpPacketTreeWriter.cxx:32  UdpPacketTreeWriter.cxx:33  UdpPacketTreeWriter.cxx:34  UdpPacketTreeWriter.cxx:35  UdpPacketTreeWriter.cxx:36  UdpPacketTreeWriter.cxx:37  UdpPacketTreeWriter.cxx:38  UdpPacketTreeWriter.cxx:39  UdpPacketTreeWriter.cxx:40  UdpPacketTreeWriter.cxx:41  UdpPacketTreeWriter.cxx:42  UdpPacketTreeWriter.cxx:43  UdpPacketTreeWriter.cxx:44  UdpPacketTreeWriter.cxx:45  UdpPacketTreeWriter.cxx:46  UdpPacketTreeWriter.cxx:47  UdpPacketTreeWriter.cxx:48  UdpPacketTreeWriter.cxx:49  UdpPacketTreeWriter.cxx:50  UdpPacketTreeWriter.cxx:51  UdpPacketTreeWriter.cxx:52  UdpPacketTreeWriter.cxx:53  UdpPacketTreeWriter.cxx:54  UdpPacketTreeWriter.cxx:55  UdpPacketTreeWriter.cxx:56  UdpPacketTreeWriter.cxx:57  UdpPacketTreeWriter.cxx:58  UdpPacketTreeWriter.cxx:59  UdpPacketTreeWriter.cxx:60  UdpPacketTreeWriter.cxx:61  UdpPacketTreeWriter.cxx:62  UdpPacketTreeWriter.cxx:63  UdpPacketTreeWriter.cxx:64  UdpPacketTreeWriter.cxx:65  UdpPacketTreeWriter.cxx:66  UdpPacketTreeWriter.cxx:67  UdpPacketTreeWriter.cxx:68  UdpPacketTreeWriter.cxx:69  UdpPacketTreeWriter.cxx:70  UdpPacketTreeWriter.cxx:71  UdpPacketTreeWriter.cxx:72  UdpPacketTreeWriter.cxx:73  UdpPacketTreeWriter.cxx:74  UdpPacketTreeWriter.cxx:75  UdpPacketTreeWriter.cxx:76  UdpPacketTreeWriter.cxx:77  UdpPacketTreeWriter.cxx:78  UdpPacketTreeWriter.cxx:79  UdpPacketTreeWriter.cxx:80  UdpPacketTreeWriter.cxx:81  UdpPacketTreeWriter.cxx:82  UdpPacketTreeWriter.cxx:83  UdpPacketTreeWriter.cxx:84  UdpPacketTreeWriter.cxx:85  UdpPacketTreeWriter.cxx:86  UdpPacketTreeWriter.cxx:87  UdpPacketTreeWriter.cxx:88  UdpPacketTreeWriter.cxx:89  UdpPacketTreeWriter.cxx:90  UdpPacketTreeWriter.cxx:91  UdpPacketTreeWriter.cxx:92  UdpPacketTreeWriter.cxx:93  UdpPacketTreeWriter.cxx:94  UdpPacketTreeWriter.cxx:95  UdpPacketTreeWriter.cxx:96  UdpPacketTreeWriter.cxx:97  UdpPacketTreeWriter.cxx:98  UdpPacketTreeWriter.cxx:99  UdpPacketTreeWriter.cxx:100  UdpPacketTreeWriter.cxx:101  UdpPacketTreeWriter.cxx:102  UdpPacketTreeWriter.cxx:103  UdpPacketTreeWriter.cxx:104  UdpPacketTreeWriter.cxx:105  UdpPacketTreeWriter.cxx:106  UdpPacketTreeWriter.cxx:107  UdpPacketTreeWriter.cxx:108  UdpPacketTreeWriter.cxx:109  UdpPacketTreeWriter.cxx:110  UdpPacketTreeWriter.cxx:111  UdpPacketTreeWriter.cxx:112  UdpPacketTreeWriter.cxx:113  UdpPacketTreeWriter.cxx:114  UdpPacketTreeWriter.cxx:115  UdpPacketTreeWriter.cxx:116  UdpPacketTreeWriter.cxx:117  UdpPacketTreeWriter.cxx:118  UdpPacketTreeWriter.cxx:119  UdpPacketTreeWriter.cxx:120  UdpPacketTreeWriter.cxx:121  UdpPacketTreeWriter.cxx:122  UdpPacketTreeWriter.cxx:123  UdpPacketTreeWriter.cxx:124  UdpPacketTreeWriter.cxx:125  UdpPacketTreeWriter.cxx:126  UdpPacketTreeWriter.cxx:127  UdpPacketTreeWriter.cxx:128  UdpPacketTreeWriter.cxx:129  UdpPacketTreeWriter.cxx:130  UdpPacketTreeWriter.cxx:131  UdpPacketTreeWriter.cxx:132  UdpPacketTreeWriter.cxx:133  UdpPacketTreeWriter.cxx:134  UdpPacketTreeWriter.cxx:135  UdpPacketTreeWriter.cxx:136  UdpPacketTreeWriter.cxx:137  UdpPacketTreeWriter.cxx:138  UdpPacketTreeWriter.cxx:139  UdpPacketTreeWriter.cxx:140  UdpPacketTreeWriter.cxx:141  UdpPacketTreeWriter.cxx:142  UdpPacketTreeWriter.cxx:143  UdpPacketTreeWriter.cxx:144  UdpPacketTreeWriter.cxx:145  UdpPacketTreeWriter.cxx:146  UdpPacketTreeWriter.cxx:147  UdpPacketTreeWriter.cxx:148  UdpPacketTreeWriter.cxx:149  UdpPacketTreeWriter.cxx:150  UdpPacketTreeWriter.cxx:151  UdpPacketTreeWriter.cxx:152  UdpPacketTreeWriter.cxx:153  UdpPacketTreeWriter.cxx:154  UdpPacketTreeWriter.cxx:155  UdpPacketTreeWriter.cxx:156  UdpPacketTreeWriter.cxx:157  UdpPacketTreeWriter.cxx:158  UdpPacketTreeWriter.cxx:159  UdpPacketTreeWriter.cxx:160  UdpPacketTreeWriter.cxx:161  UdpPacketTreeWriter.cxx:162  UdpPacketTreeWriter.cxx:163  UdpPacketTreeWriter.cxx:164  UdpPacketTreeWriter.cxx:165  UdpPacketTreeWriter.cxx:166  UdpPacketTreeWriter.cxx:167  UdpPacketTreeWriter.cxx:168  UdpPacketTreeWriter.cxx:169  UdpPacketTreeWriter.cxx:170  UdpPacketTreeWriter.cxx:171  UdpPacketTreeWriter.cxx:172  UdpPacketTreeWriter.cxx:173  UdpPacketTreeWriter.cxx:174  UdpPacketTreeWriter.cxx:175  UdpPacketTreeWriter.cxx:176  UdpPacketTreeWriter.cxx:177  UdpPacketTreeWriter.cxx:178  UdpPacketTreeWriter.cxx:179  UdpPacketTreeWriter.cxx:180  UdpPacketTreeWriter.cxx:181  UdpPacketTreeWriter.cxx:182  UdpPacketTreeWriter.cxx:183  UdpPacketTreeWriter.cxx:184  UdpPacketTreeWriter.cxx:185  UdpPacketTreeWriter.cxx:186  UdpPacketTreeWriter.cxx:187  UdpPacketTreeWriter.cxx:188  UdpPacketTreeWriter.cxx:189  UdpPacketTreeWriter.cxx:190  UdpPacketTreeWriter.cxx:191  UdpPacketTreeWriter.cxx:192  UdpPacketTreeWriter.cxx:193  UdpPacketTreeWriter.cxx:194  UdpPacketTreeWriter.cxx:195  UdpPacketTreeWriter.cxx:196  UdpPacketTreeWriter.cxx:197  UdpPacketTreeWriter.cxx:198  UdpPacketTreeWriter.cxx:199  UdpPacketTreeWriter.cxx:200  UdpPacketTreeWriter.cxx:201  UdpPacketTreeWriter.cxx:202  UdpPacketTreeWriter.cxx:203  UdpPacketTreeWriter.cxx:204  UdpPacketTreeWriter.cxx:205  UdpPacketTreeWriter.cxx:206  UdpPacketTreeWriter.cxx:207  UdpPacketTreeWriter.cxx:208  UdpPacketTreeWriter.cxx:209  UdpPacketTreeWriter.cxx:210  UdpPacketTreeWriter.cxx:211  UdpPacketTreeWriter.cxx:212  UdpPacketTreeWriter.cxx:213  UdpPacketTreeWriter.cxx:214  UdpPacketTreeWriter.cxx:215  UdpPacketTreeWriter.cxx:216  UdpPacketTreeWriter.cxx:217  UdpPacketTreeWriter.cxx:218  UdpPacketTreeWriter.cxx:219  UdpPacketTreeWriter.cxx:220  UdpPacketTreeWriter.cxx:221  UdpPacketTreeWriter.cxx:222  UdpPacketTreeWriter.cxx:223  UdpPacketTreeWriter.cxx:224  UdpPacketTreeWriter.cxx:225  UdpPacketTreeWriter.cxx:226  UdpPacketTreeWriter.cxx:227  UdpPacketTreeWriter.cxx:228  UdpPacketTreeWriter.cxx:229  UdpPacketTreeWriter.cxx:230  UdpPacketTreeWriter.cxx:231  UdpPacketTreeWriter.cxx:232  UdpPacketTreeWriter.cxx:233  UdpPacketTreeWriter.cxx:234  UdpPacketTreeWriter.cxx:235  UdpPacketTreeWriter.cxx:236  UdpPacketTreeWriter.cxx:237  UdpPacketTreeWriter.cxx:238  UdpPacketTreeWriter.cxx:239  UdpPacketTreeWriter.cxx:240  UdpPacketTreeWriter.cxx:241  UdpPacketTreeWriter.cxx:242  UdpPacketTreeWriter.cxx:243  UdpPacketTreeWriter.cxx:244  UdpPacketTreeWriter.cxx:245  UdpPacketTreeWriter.cxx:246  UdpPacketTreeWriter.cxx:247  UdpPacketTreeWriter.cxx:248  UdpPacketTreeWriter.cxx:249  UdpPacketTreeWriter.cxx:250  UdpPacketTreeWriter.cxx:251  UdpPacketTreeWriter.cxx:252  UdpPacketTreeWriter.cxx:253  UdpPacketTreeWriter.cxx:254  UdpPacketTreeWriter.cxx:255  UdpPacketTreeWriter.cxx:256  UdpPacketTreeWriter.cxx:257  UdpPacketTreeWriter.cxx:258  UdpPacketTreeWriter.cxx:259  UdpPacketTreeWriter.cxx:260  UdpPacketTreeWriter.cxx:261  UdpPacketTreeWriter.cxx:262  UdpPacketTreeWriter.cxx:263  UdpPacketTreeWriter.cxx:264  UdpPacketTreeWriter.cxx:265  UdpPacketTreeWriter.cxx:266  UdpPacketTreeWriter.cxx:267  UdpPacketTreeWriter.cxx:268  UdpPacketTreeWriter.cxx:269  UdpPacketTreeWriter.cxx:270  UdpPacketTreeWriter.cxx:271  UdpPacketTreeWriter.cxx:272  UdpPacketTreeWriter.cxx:273  UdpPacketTreeWriter.cxx:274  UdpPacketTreeWriter.cxx:275  UdpPacketTreeWriter.cxx:276  UdpPacketTreeWriter.cxx:277  UdpPacketTreeWriter.cxx:278  UdpPacketTreeWriter.cxx:279  UdpPacketTreeWriter.cxx:280  UdpPacketTreeWriter.cxx:281  UdpPacketTreeWriter.cxx:282  UdpPacketTreeWriter.cxx:283  UdpPacketTreeWriter.cxx:284  UdpPacketTreeWriter.cxx:285  UdpPacketTreeWriter.cxx:286  UdpPacketTreeWriter.cxx:287  UdpPacketTreeWriter.cxx:288  UdpPacketTreeWriter.cxx:289  UdpPacketTreeWriter.cxx:290  UdpPacketTreeWriter.cxx:291  UdpPacketTreeWriter.cxx:292  UdpPacketTreeWriter.cxx:293  UdpPacketTreeWriter.cxx:294  UdpPacketTreeWriter.cxx:295  UdpPacketTreeWriter.cxx:296  UdpPacketTreeWriter.cxx:297  UdpPacketTreeWriter.cxx:298  UdpPacketTreeWriter.cxx:299  UdpPacketTreeWriter.cxx:300  UdpPacketTreeWriter.cxx:301  UdpPacketTreeWriter.cxx:302  UdpPacketTreeWriter.cxx:303  UdpPacketTreeWriter.cxx:304  UdpPacketTreeWriter.cxx:305  UdpPacketTreeWriter.cxx:306  UdpPacketTreeWriter.cxx:307  UdpPacketTreeWriter.cxx:308  UdpPacketTreeWriter.cxx:309  UdpPacketTreeWriter.cxx:310  UdpPacketTreeWriter.cxx:311  UdpPacketTreeWriter.cxx:312  UdpPacketTreeWriter.cxx:313  UdpPacketTreeWriter.cxx:314  UdpPacketTreeWriter.cxx:315  UdpPacketTreeWriter.cxx:316  UdpPacketTreeWriter.cxx:317  UdpPacketTreeWriter.cxx:318  UdpPacketTreeWriter.cxx:319  UdpPacketTreeWriter.cxx:320  UdpPacketTreeWriter.cxx:321  UdpPacketTreeWriter.cxx:322  UdpPacketTreeWriter.cxx:323  UdpPacketTreeWriter.cxx:324  UdpPacketTreeWriter.cxx:325  UdpPacketTreeWriter.cxx:326  UdpPacketTreeWriter.cxx:327  UdpPacketTreeWriter.cxx:328  UdpPacketTreeWriter.cxx:329  UdpPacketTreeWriter.cxx:330  UdpPacketTreeWriter.cxx:331  UdpPacketTreeWriter.cxx:332  UdpPacketTreeWriter.cxx:333  UdpPacketTreeWriter.cxx:334  UdpPacketTreeWriter.cxx:335  UdpPacketTreeWriter.cxx:336  UdpPacketTreeWriter.cxx:337