Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TLeafElement.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 14/01/2001
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TLeafElement
13 \ingroup tree
14 
15 A TLeaf for the general case when using the branches created via
16 a TStreamerInfo (i.e. using TBranchElement).
17 */
18 
19 #include "TLeafElement.h"
20 //#include "TMethodCall.h"
21 
22 #include "TVirtualStreamerInfo.h"
23 #include "Bytes.h"
24 
25 ClassImp(TLeafElement);
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 /// Default constructor for LeafObject.
29 
30 TLeafElement::TLeafElement(): TLeaf()
31 {
32  fAbsAddress = 0;
33  fID = -1;
34  fType = -1;
35 }
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Create a LeafObject.
39 
40 TLeafElement::TLeafElement(TBranch *parent, const char *name, Int_t id, Int_t type)
41  : TLeaf(parent, name,name)
42 {
43  fLenType = 0;
44  fAbsAddress = 0;
45  fID = id;
46  fType = type;
47  if (type < TVirtualStreamerInfo::kObject) {
48  Int_t bareType = type;
49  if (bareType > TVirtualStreamerInfo::kOffsetP)
50  bareType -= TVirtualStreamerInfo::kOffsetP;
51  else if (bareType > TVirtualStreamerInfo::kOffsetL)
52  bareType -= TVirtualStreamerInfo::kOffsetL;
53 
54  if ((bareType >= TVirtualStreamerInfo::kUChar && bareType <= TVirtualStreamerInfo::kULong)
55  || bareType == TVirtualStreamerInfo::kULong64)
56  {
57  SetUnsigned();
58  }
59 
60  auto bareTypeCopy = static_cast<EDataType>(bareType);
61  switch (bareTypeCopy) {
62  case kChar_t: // fall-through
63  case kUChar_t: // fall-through
64  case kchar: // fall-through
65  case kBool_t:
66  fLenType = 1;
67  break;
68  case kShort_t: // fall-through
69  case kUShort_t: // fall-through
70  case kFloat16_t:
71  fLenType = 2;
72  break;
73  case kFloat_t: // fall-through
74  case kDouble32_t: // fall-through
75  case kInt_t: // fall-through
76  case kUInt_t:
77  fLenType = 4;
78  break;
79  case kLong_t: // fall-through
80  case kULong_t: // fall-through
81  case kLong64_t: // fall-through
82  case kULong64_t: // fall-through
83  case kDouble_t:
84  fLenType = 8;
85  break;
86  // All cases I don't know how to handle.
87  case kOther_t: // fall-through
88  case kNoType_t: // fall-through
89  case kCounter: // fall-through
90  case kCharStar: // fall-through
91  case kBits: // fall-through
92  case kVoid_t: // fall-through
93  case kDataTypeAliasUnsigned_t: // fall-through
94  case kDataTypeAliasSignedChar_t: // fall-through
95  case kNumDataTypes: // fall-through
96  fLenType = 0;
97  };
98  }
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Default destructor for a LeafObject.
103 
104 TLeafElement::~TLeafElement()
105 {
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Determine if this TLeafElement supports bulk IO
110 TLeaf::DeserializeType
111 TLeafElement::GetDeserializeType() const
112 {
113  if (R__likely(fDeserializeTypeCache.load(std::memory_order_relaxed) != DeserializeType::kInvalid))
114  return fDeserializeTypeCache;
115 
116  TClass *clptr = nullptr;
117  EDataType type = EDataType::kOther_t;
118  if (fBranch->GetExpectedType(clptr, type)) { // Returns non-zero in case of failure
119  fDeserializeTypeCache.store(DeserializeType::kDestructive, std::memory_order_relaxed);
120  return DeserializeType::kDestructive; // I don't know what it is, but we aren't going to use bulk IO.
121  }
122  fDataTypeCache.store(type, std::memory_order_release);
123  if (clptr) { // Something that requires a dictionary to read; skip.
124  fDeserializeTypeCache.store(DeserializeType::kDestructive, std::memory_order_relaxed);
125  return DeserializeType::kDestructive;
126  }
127 
128  if ((fType == EDataType::kChar_t) || fType == EDataType::kUChar_t || type == EDataType::kBool_t) {
129  fDeserializeTypeCache.store(DeserializeType::kZeroCopy, std::memory_order_relaxed);
130  return DeserializeType::kZeroCopy;
131  } else if ((type == EDataType::kFloat_t) || (type == EDataType::kDouble_t) ||
132  (type == EDataType::kInt_t) || (type == EDataType::kUInt_t) ||
133  (type == EDataType::kLong64_t) || (type == EDataType::kULong64_t)) {
134  fDeserializeTypeCache.store(DeserializeType::kInPlace, std::memory_order_relaxed);
135  return DeserializeType::kInPlace;
136  }
137 
138  fDeserializeTypeCache.store(DeserializeType::kDestructive, std::memory_order_relaxed);
139  return DeserializeType::kDestructive;
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Deserialize N events from an input buffer.
144 Bool_t TLeafElement::ReadBasketFast(TBuffer &input_buf, Long64_t N)
145 {
146  EDataType type = fDataTypeCache.load(std::memory_order_consume);
147  return input_buf.ByteSwapBuffer(fLen*N, type);
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Returns pointer to method corresponding to name name is a string
152 /// with the general form "method(list of params)" If list of params is
153 /// omitted, () is assumed;
154 
155 TMethodCall *TLeafElement::GetMethodCall(const char * /*name*/)
156 {
157  return 0;
158 }
159 
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Copy/set fMinimum and fMaximum to include/be wide than those of the parameter
163 
164 Bool_t TLeafElement::IncludeRange(TLeaf *input)
165 {
166  if (input) {
167  if (input->GetMaximum() > this->GetMaximum())
168  ((TBranchElement*)fBranch)->fMaximum = input->GetMaximum();
169  return kTRUE;
170  } else {
171  return kFALSE;
172  }
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Return true if this leaf is does not have any sub-branch/leaf.
177 
178 Bool_t TLeafElement::IsOnTerminalBranch() const
179 {
180  if (fBranch->GetListOfBranches()->GetEntriesFast()) return kFALSE;
181  return kTRUE;
182 }