DABC (Data Acquisition Backbone Core)  2.9.9
Hierarchy.cxx
Go to the documentation of this file.
1 // $Id: Hierarchy.cxx 4476 2020-04-15 14:12:38Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "dabc/Hierarchy.h"
17 
18 #include <cstring>
19 #include <cstdlib>
20 
21 #include "dabc/defines.h"
22 #include "dabc/threads.h"
23 #include "dabc/Exception.h"
24 #include "dabc/Command.h"
25 #include "dabc/ConfigBase.h"
26 #include "dabc/ReferencesVector.h"
27 
28 const char* dabc::prop_version = "_version";
29 const char* dabc::prop_kind = "_kind";
30 const char* dabc::prop_realname = "_realname"; // real object name
31 const char* dabc::prop_masteritem = "_master";
32 const char* dabc::prop_producer = "_producer";
33 const char* dabc::prop_error = "_error";
34 const char* dabc::prop_auth = "_auth";
35 const char* dabc::prop_hash = "hash";
36 const char* dabc::prop_history = "_history";
37 const char* dabc::prop_time = "time";
38 const char* dabc::prop_more = "_more";
39 const char* dabc::prop_view = "_view";
40 
41 
42 uint64_t dabc::HistoryContainer::StoreSize(uint64_t version, int hlimit)
43 {
44  sizestream s;
45  Stream(s, version, hlimit);
46  return s.size();
47 }
48 
49 bool dabc::HistoryContainer::Stream(iostream& s, uint64_t version, int hlimit)
50 {
51  uint64_t pos = s.size();
52  uint64_t sz = 0;
53 
54  uint32_t storesz(0), storenum(0), storevers(0);
55 
56  if (s.is_output()) {
57  sz = s.is_real() ? StoreSize(version, hlimit) : 0;
58  storesz = sz / 8;
59 
60  uint32_t first = 0;
61  if ((hlimit>0) && (fArr.Size() > (unsigned) hlimit)) first = fArr.Size() - hlimit;
62  storenum = 0;
63  bool cross_boundary = false;
64  for (unsigned n=first; n<fArr.Size();n++) {
65  // we have longer history as requested
66  if ((version>0) && (fArr.Item(n).version <= version)) {
67  cross_boundary = fArr.Item(n).version < version;
68  continue;
69  }
70  storenum++;
71  }
72 
73  s.write_uint32(storesz);
74  s.write_uint32(storenum | (storevers<<24));
75 
76  uint64_t mask = cross_boundary ? 1 : 0;
77  s.write_uint64(mask);
78 
79  for (uint32_t n=first;n<fArr.Size();n++) {
80  if ((version>0) && (fArr.Item(n).version <= version)) continue;
81  fArr.Item(n).fields->Stream(s);
82  }
83 
84  } else {
85  s.read_uint32(storesz);
86  sz = ((uint64_t) storesz) * 8;
87  s.read_uint32(storenum);
88  // storevers = storenum >> 24;
89  storenum = storenum & 0xffffff;
90 
91  uint64_t mask(0);
92  s.read_uint64(mask);
93  fCrossBoundary = (mask & 1) != 0;
94 
95  if (fArr.Capacity()==0)
96  fArr.Allocate((int)storenum > hlimit ? (int) storenum : hlimit);
97 
98  for (uint32_t n=0;n<storenum;n++) {
99  RecordFieldsMap* fields = new RecordFieldsMap;
100  fields->Stream(s);
101 
102  if (fArr.Full()) fArr.PopOnly();
103  HistoryItem* h = fArr.PushEmpty();
104  h->version = 0; // here is not matter, when applied to other structure will be set
105  h->fields = fields;
106  }
107  }
108 
109  return s.verify_size(pos, sz);
110 }
111 
112 
114 {
115  if (null()) return false;
116 
117  // we could use value, restored from binary array
118  bool cross_boundary = GetObject()->fCrossBoundary;
119 
120  unsigned first = 0;
121  if ((res.hlimit()>0) && (GetObject()->fArr.Size() > res.hlimit()))
122  first = GetObject()->fArr.Size() - res.hlimit();
123 
124  for (unsigned n=first; n < GetObject()->fArr.Size();n++)
125  if (GetObject()->fArr.Item(n).version < res.version())
126  { cross_boundary = true; break; }
127 
128  // if specific version was defined, and we do not have history backward to that version
129  // we need to indicate this to the client
130  // Client in this case should cleanup its buffers while with gap
131  // one cannot correctly reconstruct history backwards
132  if (!cross_boundary) res.SetField("history_gap", xmlTrueValue);
133 
134  for (unsigned n=first; n < GetObject()->fArr.Size();n++) {
135  HistoryItem& item = GetObject()->fArr.Item(n);
136 
137  // we have longer history as requested
138  if ((res.version()>0) && (item.version <= res.version())) continue;
139 
140  res.BeforeNextChild("history");
141 
142  res.CreateNode(0);
143 
144  item.fields->SaveTo(res);
145 
146  res.CloseNode(0);
147  }
148 
149  res.CloseChilds();
150 
151  return true;
152 }
153 
154 
155 // ===============================================================================
156 
157 
159  dabc::RecordContainer(name, flNoMutex | flIsOwner),
160  fNodeVersion(0),
161  fNamesVersion(0),
162  fChildsVersion(0),
163  fAutoTime(false),
164  fPermanent(false),
165  fNodeChanged(false),
166  fNamesChanged(false),
167  fChildsChanged(false),
168  fDisableDataReading(false),
169  fDisableChildsReading(false),
170  fDisableReadingAsChild(false),
171  fBinData(),
172  fHist(),
173  fHierarchyMutex(0)
174 {
175  #ifdef DABC_EXTRA_CHECKS
176  DebugObject("Hierarchy", this, 1);
177  #endif
178 
179 // DOUT0("Constructor %s %p", GetName(), this);
180 }
181 
183 {
184  #ifdef DABC_EXTRA_CHECKS
185  DebugObject("Hierarchy", this, -1);
186  #endif
187 
188 // DOUT0("Destructor %s %p", GetName(), this);
189 
190  if (fHierarchyMutex!=0) {
191  delete fHierarchyMutex;
192  fHierarchyMutex = 0;
193  }
194 }
195 
196 
198 {
199  if (fHierarchyMutex==0) fHierarchyMutex = new Mutex;
200 }
201 
203 {
204  dabc::HierarchyContainer* parent = this;
205 
206  while (parent!=0) {
207  dabc::HierarchyContainer* top = dynamic_cast<dabc::HierarchyContainer*> (parent->GetParent());
208  if (top==0) return parent;
209  parent = top;
210  }
211 
212  EOUT("Should never happen");
213  return this;
214 }
215 
216 uint64_t dabc::HierarchyContainer::StoreSize(unsigned kind, uint64_t version, unsigned hlimit)
217 {
218  sizestream s;
219  Stream(s, kind, version, hlimit);
220  //DOUT0("HierarchyContainer::StoreSize %s %u", GetName(), (unsigned) s.size());
221  return s.size();
222 }
223 
224 bool dabc::HierarchyContainer::Stream(iostream& s, unsigned kind, uint64_t version, unsigned hlimit)
225 {
226  // stream used not only to write or read hierarchy in binary form
227  // at the same time it is used to store diff and restore from diff
228  // in such case one do not need to recreate everything from the beginning
229 
230  uint64_t pos = s.size();
231  uint64_t sz = 0;
232 
233  uint32_t storesz(0), storenum(0), storevers(0);
234 
235  //DOUT0("dabc::HierarchyContainer::Stream %s isout %s isreal %s", GetName(), DBOOL(s.is_output()), DBOOL(s.is_real()));
236 
237  if (s.is_output()) {
238  bool store_fields(true), store_childs(true), store_history(false), store_diff(false);
239  std::string fields_prefix;
240 
241  switch (kind) {
242  case stream_NamesList: // this is DNS case - only names list
243  fields_prefix = "_";
244  store_fields = fNamesVersion >= version;
245  store_childs = fNamesVersion >= version;
246  store_history = false;
247  store_diff = store_fields; // we indicate if only selected fields are stored
248  break;
249  case stream_Value: // only fields are stored
250  store_fields = true;
251  store_childs = false;
252  store_history = !fHist.null() && (hlimit>0);
253  store_diff = false;
254  break;
255  default: // full stream
256  store_fields = fNodeVersion >= version;
257  store_childs = fChildsVersion >= version;
258  store_history = !fHist.null() && (hlimit>0);
259  break;
260  }
261 
262  DOUT2("STORE %20s num_childs %u store %6s namesv %u nodevers %u childsvers %u", GetName(), NumChilds(), DBOOL(store_childs), fNamesVersion, fNodeVersion, fChildsVersion);
263 
264  uint64_t mask = (store_fields ? maskFieldsStored : 0) |
265  (store_childs ? maskChildsStored : 0) |
266  (store_diff ? maskDiffStored : 0) |
267  (store_history ? maskHistory : 0);
268 
269  sz = s.is_real() ? StoreSize(kind, version, hlimit) : 0;
270 
271  //if (s.is_real()) DOUT0("dabc::HierarchyContainer %s storesize %u", GetName(), (unsigned) sz);
272 
273  storesz = sz / 8;
274  if (store_childs) storenum = ((uint32_t) NumChilds());
275  storenum = storenum | (storevers<<24);
276 
277  s.write_uint32(storesz);
278  s.write_uint32(storenum);
279 
280  s.write_uint64(mask);
281 
282  if (store_fields) Fields().Stream(s, fields_prefix);
283 
284  if (store_history) fHist()->Stream(s, version, hlimit);
285 
286  if (store_childs)
287  for (unsigned n=0;n<NumChilds();n++) {
288  dabc::HierarchyContainer* child = dynamic_cast<dabc::HierarchyContainer*> (GetChild(n));
289  if (child==0) continue;
290  s.write_str(child->GetName());
291  child->Stream(s, kind, version, hlimit);
292  }
293 
294  //DOUT0("Write childs %u", (unsigned) s.size());
295 
296  } else {
297 
298  s.read_uint32(storesz);
299  sz = ((uint64_t) storesz)*8;
300  s.read_uint32(storenum);
301  // storevers = storenum >> 24;
302  storenum = storenum & 0xffffff;
303 
304  uint64_t mask(0);
305  s.read_uint64(mask);
306 
307  if (mask & maskFieldsStored) {
308  if (fDisableDataReading) {
309  if (!s.skip_object())
310  EOUT("FAIL to skip fields part in the streamer for %s", ItemName().c_str());
311  else
312  DOUT3("SKIP FIELDS in %s", ItemName().c_str());
313  } else {
314  fNodeChanged = true;
315  std::string prefix;
316  if (mask & maskDiffStored) { prefix = "_"; fNamesChanged = true; }
317  Fields().Stream(s, prefix);
318  }
319  }
320 
321  if (mask & maskHistory) {
322  if (fDisableDataReading) {
323  if (!s.skip_object())
324  EOUT("FAIL to skip history part in the streamer");
325  else
326  DOUT3("SKIP HISTORY in %s", ItemName().c_str());
327  } else {
328  if (fHist.null()) fHist.Allocate();
329  fHist()->Stream(s, version, hlimit);
330  }
331  }
332 
333  if (mask & maskChildsStored) {
334  // when childs cannot be deleted, also order of childs may be broken
335  // therefore in that case childs just inserted in arbitrary way
336  bool candeletechilds = (kind != stream_NoDelete);
337 
338  fChildsChanged = true;
339  unsigned tgtcnt = 0;
340  // exclude from update permanent items
341  if (candeletechilds)
342  while ((tgtcnt < NumChilds()) && ((HierarchyContainer*) GetChild(tgtcnt))->fPermanent) tgtcnt++;
343 
344  for (unsigned srcnum=0; srcnum<storenum; srcnum++) {
345  // first read name of next child
346  std::string childname;
347  s.read_str(childname);
348 
349  if (fDisableChildsReading) {
350  if (!s.skip_object())
351  EOUT("FAIL to skip child %s in %s", childname.c_str(), ItemName().c_str());
352  else
353  DOUT0("SKIP CHILD %s in %s", childname.c_str(), ItemName().c_str());
354  continue;
355  }
356 
357  dabc::HierarchyContainer* child = 0;
358 
359  // try to find item with such name in the current list
360  unsigned findindx = candeletechilds ? tgtcnt : 0;
361  while (findindx<NumChilds()) {
362  if (GetChild(findindx)->IsName(childname.c_str())) {
363  child = (HierarchyContainer*) GetChild(findindx);
364  break;
365  }
366  findindx++;
367  }
368 
369  if (child == 0) {
370  // if no child with such name found, create and add it in current position
371  child = new dabc::HierarchyContainer(childname);
372 
373  // TODO: may be tgtcnt should not be used when !candeletechilds is specified
374  AddChildAt(child, tgtcnt);
375  } else {
376  // we need to delete all skipped childs in between
377  if (candeletechilds)
378  while (findindx-- > tgtcnt) RemoveChildAt(tgtcnt, true);
379  }
380 
381  if (child->fDisableReadingAsChild) {
382  if (!s.skip_object())
383  EOUT("FAIL to skip item %s completely", child->ItemName().c_str());
384  else
385  DOUT3("SKIP item completely %s", child->ItemName().c_str());
386  } else {
387  child->Stream(s, kind, version, hlimit);
388  }
389 
390  tgtcnt++;
391  }
392 
393  // remove remained items at the end
394  if (candeletechilds)
395  while (tgtcnt < NumChilds()) RemoveChildAt(tgtcnt, true);
396  }
397  }
398 
399  return s.verify_size(pos, sz);
400 }
401 
402 
403 bool dabc::HierarchyContainer::SaveTo(HStore& res, bool create_node)
404 {
405  if (create_node)
406  res.CreateNode(GetName());
407 
408  fFields->SaveTo(res);
409 
410  if (res.mask() & storemask_TopVersion) {
411  res.SetField(dabc::prop_version, dabc::format("%lu", (long unsigned) fNodeVersion).c_str());
412  res.SetMask(res.mask() & ~storemask_TopVersion);
413  }
414 
415  if ((res.mask() & storemask_Version) != 0) {
416  res.SetField("node_ver", dabc::format("%lu", (long unsigned) fNodeVersion).c_str());
417  res.SetField("dns_ver", dabc::format("%lu", (long unsigned) fNamesVersion).c_str());
418  res.SetField("chld_ver", dabc::format("%lu", (long unsigned) fChildsVersion).c_str());
419  }
420 
421  if (((res.mask() & storemask_History) != 0) && !fHist.null())
422  fHist.SaveTo(res);
423 
424  if ((res.mask() & storemask_NoChilds) == 0) {
425  for (unsigned n=0;n<NumChilds();n++) {
426  dabc::HierarchyContainer* child = dynamic_cast<dabc::HierarchyContainer*> (GetChild(n));
427  if (child==0) continue;
428  res.BeforeNextChild();
429  child->SaveTo(res);
430  }
431  }
432 
433  if (create_node)
434  res.CloseNode(GetName());
435 
436  return true;
437 }
438 
439 
440 
441 void dabc::HierarchyContainer::SetModified(bool node, bool hierarchy, bool recursive)
442 {
443  if (node) fNodeChanged = true;
444  if (hierarchy) fChildsChanged = true;
445  if (recursive)
446  for (unsigned n=0;n<NumChilds();n++) {
447  dabc::HierarchyContainer* child = dynamic_cast<dabc::HierarchyContainer*> (GetChild(n));
448  if (child) child->SetModified(node, hierarchy, recursive);
449  }
450 }
451 
452 
454 {
455  Fields().CopyFrom(cont->Fields(), true);
456 
457  // verify if not was changed - do not clear flags, they may be required
458  if (!fNodeChanged) fNodeChanged = Fields().WasChanged();
459 
460  for (unsigned n=0;n<cont->NumChilds();n++) {
461  HierarchyContainer* src_chld = (HierarchyContainer*) cont->GetChild(n);
462 
463  HierarchyContainer* child = (HierarchyContainer*) FindChild(src_chld->GetName());
464  if (child == 0) {
465  child = new HierarchyContainer(src_chld->GetName());
466  AddChild(child);
467  }
468 
469  if (child->DuplicateHierarchyFrom(src_chld)) fChildsChanged = true;
470  }
471 
472  return fChildsChanged || fNodeChanged;
473 }
474 
475 
477 {
478  fNodeChanged = false;
479  fChildsChanged = false;
480 
481  if (cont==0) throw dabc::Exception(ex_Hierarchy, "empty container", ItemName());
482 
483  // we do not check names here - top object name can be different
484  // if (!IsName(obj->GetName())) throw dabc::Exception(ex_Hierarchy, "mismatch between object and hierarchy itme", ItemName());
485 
486  // we do like manually set/remove all fields, excluding protected fields
487  Fields().MoveFrom(cont->Fields());
488  if (Fields().WasChanged()) fNodeChanged = true;
489 
490  // now we should check if any childs were changed
491 
492  unsigned cnt1(0); // counter over source container
493  unsigned cnt2(0); // counter over existing childs
494 
495  // skip first permanent childs from update procedure
496  while (cnt2 < NumChilds() && ((HierarchyContainer*) GetChild(cnt2))->fPermanent) cnt2++;
497 
498  while ((cnt1 < cont->NumChilds()) || (cnt2 < NumChilds())) {
499  if (cnt1 >= cont->NumChilds()) {
500  RemoveChildAt(cnt2, true);
501  fChildsChanged = true;
502  continue;
503  }
504 
505  dabc::Hierarchy cont_child(cont->GetChild(cnt1));
506  if (cont_child.null()) {
507  EOUT("FAILURE");
508  return false;
509  }
510 
511  bool findchild(false);
512  unsigned findindx(0);
513 
514  for (unsigned n=cnt2;n<NumChilds();n++)
515  if (GetChild(n)->IsName(cont_child.GetName())) {
516  findchild = true;
517  findindx = n;
518  break;
519  }
520 
521  if (!findchild) {
522  // if child did not found, just take it out form source container and place at proper position
523 
524  // remove object and do not cleanup (destroy) it
525  cont->RemoveChild(cont_child(), false);
526 
527  cont_child()->SetModified(true, true, true);
528 
529  AddChildAt(cont_child(), cnt2);
530 
531  fChildsChanged = true;
532  cnt2++;
533 
534  continue;
535  }
536 
537  while (findindx > cnt2) { RemoveChildAt(cnt2, true); findindx--; fChildsChanged = true; }
538 
540 
541  if ((child==0) || !child->IsName(cont_child.GetName())) {
542  throw dabc::Exception(ex_Hierarchy, "mismatch between object and hierarchy item", ItemName());
543  return false;
544  }
545 
546  if (child->UpdateHierarchyFrom(cont_child())) fChildsChanged = true;
547 
548  cnt1++;
549  cnt2++;
550  }
551 
552  return fChildsChanged || fNodeChanged;
553 }
554 
556 {
557  while ((indx>=0) && (indx<(int) NumChilds())) {
559  if (child->IsName(name.c_str())) return child;
560  RemoveChildAt(indx, true);
561  }
562 
564  AddChild(res);
565 
566  //fNamesChanged = true;
567  //fChildsChanged = true;
568 
569  return res;
570 }
571 
572 
574 {
575  std::string res;
576  FillFullName(res, 0, true);
577  return res;
578 }
579 
580 
582 {
583  if (top.null()) return;
584 
585  top()->BuildFieldsMap(&Fields());
586 
587  if (top()->IsChildsHidden()) return;
588 
589  ReferencesVector chlds;
590  if (!top.GetAllChildRef(&chlds)) return;
591 
592  for (unsigned n=0;n<chlds.GetSize();n++) {
593 
594  if (chlds[n].GetObject()->IsHidden()) continue;
595 
596  HierarchyContainer* chld = new HierarchyContainer(chlds[n].GetName());
597  AddChild(chld);
598  chld->BuildObjectsHierarchy(chlds[n]);
599  }
600 }
601 
602 
604 {
605  if (fHist.Capacity()==0) return;
606  if (fHist()->fArr.Full()) fHist()->fArr.PopOnly();
607  HistoryItem* h = fHist()->fArr.PushEmpty();
608  h->version = fNodeVersion;
609  h->fields = diff;
610 }
611 
613 {
614  if (fHist.Capacity()<=step) return false;
615 
616  RecordFieldsMap* hfields = fHist()->fArr.Item(fHist.Capacity()-step-1).fields;
617 
618  fields->ApplyDiff(*hfields);
619 
620  return true;
621 }
622 
623 
625 {
626  if (fHist.Capacity()==0) return;
627  while (fHist()->fArr.Size() > 0) fHist()->fArr.PopOnly();
628 }
629 
630 
632 {
633  if (fNodeChanged || fChildsChanged) return true;
634 
635  if (Fields().WasChanged()) { fNodeChanged = true; return true; }
636 
637  if (withchilds)
638  for (unsigned indx=0; indx < NumChilds(); indx++) {
640  if (child && child->IsNodeChanged(withchilds)) {
641  fChildsChanged = true;
642  return true;
643  }
644  }
645 
646  return false;
647 }
648 
650 {
651  if (!fHist.null()) return fHist.DoHistory();
652 
653  HierarchyContainer* prnt = dynamic_cast<HierarchyContainer*> (GetParent());
654  while (prnt != nullptr) {
655 
656  if (prnt->fHist.DoHistory() && prnt->fHist()->fChildsEnabled) {
657  fHist.Allocate(prnt->fHist.Capacity());
658  fHist()->fEnabled = true;
659  fHist()->fChildsEnabled = true;
660  Fields().Field(prop_history).SetUInt(prnt->fHist.Capacity());
661  return true;
662  }
663 
664  prnt = dynamic_cast<HierarchyContainer*> (prnt->GetParent());
665  }
666 
667  return false;
668 }
669 
673  change_Childs = 0x4
674 };
675 
676 
677 void dabc::HierarchyContainer::MarkReading(bool withchilds, bool readvalues, bool readchilds)
678 {
679  if (withchilds)
680  for (unsigned indx=0; indx < NumChilds(); indx++) {
682  if (child) child->MarkReading(withchilds, readvalues, readchilds);
683  }
684 
685  fDisableDataReading = !readvalues;
686  fDisableChildsReading = !readchilds;
687 }
688 
689 
690 unsigned dabc::HierarchyContainer::MarkVersionIfChanged(uint64_t ver, uint64_t& tm, bool withchilds)
691 {
692  unsigned mask = 0;
693 
694  if (withchilds)
695  for (unsigned indx=0; indx < NumChilds(); indx++) {
697  if (child) mask = mask | child->MarkVersionIfChanged(ver, tm, withchilds);
698  }
699 
700  if (mask != 0) fNodeChanged = true;
701 
702  if (mask & change_Names) fNamesChanged = true;
703 
704  // if any child was changed directly (bit 1)
705  if (mask & (change_Value | change_Childs)) fChildsChanged = true;
706 
707  bool fields_were_chaneged = Fields().WasChanged();
708 
709  if (fields_were_chaneged) {
710  fNodeChanged = true;
711  if (Fields().WasChangedWith("_")) fNamesChanged = true;
712  }
713 
714  if (fNodeChanged) {
715 
716  if (fNodeChanged) { fNodeVersion = ver; mask = mask | change_Value; }
717  if (fNamesChanged) { fNamesVersion = ver; mask = mask | change_Names; }
718  if (fChildsChanged) { fChildsVersion = ver; mask = mask | change_Childs; }
719 
720  if (fNodeChanged && fAutoTime) {
721  if (tm==0) tm = dabc::DateTime().GetNow().AsJSDate();
722  Fields().Field(prop_time).SetDatime(tm);
723  }
724 
725  if (CheckIfDoingHistory() && fields_were_chaneged) {
726  // we need to be sure that really something changed,
727  // otherwise we will produce empty entry
728  RecordFieldsMap *prev = fHist()->fPrev;
729 
730  if (prev != nullptr) {
731  prev->MakeAsDiffTo(Fields());
732  AddHistory(prev);
733  }
734 
735  fHist()->fPrev = Fields().Clone();
736  }
737 
738  // clear flags only after we produce diff
739  Fields().ClearChangeFlags();
740  fNodeChanged = false;
741  fNamesChanged = false;
742  fChildsChanged = false;
743  }
744 
745  return mask;
746 }
747 
749 {
750  const HierarchyContainer* top = this, *prnt = this;
751 
752  while (prnt!=0) {
753  top = prnt;
754  prnt = dynamic_cast<const HierarchyContainer*> (prnt->GetParent());
755  }
756 
757  return top->GetVersion() + 1;
758 }
759 
760 
762 {
763  uint64_t next_ver = GetNextVersion();
764 
765  // mark node and childs
766  unsigned mask = MarkVersionIfChanged(next_ver, tm, true);
767 
768  if (mask == 0) return;
769 
770  // mark changes in parent
771  HierarchyContainer* prnt = dynamic_cast<HierarchyContainer*> (GetParent());
772  while (prnt != 0) {
773  prnt->fNodeChanged = true;
774  if (mask & change_Names) prnt->fNamesChanged = true;
775  if (mask & (change_Value | change_Childs)) prnt->fChildsChanged = true;
776 
777  prnt->MarkVersionIfChanged(next_ver, tm, false);
778  prnt = dynamic_cast<HierarchyContainer*> (prnt->GetParent());
779  }
780 }
781 
783 {
784  fAutoTime = true;
785  if (withchilds)
786  for (unsigned indx=0; indx < NumChilds(); indx++) {
788  if (child) child->EnableTimeRecording(withchilds);
789  }
790 }
791 
792 // __________________________________________________-
793 
794 
796 {
797  if (null()) Create("Objects");
798  GetObject()->BuildObjectsHierarchy(top);
799 }
800 
801 
803 {
804  if (src.null()) {
805  // now release will work - any hierarchy will be deleted once no any other refs exists
806  Release();
807  return true;
808  }
809 
810  if (null()) {
811  EOUT("Hierarchy structure MUST exist at this moment");
812  Create("DABC");
813  }
814 
815  if (GetObject()->UpdateHierarchyFrom(src()))
816  GetObject()->MarkChangedItems();
817 
818  return true;
819 }
820 
822 {
823  if (src.null()) return true;
824 
825  if (null()) {
826  EOUT("Hierarchy structure MUST exist at this moment");
827  Create("DABC");
828  }
829 
830  if (GetObject()->DuplicateHierarchyFrom(src()))
831  GetObject()->MarkChangedItems();
832 
833  return true;
834 }
835 
836 
837 void dabc::Hierarchy::EnableHistory(unsigned length, bool withchilds)
838 {
839  if (null()) return;
840 
841  if (length>0) GetObject()->EnableTimeRecording(withchilds);
842 
843  if (GetObject()->fHist.Capacity() != length) {
844  if (length>0) {
845  GetObject()->fHist.Allocate(length);
846  GetObject()->fHist()->fEnabled = true;
847  GetObject()->fHist()->fChildsEnabled = withchilds;
848  SetField(prop_history, length);
849  } else {
850  GetObject()->fHist.Release();
851  RemoveField(prop_history);
852  }
853  }
854 }
855 
856 
858 {
859  return null() ? false : GetObject()->fHist.DoHistory();
860 }
861 
862 
864 {
865  if (null() || (GetObject()->fHist.Capacity() == 0)) return false;
866 
867  // we have actual copy of remote history when request was done after last hierarchy update
868  return ((GetObject()->fHist()->fRemoteReqVersion > 0) &&
869  (GetObject()->fHist()->fLocalReqVersion == GetObject()->GetVersion()));
870 }
871 
872 
873 dabc::Buffer dabc::Hierarchy::SaveToBuffer(unsigned kind, uint64_t version, unsigned hlimit)
874 {
875  if (null()) return dabc::Buffer();
876 
877  uint64_t size = GetObject()->StoreSize(kind, version, hlimit);
878 
880  if (res.null()) return res;
881 
882  memstream outs(false, (char*) res.SegmentPtr(), res.SegmentSize());
883 
884  if (GetObject()->Stream(outs, kind, version, hlimit)) {
885 
886  if (size != outs.size()) { EOUT("Sizes mismatch %lu %lu", (long unsigned) size, (long unsigned) outs.size()); }
887 
888  res.SetTotalSize(size);
889  } else {
890  res.Release();
891  }
892 
893  return res;
894 }
895 
897 {
898  if (buf.null()) return false;
899 
900  memstream inps(true, (char*) buf.SegmentPtr(), buf.SegmentSize());
901 
902  if (null()) Create("RAW");
903 
904  if (!GetObject()->Stream(inps)) {
905  EOUT("Cannot reconstruct hierarchy from the binary data!");
906  return false;
907  }
908 
909  return true;
910 }
911 
913 {
914  if (buf.null()) return false;
915 
916  if (null()) {
917  EOUT("Hierarchy must be created before it can be updated");
918  Create("TOP");
919  }
920 
921  memstream inps(true, (char*) buf.SegmentPtr(), buf.SegmentSize());
922 
923  if (!GetObject()->Stream(inps, kind)) {
924  EOUT("Cannot reconstruct hierarchy from the binary data!");
925  return false;
926  }
927 
928  GetObject()->MarkChangedItems();
929 
930  return true;
931 }
932 
933 
934 void dabc::Hierarchy::Create(const std::string &name, bool withmutex)
935 {
936  Release();
937 
938  HierarchyContainer* cont = new HierarchyContainer(name);
939  if (withmutex) cont->CreateHMutex();
940  SetObject(cont);
941 }
942 
943 
944 dabc::Hierarchy dabc::Hierarchy::GetHChild(const std::string &name, bool allowslahes, bool force, bool sortorder)
945 {
946  // DOUT0("GetHChild main:%p name:%s force %s", this, name.c_str(), DBOOL(force));
947 
948  // if name empty, return null
949  if (name.empty()) return dabc::Hierarchy();
950 
951  size_t pos = name.rfind("/");
952  if ((pos != std::string::npos) && !allowslahes) {
953  if (pos==0) return GetHChild(name.substr(1), allowslahes, force, sortorder);
954  if (pos==name.length()-1) return GetHChild(name.substr(0, name.length()-1), allowslahes, force, sortorder);
955  return GetHChild(name.substr(0, pos), allowslahes, force, sortorder).GetHChild(name.substr(pos+1), allowslahes, force, sortorder);
956  }
957 
958  std::string itemname = name;
959  if (pos != std::string::npos) itemname = itemname.substr(pos+1);
960  if (itemname.empty()) itemname = "item";
961 
962  // replace all special symbols which can make problem in http (not in xml)
963  while ((pos = itemname.find_first_of("#:&?")) != std::string::npos)
964  itemname.replace(pos, 1, "_");
965 
966  if (itemname == name) {
967  // simple case - no any special symbols
968  dabc::Hierarchy res = FindChild(name.c_str());
969  if (!res.null() && !res.HasField(dabc::prop_realname)) {
970  return res;
971  } else if (res.null() && !force) {
972  return res;
973  }
974  }
975 
976  int first_big = -1;
977 
978  for (unsigned n=0;n<NumChilds();n++) {
979  dabc::Hierarchy res = GetChild(n);
980 
981  std::string realname = res.GetName();
982  if (res.HasField(dabc::prop_realname))
983  realname = res.GetField(dabc::prop_realname).AsStr();
984 
985  if (realname == name) return res;
986 
987  if (sortorder && (first_big < 0) && (realname > name))
988  first_big = (int) n;
989  }
990 
991  if (!force) return dabc::Hierarchy();
992 
993  if (itemname != name) {
994  unsigned cnt = NumChilds();
995  std::string basename = itemname;
996 
997  // prevent same item name
998  while (!FindChild(itemname.c_str()).null())
999  itemname = basename + std::to_string(cnt++);
1000  }
1001 
1002  dabc::Hierarchy res = new dabc::HierarchyContainer(itemname);
1003 
1004  if (!sortorder || (first_big < 0))
1005  GetObject()->AddChild(res.GetObject());
1006  else
1007  GetObject()->AddChildAt(res.GetObject(), first_big);
1008 
1009  if (itemname != name)
1010  res.SetField(dabc::prop_realname, name);
1011 
1012  //fNamesChanged = true;
1013  //fChildsChanged = true;
1014 
1015  return res;
1016 }
1017 
1018 bool dabc::Hierarchy::RemoveHChild(const std::string &path, bool allowslahes)
1019 {
1020  dabc::Hierarchy h = GetHChild(path, allowslahes);
1021  if (h.null()) return false;
1022 
1023  dabc::Hierarchy prnt = h.GetParentRef();
1024  h.Destroy();
1025  while (!prnt.null() && (prnt() != GetObject())) {
1026  h << prnt;
1027  prnt = h.GetParentRef();
1028  if (h.NumChilds() != 0) break;
1029  h.Destroy(); // delete as long no any other involved
1030  }
1031  return true;
1032 }
1033 
1034 
1036 {
1037  if (null() || (GetParent()==0) || !HasField(dabc::prop_masteritem)) return dabc::Hierarchy();
1038 
1039  std::string masteritem = GetField(dabc::prop_masteritem).AsStr();
1040 
1041  if (masteritem.empty()) return dabc::Hierarchy();
1042 
1043  return GetParent()->FindChildRef(masteritem.c_str());
1044 }
1045 
1046 
1047 bool dabc::Hierarchy::IsBinItemChanged(const std::string &itemname, uint64_t hash, uint64_t last_version)
1048 {
1049  if (null()) return false;
1050 
1051  dabc::Hierarchy item;
1052  if (itemname.empty()) item = *this; else item = FindChild(itemname.c_str());
1053 
1054  // if item for the object not found, we suppose to always have changed object
1055  if (item.null()) return true;
1056 
1057  // if there is no hash information provided, we always think that binary data is changed
1058  if (hash==0) return true;
1059 
1060  if (item.Field(dabc::prop_hash).AsUInt() != hash) {
1061  item.SetField(dabc::prop_hash, hash);
1062  item.SetFieldProtected(dabc::prop_hash, true);
1063  item.MarkChangedItems();
1064  }
1065 
1066  return (last_version==0) || (last_version<item.GetVersion());
1067 }
1068 
1069 
1070 bool dabc::Hierarchy::FillBinHeader(const std::string &itemname, dabc::Command& cmd, uint64_t mhash, const std::string &dflt_master_name)
1071 {
1072  if (null()) return false;
1073 
1074  dabc::Hierarchy item, master;
1075  if (itemname.empty()) item = *this;
1076  else item = FindChild(itemname.c_str());
1077 
1078  if (item.null() && !dflt_master_name.empty()) {
1079  master = FindChild(dflt_master_name.c_str());
1080  DOUT2("Found default master %s res = %p", dflt_master_name.c_str(), master());
1081  } else {
1082  master = item.FindMaster();
1083  }
1084 
1085  if (!master.null() && (mhash!=0) && (master.GetField(dabc::prop_hash).AsUInt()!=mhash)) {
1086  master.SetField(dabc::prop_hash, mhash);
1087  master.SetFieldProtected(dabc::prop_hash, true);
1088  master.MarkChangedItems();
1089  }
1090 
1091  if (!item.null()) cmd.SetUInt("BVersion", item.GetVersion());
1092  if (!master.null()) cmd.SetUInt("MVersion", master.GetVersion());
1093 
1094  return true;
1095 }
1096 
1097 
1098 std::string dabc::Hierarchy::FindBinaryProducer(std::string& request_name, bool topmost)
1099 {
1100  dabc::Hierarchy parent = *this;
1101  std::string producer_name;
1102 
1103  // we need to find parent on the most-top position with binary_producer property
1104  while (!parent.null()) {
1105  if (parent.HasField(dabc::prop_producer)) {
1106  producer_name = parent.Field(dabc::prop_producer).AsStr();
1107  request_name = RelativeName(parent);
1108  if (!topmost) break;
1109  }
1110  parent = parent.GetParentRef();
1111  }
1112 
1113  return producer_name;
1114 }
1115 
1116 
1117 bool dabc::Hierarchy::RemoveEmptyFolders(const std::string &path)
1118 {
1119  dabc::Hierarchy h = GetFolder(path);
1120  if (h.null()) return false;
1121 
1122  dabc::Hierarchy prnt = h.GetParentRef();
1123  h.Destroy();
1124  while (!prnt.null() && (prnt() != GetObject())) {
1125  h << prnt;
1126  prnt = h.GetParentRef();
1127  if (h.NumChilds() != 0) break;
1128  h.Destroy(); // delete as long no any other involved
1129  }
1130  return true;
1131 }
1132 
1133 std::string dabc::Hierarchy::ItemName() const
1134 {
1135  if (null()) return std::string();
1136  return GetObject()->ItemName();
1137 }
1138 
1140 {
1141  HierarchyContainer* obj = GetObject();
1142  while (obj!=0) {
1143  HierarchyContainer* prnt = dynamic_cast<HierarchyContainer*> (obj->GetParent());
1144  if (prnt == 0) break;
1145  obj = prnt;
1146  }
1147  return dabc::Hierarchy(obj);
1148 }
1149 
1151 {
1152  Object* prnt = GetParent();
1153 
1154  return prnt ? prnt->RemoveChild(GetObject(), false) : true;
1155 }
1156 
1158 {
1159  if (!null()) GetObject()->MarkReading(withchlds, false, false);
1160 }
1161 
1163 {
1164  if (!null()) GetObject()->fDisableReadingAsChild = true;
1165 }
1166 
1168 {
1169  if (null()) return;
1170  GetObject()->MarkReading(false, true, true);
1171 
1172  if (upto.null()) return;
1173 
1174  dabc::Hierarchy prnt = GetParentRef();
1175 
1176  while (!prnt.null()) {
1177  prnt()->MarkReading(false, false, true);
1178  if (prnt == upto) break;
1179  prnt = prnt.GetParentRef();
1180  }
1181 }
1182 
1183 
1184 // =====================================================
1185 
1186 namespace dabc {
1188  friend class HistoryIter;
1189 
1190  protected:
1192  int fCnt;
1193 
1194  bool next()
1195  {
1196  if (fSrc.null()) return false;
1197 
1198  if (fCnt<=0) {
1199  RecordFieldsMap* fields = fSrc()->Fields().Clone();
1200  SetFieldsMap(fields);
1201  fCnt=1;
1202  return true;
1203  }
1204 
1205  if (fSrc()->ExtractHistoryStep(&Fields(), fCnt-1)) {
1206  fCnt++;
1207  return true;
1208  }
1209 
1211  fCnt = 0;
1212 
1213  return false;
1214  }
1215 
1216  public:
1217 
1219  RecordContainer(src.GetName()),
1220  fSrc(src),
1221  fCnt(0)
1222  {
1223  }
1224 
1225  };
1226 }
1227 
1228 
1230 {
1231  HistoryIterContainer* cont = dynamic_cast<HistoryIterContainer*> (GetObject());
1232 
1233  return cont ? cont->next() : false;
1234 }
1235 
1237 {
1238  dabc::HistoryIter res;
1239 
1240  if (!null())
1241  res = new HistoryIterContainer(*this);
1242 
1243  return res;
1244 }
1245 
ChangeBits
Definition: Hierarchy.cxx:670
@ change_Childs
Definition: Hierarchy.cxx:673
@ change_Value
Definition: Hierarchy.cxx:671
@ change_Names
Definition: Hierarchy.cxx:672
Reference on memory from memory pool.
Definition: Buffer.h:135
unsigned SegmentSize(unsigned n=0) const
Returns size on the segment, no any boundary checks.
Definition: Buffer.h:174
void SetTotalSize(BufferSize_t len)
Set total length of the buffer to specified value Size cannot be bigger than original size of the buf...
Definition: Buffer.cxx:99
static Buffer CreateBuffer(BufferSize_t sz)
This static method create independent buffer for any other memory pools Therefore it can be used in s...
Definition: Buffer.cxx:419
void * SegmentPtr(unsigned n=0) const
Returns pointer on the segment, no any boundary checks.
Definition: Buffer.h:171
Represents command with its arguments.
Definition: Command.h:99
bool SetUInt(const std::string &name, unsigned v)
Definition: Command.h:147
Class for holding GMT time with precision of nanoseconds.
Definition: timing.h:190
uint64_t AsJSDate() const
Return date and time in JS format - number of millisecond since 1.1.1970.
Definition: timing.cxx:158
DateTime & GetNow()
Definition: timing.cxx:147
DABC exception.
Definition: Exception.h:57
class, used for direct store of records in JSON/XML form
Definition: Record.h:179
unsigned hlimit() const
Definition: Record.h:210
void CloseNode(const char *nodename)
Definition: Record.cxx:221
void SetField(const char *name, const char *value)
Definition: Record.cxx:170
void CloseChilds()
Definition: Record.cxx:277
void BeforeNextChild(const char *basename=0)
Definition: Record.cxx:247
unsigned mask() const
Definition: Record.h:206
void SetMask(unsigned m)
Definition: Record.h:207
uint64_t version() const
Definition: Record.h:209
void CreateNode(const char *nodename)
Definition: Record.cxx:145
bool fChildsChanged
indicate if something was changed in the hierarchy
Definition: Hierarchy.h:173
HierarchyContainer(const std::string &name)
Definition: Hierarchy.cxx:158
uint64_t GetNextVersion() const
Definition: Hierarchy.cxx:748
unsigned MarkVersionIfChanged(uint64_t ver, uint64_t &tm, bool withchilds)
If item changed, marked with version, time stamp applied, history recording returns mask with changes...
Definition: Hierarchy.cxx:690
void AddHistory(RecordFieldsMap *diff)
Add new entry to history.
Definition: Hierarchy.cxx:603
bool CheckIfDoingHistory()
Return true if history activated for the node If necessary, history object will be initialized.
Definition: Hierarchy.cxx:649
std::string ItemName()
Definition: Hierarchy.cxx:573
History fHist
special object with history data
Definition: Hierarchy.h:181
void ClearHistoryEntries()
Clear all entries in history, but not history object itself.
Definition: Hierarchy.cxx:624
HierarchyContainer * TopParent()
Definition: Hierarchy.cxx:202
bool ExtractHistoryStep(RecordFieldsMap *fields, unsigned step)
Extract values of specified history step.
Definition: Hierarchy.cxx:612
HierarchyContainer * CreateChildAt(const std::string &name, int indx)
Create child with specified name.
Definition: Hierarchy.cxx:555
bool fNodeChanged
indicate if something was changed in the node during update
Definition: Hierarchy.h:171
void SetModified(bool node, bool hierarchy, bool recursive=false)
Switch on node or hierarchy modified flags.
Definition: Hierarchy.cxx:441
uint64_t GetVersion() const
Definition: Hierarchy.h:265
bool DuplicateHierarchyFrom(HierarchyContainer *cont)
Duplicate hierarchy from provided container.
Definition: Hierarchy.cxx:453
void MarkReading(bool withchilds, bool readvalues, bool readchilds)
Mark reading flags.
Definition: Hierarchy.cxx:677
void EnableTimeRecording(bool withchilds=true)
Enable time recording for hierarchy element every time when item is changed.
Definition: Hierarchy.cxx:782
bool UpdateHierarchyFrom(HierarchyContainer *cont)
Update hierarchy from provided container.
Definition: Hierarchy.cxx:476
bool Stream(iostream &s, unsigned kind=stream_Full, uint64_t v=0, unsigned hist_limit=0)
Definition: Hierarchy.cxx:224
bool fDisableReadingAsChild
when true, object will not be updated when provided as child
Definition: Hierarchy.h:177
virtual bool SaveTo(HStore &res, bool create_node=true)
Save hierarchy in json/xml form.
Definition: Hierarchy.cxx:403
bool fNamesChanged
indicate if DNS structure was changed (either childs or relevant dabc fields)
Definition: Hierarchy.h:172
void BuildObjectsHierarchy(const Reference &top)
Definition: Hierarchy.cxx:581
void MarkChangedItems(uint64_t tm=0)
Central method, which analyzes all possible changes in node (and its childs) If any changes found,...
Definition: Hierarchy.cxx:761
bool IsNodeChanged(bool withchilds=true)
Returns true if any node field was changed or removed/inserted If specified, all childs will be check...
Definition: Hierarchy.cxx:631
uint64_t StoreSize(unsigned kind=stream_Full, uint64_t v=0, unsigned hist_limit=0)
Definition: Hierarchy.cxx:216
Represents objects hierarchy of remote (or local) DABC process.
Definition: Hierarchy.h:285
bool IsBinItemChanged(const std::string &itemname, uint64_t hash, uint64_t last_version=0)
Return true if one could suppose that binary item is changed and binary data must be regenerated.
Definition: Hierarchy.cxx:1047
void DisableReading(bool withchlds=true)
Mark all elements that non of data will be read.
Definition: Hierarchy.cxx:1157
bool FillBinHeader(const std::string &itemname, dabc::Command &cmd, uint64_t mhash=0, const std::string &dflt_master_name="")
Fill binary header with item and master versions.
Definition: Hierarchy.cxx:1070
Hierarchy GetTop() const
Returns reference on the top element of the hierarchy.
Definition: Hierarchy.cxx:1139
void DisableReadingAsChild()
Disable reading of element when it appears as child in the structure.
Definition: Hierarchy.cxx:1162
Hierarchy FindMaster() const
Find master item It is used in ROOT to specify position of streamer info.
Definition: Hierarchy.cxx:1035
bool HasLocalHistory() const
Returns true if item records history local, no need to request any other sources.
Definition: Hierarchy.cxx:857
void MarkChangedItems(uint64_t tm=0)
If any field was modified, item will be marked with new version.
Definition: Hierarchy.h:330
uint64_t GetVersion() const
Returns actual version of hierarchy entry.
Definition: Hierarchy.h:349
bool Duplicate(const Hierarchy &src)
Duplicate hierarchy from the source.
Definition: Hierarchy.cxx:821
bool RemoveHChild(const std::string &name, bool allowslahes=false)
Delete H item, including all empty parent folders.
Definition: Hierarchy.cxx:1018
std::string ItemName() const
Name which is used as item name in hierarchy.
Definition: Hierarchy.cxx:1133
bool DettachFromParent()
Detach from parent object.
Definition: Hierarchy.cxx:1150
const RecordField & Field(const std::string &name) const
Definition: Hierarchy.h:304
Hierarchy GetHChild(const std::string &name, bool allowslahes=false, bool force=false, bool sortorder=false)
Return child, if necessary creates with full subfolder If force specified, missing childs and folders...
Definition: Hierarchy.cxx:944
HistoryIter MakeHistoryIter()
Produce history iterator.
Definition: Hierarchy.cxx:1236
bool RemoveEmptyFolders(const std::string &path)
Removes folder and its parents as long as no other childs are present.
Definition: Hierarchy.cxx:1117
void EnableReading(const Hierarchy &upto=nullptr)
Enable element and all its parents to read data.
Definition: Hierarchy.cxx:1167
void Create(const std::string &name, bool withmutex=false)
Create top-level object with specified name.
Definition: Hierarchy.cxx:934
std::string FindBinaryProducer(std::string &request_name, bool topmost=true)
Search for parent element, where binary_producer property is specified Returns name of binary produce...
Definition: Hierarchy.cxx:1098
bool UpdateFromBuffer(const dabc::Buffer &buf, HierarchyStreamKind kind=stream_Full)
Apply modification to hierarchy, using stored binary data
Definition: Hierarchy.cxx:912
bool HasActualRemoteHistory() const
Returns true if remote history is recorded and it is up-to-date.
Definition: Hierarchy.cxx:863
bool ReadFromBuffer(const dabc::Buffer &buf)
Read hierarchy from buffer.
Definition: Hierarchy.cxx:896
bool Update(Hierarchy &src)
Reconstruct complete hierarchy, setting node/structure modifications fields correctly.
Definition: Hierarchy.cxx:802
void BuildNew(Reference top)
Build objects hierarchy, referenced by top.
Definition: Hierarchy.cxx:795
void EnableHistory(unsigned length=100, bool withchilds=false)
Activate history production for selected element and its childs.
Definition: Hierarchy.cxx:837
bool Stream(iostream &s, uint64_t version, int hist_limit=-1)
Definition: Hierarchy.cxx:49
uint64_t StoreSize(uint64_t version, int hist_limit=-1)
Definition: Hierarchy.cxx:42
HistoryIterContainer(Hierarchy &src)
Definition: Hierarchy.cxx:1218
bool DoHistory() const
Definition: Hierarchy.h:108
bool SaveTo(HStore &res)
Definition: Hierarchy.cxx:113
unsigned Capacity() const
Definition: Hierarchy.h:110
posix pthread mutex
Definition: threads.h:61
Base class for most of the DABC classes.
Definition: Object.h:116
bool RemoveChild(Object *child, bool cleanup=true)
Detach child from parent object If cleanup==true and parent is owner of child, child will be destroye...
Definition: Object.cxx:604
bool IsName(const char *str) const
Checks if object name is same as provided string, thread safe
Definition: Object.h:298
Object * GetParent() const
Returns pointer on parent object, thread safe
Definition: Object.h:286
const char * GetName() const
Returns name of the object, thread safe
Definition: Object.h:295
unsigned NumChilds() const
returns number of child objects
Definition: Object.cxx:670
Object * GetChild(unsigned n) const
returns pointer on child object
Definition: Object.cxx:677
Container for records fields.
Definition: Record.h:440
void SetFieldsMap(RecordFieldsMap *newmap)
Replaces existing fields map.
Definition: Record.cxx:1627
RecordFieldsMap & Fields() const
Definition: Record.h:488
uint64_t AsUInt(uint64_t dflt=0) const
Definition: Record.cxx:525
std::string AsStr(const std::string &dflt="") const
Definition: Record.cxx:749
void ApplyDiff(const RecordFieldsMap &diff)
Apply diff map One should use fields, generated with MakeAsDiffTo call.
Definition: Record.cxx:1586
void MakeAsDiffTo(const RecordFieldsMap &src)
In the map only modified fields are remained Also dabc:delete field can appear which marks all remove...
Definition: Record.cxx:1570
bool Stream(iostream &s, const std::string &nameprefix="")
Definition: Record.cxx:1467
bool SaveTo(HStore &res)
Save all field in json format.
Definition: Record.cxx:1529
dabc::Buffer SaveToBuffer()
Definition: Record.cxx:1712
bool SetFieldProtected(const std::string &name, bool on=true)
Definition: Record.h:526
RecordField GetField(const std::string &name) const
Definition: Record.h:510
bool HasField(const std::string &name) const
Definition: Record.h:498
bool SetField(const std::string &name, const RecordField &v)
Definition: Record.h:516
Reference on the arbitrary object
Definition: Reference.h:73
void Release()
Releases reference on the object.
Definition: Reference.cxx:138
const char * GetName() const
Return name of referenced object, if object not assigned, returns "---".
Definition: Reference.cxx:167
Reference GetParentRef() const
Returns reference on parent object.
Definition: Reference.h:135
Object * GetObject() const
Return pointer on the object.
Definition: Reference.h:129
bool GetAllChildRef(ReferencesVector *vect) const
Return references for all childs.
Definition: Reference.cxx:204
unsigned NumChilds() const
Return number of childs in referenced object.
Definition: Reference.cxx:194
bool null() const
Returns true if reference contains nullptr.
Definition: Reference.h:151
void Destroy()
Release reference and starts destroyment of referenced object.
Definition: Reference.cxx:148
Vector of dabc::Reference objects.
unsigned GetSize() const
Returns number of items in vector.
class to stream binary data
Definition: Record.h:41
bool write_uint32(uint32_t v)
Definition: Record.h:77
virtual bool is_real() const
Definition: Record.h:58
bool read_uint64(uint64_t &v)
Definition: Record.h:85
bool read_uint32(uint32_t &v)
Definition: Record.h:83
bool is_output() const
Definition: Record.h:57
virtual uint64_t size() const
return number of bytes, written or read from the stream
Definition: Record.h:71
bool skip_object()
Insted of reading object we read size and shift on that size Only can be done where size stored as 32...
Definition: Record.cxx:23
bool write_uint64(uint64_t v)
Definition: Record.h:79
bool read_str(std::string &str)
Restore string from the stream.
Definition: Record.cxx:94
bool write_str(const std::string &str)
Store string in the stream.
Definition: Record.cxx:76
bool verify_size(uint64_t pos, uint64_t sz)
Definition: Record.cxx:33
iostream class, which write and read data from memory
Definition: Record.h:133
virtual uint64_t size() const
return number of bytes, written or read from the stream
Definition: Record.h:145
special class only to define how many data will be written to the stream
Definition: Record.h:102
virtual uint64_t size() const
return number of bytes, written or read from the stream
Definition: Record.h:116
#define DOUT2(args ...)
Definition: logging.h:170
#define DOUT0(args ...)
Definition: logging.h:156
#define DOUT3(args ...)
Definition: logging.h:176
#define EOUT(args ...)
Definition: logging.h:150
#define DBOOL(arg)
Definition: logging.h:191
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
Definition: XmlEngine.cxx:917
void AddChild(XMLNodePointer_t parent, XMLNodePointer_t child)
Definition: XmlEngine.cxx:652
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode)
Definition: XmlEngine.cxx:906
Event manipulation API.
Definition: api.h:23
const char * prop_time
Definition: Hierarchy.cxx:37
const char * prop_realname
Definition: Hierarchy.cxx:30
@ storemask_TopVersion
Definition: Record.h:170
@ storemask_History
Definition: Record.h:171
@ storemask_NoChilds
Definition: Record.h:172
@ storemask_Version
Definition: Record.h:169
const char * prop_error
Definition: Hierarchy.cxx:33
std::string format(const char *fmt,...)
Definition: string.cxx:49
const char * prop_hash
Definition: Hierarchy.cxx:35
const char * prop_view
Definition: Hierarchy.cxx:39
const char * prop_masteritem
Definition: Hierarchy.cxx:31
const char * prop_kind
Definition: Hierarchy.cxx:29
const char * prop_more
Definition: Hierarchy.cxx:38
const char * prop_auth
Definition: Hierarchy.cxx:34
const char * xmlTrueValue
Definition: ConfigBase.cxx:90
HierarchyStreamKind
Definition: Hierarchy.h:131
@ stream_NoDelete
Definition: Hierarchy.h:135
@ stream_NamesList
Definition: Hierarchy.h:132
@ stream_Value
Definition: Hierarchy.h:133
const char * prop_producer
Definition: Hierarchy.cxx:32
const char * prop_history
Definition: Hierarchy.cxx:36
@ ex_Hierarchy
Definition: Exception.h:39
const char * prop_version
Definition: Hierarchy.cxx:28
uint64_t version
version number
Definition: Hierarchy.h:49
RecordFieldsMap * fields
all fields, which are preserved
Definition: Hierarchy.h:50