Skip to content
Next Next commit
io: introduce actions list for text writing like JSON or XML
In most cases it should be same actions like for binary I/O,
but several special cases will be implemented.
Also in such list original (not-compressed) list of data members will be
used. This will solve problem of unfolding such compressed members later
  • Loading branch information
linev committed May 16, 2017
commit 4be8c5b4df45de52db1c154726bfa4ce825d8b27
3 changes: 3 additions & 0 deletions io/io/inc/TStreamerInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class TStreamerInfo : public TVirtualStreamerInfo {
TStreamerInfoActions::TActionSequence *fWriteObjectWise; ///<! List of write action resulting from the compilation.
TStreamerInfoActions::TActionSequence *fWriteMemberWise; ///<! List of write action resulting from the compilation for use in member wise streaming.
TStreamerInfoActions::TActionSequence *fWriteMemberWiseVecPtr; ///<! List of write action resulting from the compilation for use in member wise streaming.
TStreamerInfoActions::TActionSequence *fWriteText; ///<! List of write action resulting for text output like JSON or XML.

static std::atomic<Int_t> fgCount; ///<Number of TStreamerInfo instances

Expand All @@ -128,6 +129,7 @@ class TStreamerInfo : public TVirtualStreamerInfo {
TStreamerInfo& operator=(const TStreamerInfo&); // TStreamerInfo are copiable. Not Implemented.
void AddReadAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo);
void AddWriteAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo);
void AddWriteTextAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo);
void AddReadMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo);
void AddWriteMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo);

Expand Down Expand Up @@ -216,6 +218,7 @@ class TStreamerInfo : public TVirtualStreamerInfo {
TStreamerInfoActions::TActionSequence *GetReadObjectWiseActions() { return fReadObjectWise; }
TStreamerInfoActions::TActionSequence *GetWriteMemberWiseActions(Bool_t forCollection) { return forCollection ? fWriteMemberWiseVecPtr : fWriteMemberWise; }
TStreamerInfoActions::TActionSequence *GetWriteObjectWiseActions() { return fWriteObjectWise; }
TStreamerInfoActions::TActionSequence *GetWriteTextActions() { return fWriteText; }
Int_t GetNdata() const {return fNdata;}
Int_t GetNelement() const { return fElements->GetEntries(); }
Int_t GetNumber() const {return fNumber;}
Expand Down
4 changes: 4 additions & 0 deletions io/io/src/TStreamerInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ TStreamerInfo::TStreamerInfo()
fWriteObjectWise = 0;
fWriteMemberWise = 0;
fWriteMemberWiseVecPtr = 0;
fWriteText = 0;
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -199,6 +200,7 @@ TStreamerInfo::TStreamerInfo(TClass *cl)
fWriteObjectWise = 0;
fWriteMemberWise = 0;
fWriteMemberWiseVecPtr = 0;
fWriteText = 0;
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -217,6 +219,7 @@ TStreamerInfo::~TStreamerInfo()
delete fWriteObjectWise;
delete fWriteMemberWise;
delete fWriteMemberWiseVecPtr;
delete fWriteText;

if (!fElements) return;
fElements->Delete();
Expand Down Expand Up @@ -2534,6 +2537,7 @@ void TStreamerInfo::Clear(Option_t *option)
if (fWriteObjectWise) fWriteObjectWise->fActions.clear();
if (fWriteMemberWise) fWriteMemberWise->fActions.clear();
if (fWriteMemberWiseVecPtr) fWriteMemberWiseVecPtr->fActions.clear();
if (fWriteText) fWriteText->fActions.clear();
}
}

Expand Down
111 changes: 111 additions & 0 deletions io/io/src/TStreamerInfoActions.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,9 @@ void TStreamerInfo::Compile()
if (fWriteMemberWiseVecPtr) fWriteMemberWiseVecPtr->fActions.clear();
else fWriteMemberWiseVecPtr = new TStreamerInfoActions::TActionSequence(this,ndata);

if (fWriteText) fWriteText->fActions.clear();
else fWriteText = new TStreamerInfoActions::TActionSequence(this,ndata);

if (!ndata) {
// This may be the case for empty classes (e.g., TAtt3D).
// We still need to properly set the size of emulated classes (i.e. add the virtual table)
Expand Down Expand Up @@ -2469,6 +2472,8 @@ void TStreamerInfo::Compile()
AddWriteAction(fWriteMemberWise, i, fCompFull[i]);
AddReadMemberWiseVecPtrAction(fReadMemberWiseVecPtr, i, fCompFull[i]);
AddWriteMemberWiseVecPtrAction(fWriteMemberWiseVecPtr, i, fCompFull[i]);

AddWriteTextAction(fWriteText, i, fCompFull[i]);
}
ComputeSize();

Expand Down Expand Up @@ -2859,6 +2864,112 @@ void TStreamerInfo::AddWriteAction(TStreamerInfoActions::TActionSequence *writeS
#endif
}

////////////////////////////////////////////////////////////////////////////////

void TStreamerInfo::AddWriteTextAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t i, TStreamerInfo::TCompInfo *compinfo)
{
TStreamerElement *element = compinfo->fElem;
if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
// Skip element cached for reading purposes.
return;
}
if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
// Skip artificial element used for reading purposes.
return;
}
switch (compinfo->fType) {
// write basic types
case TStreamerInfo::kBool: writeSequence->AddAction( WriteBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kChar: writeSequence->AddAction( WriteBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kShort: writeSequence->AddAction( WriteBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kInt: writeSequence->AddAction( WriteBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kLong: writeSequence->AddAction( WriteBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kLong64: writeSequence->AddAction( WriteBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kFloat: writeSequence->AddAction( WriteBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kDouble: writeSequence->AddAction( WriteBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kUChar: writeSequence->AddAction( WriteBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kUShort: writeSequence->AddAction( WriteBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kUInt: writeSequence->AddAction( WriteBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kULong: writeSequence->AddAction( WriteBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
case TStreamerInfo::kULong64: writeSequence->AddAction( WriteBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
// case TStreamerInfo::kBits: writeSequence->AddAction( WriteBasicType<BitsMarker>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
/*case TStreamerInfo::kFloat16: {
if (element->GetFactor() != 0) {
writeSequence->AddAction( WriteBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
} else {
Int_t nbits = (Int_t)element->GetXmin();
if (!nbits) nbits = 12;
writeSequence->AddAction( WriteBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
}
break;
} */
/*case TStreamerInfo::kDouble32: {
if (element->GetFactor() != 0) {
writeSequence->AddAction( WriteBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
} else {
Int_t nbits = (Int_t)element->GetXmin();
if (!nbits) {
writeSequence->AddAction( ConvertBasicType<float,double>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
} else {
writeSequence->AddAction( WriteBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
}
}
break;
} */
//case TStreamerInfo::kTNamed: writeSequence->AddAction( WriteTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
// Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
// Streamer alltogether.
//case TStreamerInfo::kTObject: writeSequence->AddAction( WriteTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
//case TStreamerInfo::kTString: writeSequence->AddAction( WriteTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
/*case TStreamerInfo::kSTL: {
TClass *newClass = element->GetNewClass();
TClass *oldClass = element->GetClassPointer();
Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();

if (element->GetArrayLength() <= 1) {
if (newClass && newClass != oldClass) {
if (element->GetStreamer()) {
writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
} else {
writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
}
} else {
if (element->GetStreamer()) {
writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
} else {
writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
}
}
} else {
if (newClass && newClass != oldClass) {
if (element->GetStreamer()) {
writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
} else {
writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
}
} else {
if (element->GetStreamer()) {
writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
} else {
writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
}
}
}
break;
} */
default:
writeSequence->AddAction( GenericWriteAction, new TGenericConfiguration(this,i,compinfo) );
break;
}
#if defined(CDJ_NO_COMPILE)
if (element->TestBit(TStreamerElement::kCache)) {
TConfiguredAction action( writeSequence->fActions.back() ); // Action is moved, we must pop it next.
writeSequence->fActions.pop_back();
writeSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
}
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// This is for streaming via a TClonesArray (or a vector of pointers of this type).

Expand Down