Skip to content
Snippets Groups Projects
Commit 5ffda363 authored by Scott Snyder's avatar Scott Snyder Committed by Graeme Stewart
Browse files

'Implement insertMove.' (xAODRootAccess-00-01-67)

	* Tagging xAODRootAccess-00-01-67.
	* xAODRootAccess/tools/TAuxVector.h, Root/TAuxVector.cxx:
	Implement insertMove.
	* test/ut_xaodrootaccess_tauxvector_test.cxx,
	share/ut_xaodrootaccess_tauxvector_test.ref: Test it.
	* xAODRootAccess/TAuxStore.h, Root/TAuxStore.cxx: Implement
	insertMove.
	* test/ut_xaodrootaccess_tauxstore_insertmove_test.cxx,
	share/ut_xaodrootaccess_tauxstore_insertmove_test.ref: Test it.


Former-commit-id: bd02293b
parent a10d376f
No related branches found
No related tags found
No related merge requests found
# $Id: CMakeLists.txt 793319 2017-01-21 16:21:46Z ssnyder $
# $Id: CMakeLists.txt 793778 2017-01-25 04:06:29Z ssnyder $
#
# Build configuration for the xAODRootAccess package.
#
......@@ -17,6 +17,7 @@ endif()
# The dependencies of the package:
atlas_depends_on_subdirs(
PUBLIC
Control/CxxUtils
Control/AthContainersInterfaces
Control/AthContainers
Event/xAOD/xAODCore
......@@ -68,7 +69,7 @@ macro( _add_test name )
atlas_add_test( ${name}
SOURCES test/${name}.cxx
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers xAODCore xAODRootAccess
LINK_LIBRARIES ${ROOT_LIBRARIES} CxxUtils AthContainers xAODCore xAODRootAccess
PROPERTIES TIMEOUT 600 )
endmacro( _add_test )
......@@ -77,7 +78,9 @@ _add_test( ut_xaodrootaccess_metadata_test )
_add_test( ut_xaodrootaccess_remap_test )
_add_test( ut_xaodrootaccess_slimming_test )
_add_test( ut_xaodrootaccess_stats_test )
_add_test( ut_xaodrootaccess_tauxvector_test )
_add_test( ut_xaodrootaccess_tauxstore_test )
_add_test( ut_xaodrootaccess_tauxstore_insertmove_test )
_add_test( ut_xaodrootaccess_tchain_test )
_add_test( ut_xaodrootaccess_tevent_test )
_add_test( ut_xaodrootaccess_tfileaccesstracer_test )
......
......@@ -2,7 +2,7 @@
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: TAuxStore.cxx 793319 2017-01-21 16:21:46Z ssnyder $
// $Id: TAuxStore.cxx 793778 2017-01-25 04:06:29Z ssnyder $
// System include(s):
#include <string.h>
......@@ -637,6 +637,59 @@ namespace xAOD {
return;
}
bool TAuxStore::insertMove (size_t pos,
IAuxStore& other,
const SG::auxid_set_t& ignore_in)
{
// Guard against multi-threaded execution:
guard_t guard( m_mutex1 );
// A sanity check:
if( m_structMode == kObjectStore ) {
::Error( "xAOD::TAuxStore::insertMove",
XAOD_MESSAGE( "Should not have been called for single-object "
"store" ) );
return false;
}
const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
bool nomove = true;
size_t other_size = other.size();
SG::auxid_set_t ignore = ignore_in;
for (SG::auxid_t id : m_auxIDs) {
SG::IAuxTypeVector* v_dst = nullptr;
if (id < m_vecs.size())
v_dst = m_vecs[id];
if (v_dst) {
ignore.insert (id);
if (other.getData (id)) {
void* src_ptr = other.getData (id, other_size, other_size);
if (src_ptr) {
if (!v_dst->insertMove (pos, src_ptr,
reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id)))
nomove = false;
}
}
else {
const void* orig = v_dst->toPtr();
v_dst->shift (pos, other_size);
if (orig != v_dst->toPtr())
nomove = false;
}
}
}
if( m_transientStore ) {
if (!m_transientStore->insertMove( pos, other, ignore ))
nomove = false;
}
return nomove;
}
const void* TAuxStore::getIOData( auxid_t auxid ) const {
// Guard against multi-threaded execution:
......
......@@ -2,7 +2,7 @@
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: TAuxVector.cxx 793319 2017-01-21 16:21:46Z ssnyder $
// $Id: TAuxVector.cxx 793778 2017-01-25 04:06:29Z ssnyder $
// ROOT include(s):
#include <TClass.h>
......@@ -188,6 +188,27 @@ namespace xAOD {
return;
}
bool TAuxVector::insertMove (size_t pos, void* beg, void* end)
{
TVirtualCollectionProxy::TPushPop bind (m_proxy, m_vec);
size_t eltsz = m_proxy->GetIncrement();
const void* orig = this->toPtr();
char* begp = reinterpret_cast<char*> (beg);
char* endp = reinterpret_cast<char*> (end);
size_t nelt = (endp-begp) / eltsz;
shift (pos, nelt);
// FIXME: want move, not copy.
// But i don't seem to be able to call move operations through cling,
// so just use copy for now.
copyRange (beg,
reinterpret_cast<char*>(this->toPtr()) + pos*eltsz,
nelt);
return this->toPtr() == orig;
}
void TAuxVector::copyRange( const void* src, void* dst, size_t n ) {
// Size of an element in the vector:
......
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id$
/**
* @file xAODRootAccess/test/ut_xaodrootaccess_tauxstore_insertmove_test.cxx
* @author scott snyder <snyder@bnl.gov>
* @date Jan, 2017
* @brief Unit tests TAuxStore::insertMove.
*/
#undef NDEBUG
#include "xAODRootAccess/TAuxStore.h"
#include "xAODRootAccess/tools/ReturnCheck.h"
#include "AthContainers/AuxTypeRegistry.h"
#include "AthContainers/AuxStoreInternal.h"
#include "TTree.h"
#include <iostream>
#include <sstream>
#include <cassert>
const char* APP_NAME = "ut_xaodrootaccess_tauxstore_insertmove_test";
struct MoveTest
{
MoveTest(int x=0) : m_v(x) {}
MoveTest(const MoveTest& other): m_v (other.m_v) {}
MoveTest(MoveTest&& other): m_v (std::move(other.m_v)) {}
MoveTest& operator= (const MoveTest& other) {
if (this != &other) m_v = other.m_v;
return *this;
}
MoveTest& operator= (MoveTest&& other) {
if (this != &other) m_v = std::move(other.m_v);
return *this;
}
std::vector<int> m_v;
bool operator== (const MoveTest& other) const { return m_v.size() == other.m_v.size(); }
};
bool wasMoved (const MoveTest& x) { return x.m_v.empty(); }
int test1()
{
std::cout << "test1\n";
SG::auxid_t ityp1 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt");
SG::auxid_t ityp2 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anotherInt");
SG::auxid_t ityp3 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt3");
SG::auxid_t ityp4 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt4");
SG::auxid_t mtyp1 = SG::AuxTypeRegistry::instance().getAuxID<MoveTest> ("moveTest");
TTree tree ("t", "t");
xAOD::TAuxStore s1( "fooAux." );
RETURN_CHECK( APP_NAME, s1.readFrom (&tree) );
s1.resize(5);
int* i1 = reinterpret_cast<int*> (s1.getData(ityp1, 5, 20));
int* i2 = reinterpret_cast<int*> (s1.getData(ityp2, 5, 20));
MoveTest* m1 = reinterpret_cast<MoveTest*> (s1.getData(mtyp1, 5, 20));
for (int i=0; i<5; i++) {
i1[i] = i;
i2[i] = i+100;
m1[i] = MoveTest(i);
}
SG::AuxStoreInternal s2;
s2.resize(5);
int* i1_2 = reinterpret_cast<int*> (s2.getData(ityp1, 5, 5));
int* i3_2 = reinterpret_cast<int*> (s2.getData(ityp3, 5, 5));
int* i4_2 = reinterpret_cast<int*> (s2.getData(ityp4, 5, 5));
MoveTest* m1_2 = reinterpret_cast<MoveTest*> (s2.getData(mtyp1, 5, 5));
for (int i=0; i<5; i++) {
i1_2[i] = i+10;
i3_2[i] = i+110;
i4_2[i] = i+210;
m1_2[i] = MoveTest(i+10);
}
SG::auxid_set_t ignore { ityp4 };
s1.insertMove (3, s2, ignore);
assert (s1.size() == 10);
s1.reserve(20);
assert (s1.getData(ityp4) == nullptr);
const int* i3 = reinterpret_cast<const int*> (s1.getData(ityp3));
assert (i3 != 0);
i1 = reinterpret_cast<int*> (s1.getData(ityp1, 5, 20));
i2 = reinterpret_cast<int*> (s1.getData(ityp2, 5, 20));
m1 = reinterpret_cast<MoveTest*> (s1.getData(mtyp1, 5, 20));
for (int i=0; i<3; i++) {
assert (i1[i] == i);
assert (i2[i] == i+100);
assert (i3[i] == 0);
assert (m1[i] == MoveTest(i));
}
for (int i=0; i<5; i++) {
assert (i1[3+i] == i+10);
assert (i2[3+i] == 0);
assert (i3[3+i] == i+110);
assert (m1[3+i] == MoveTest(i+10));
}
for (int i=3; i<5; i++) {
assert (i1[5+i] == i);
assert (i2[5+i] == i+100);
assert (i3[5+i] == 0);
assert (m1[5+i] == MoveTest(i));
}
for (int i=0; i<5; i++) {
assert (wasMoved (m1_2[i]));
}
for (int i=0; i<5; i++) {
i1_2[i] = i+20;
i3_2[i] = i+120;
m1_2[i] = MoveTest(i+20);
}
s1.insertMove (10, s2, ignore);
assert (s1.size() == 15);
i1 = reinterpret_cast<int*> (s1.getData(ityp1, 5, 20));
i2 = reinterpret_cast<int*> (s1.getData(ityp2, 5, 20));
i3 = reinterpret_cast<int*> (s1.getData(ityp3, 5, 20));
m1 = reinterpret_cast<MoveTest*> (s1.getData(mtyp1, 5, 20));
for (int i=0; i<3; i++) {
assert (i1[i] == i);
assert (i2[i] == i+100);
assert (i3[i] == 0);
assert (m1[i] == MoveTest(i));
}
for (int i=0; i<5; i++) {
assert (i1[3+i] == i+10);
assert (i2[3+i] == 0);
assert (i3[3+i] == i+110);
assert (m1[3+i] == MoveTest(i+10));
}
for (int i=3; i<5; i++) {
assert (i1[5+i] == i);
assert (i2[5+i] == i+100);
assert (i3[5+i] == 0);
assert (m1[5+i] == MoveTest(i));
}
for (int i=0; i<5; i++) {
assert (i1[10+i] == i+20);
assert (i2[10+i] == 0);
assert (i3[10+i] == i+120);
assert (m1[10+i] == MoveTest(i+20));
}
for (int i=0; i<5; i++) {
assert (wasMoved (m1_2[i]));
}
return 0;
}
int main()
{
test1();
return 0;
}
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id$
/**
* @file xAODRootAccess/test/ut_xaodrootaccess_tauxvector_test.cxx
* @author scott snyder <snyder@bnl.gov>
* @date Jan, 2017
* @brief Unit tests for TAuxVector. (sadly incomplete)
*/
#undef NDEBUG
#include "xAODRootAccess/tools/TAuxVector.h"
#include "xAODRootAccess/tools/TAuxVectorFactory.h"
#include "CxxUtils/StrFormat.h"
#include "TClass.h"
#include <iostream>
#include <sstream>
#include <cassert>
std::string str (int x)
{
return CxxUtils::strformat ("%d", x);
}
// Test insertMove.
void test1()
{
std::cout << "test1\n";
TClass* cl_int = TClass::GetClass ("vector<int>");
xAOD::TAuxVectorFactory fac_int (cl_int);
xAOD::TAuxVector vec_int = xAOD::TAuxVector (&fac_int, cl_int, 5, 5);
int* ptr_int = reinterpret_cast<int*> (vec_int.toPtr());
for (int i=0; i < 5; i++)
ptr_int[i] = i;
std::vector<int> v2_int { 10, 11, 12, 13, 14 };
vec_int.insertMove (3, v2_int.data(), v2_int.data() + 5);
assert (vec_int.size() == 10);
ptr_int = reinterpret_cast<int*> (vec_int.toPtr());
for (int i=0; i < 3; i++)
assert (ptr_int[i] == i);
for (int i=0; i < 5; i++)
assert (ptr_int[3+i] == 10+i);
for (int i=3; i < 5; i++)
assert (ptr_int[5+i] == i);
std::vector<int> v3_int { 20, 21, 22, 23, 24 };
vec_int.insertMove (10, v3_int.data(), v3_int.data() + 5);
assert (vec_int.size() == 15);
ptr_int = reinterpret_cast<int*> (vec_int.toPtr());
for (int i=0; i < 3; i++)
assert (ptr_int[i] == i);
for (int i=0; i < 5; i++)
assert (ptr_int[3+i] == 10+i);
for (int i=3; i < 5; i++)
assert (ptr_int[5+i] == i);
for (int i=0; i < 5; i++)
assert (ptr_int[10+i] == 20+i);
//*********************************
TClass* cl_str = TClass::GetClass ("vector<std::string>");
xAOD::TAuxVectorFactory fac_str (cl_str);
xAOD::TAuxVector vec_str = xAOD::TAuxVector (&fac_str, cl_str, 5, 5);
std::string* ptr_str = reinterpret_cast<std::string*> (vec_str.toPtr());
for (int i=0; i < 5; i++)
ptr_str[i] = str(i);
std::vector<std::string> v2_str { str(10), str(11), str(12), str(13), str(14) };
vec_str.insertMove (3, v2_str.data(), v2_str.data() + 5);
assert (vec_str.size() == 10);
ptr_str = reinterpret_cast<std::string*> (vec_str.toPtr());
for (int i=0; i < 3; i++)
assert (ptr_str[i] == str(i));
for (int i=0; i < 5; i++)
assert (ptr_str[3+i] == str(10+i));
for (int i=3; i < 5; i++)
assert (ptr_str[5+i] == str(i));
std::vector<std::string> v3_str { str(20), str(21), str(22), str(23), str(24) };
vec_str.insertMove (10, v3_str.data(), v3_str.data() + 5);
assert (vec_str.size() == 15);
ptr_str = reinterpret_cast<std::string*> (vec_str.toPtr());
for (int i=0; i < 3; i++)
assert (ptr_str[i] == str(i));
for (int i=0; i < 5; i++)
assert (ptr_str[3+i] == str(10+i));
for (int i=3; i < 5; i++)
assert (ptr_str[5+i] == str(i));
for (int i=0; i < 5; i++)
assert (ptr_str[10+i] == str(20+i));
}
int main()
{
test1();
return 0;
}
......@@ -4,7 +4,7 @@
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: TAuxStore.h 793319 2017-01-21 16:21:46Z ssnyder $
// $Id: TAuxStore.h 793778 2017-01-25 04:06:29Z ssnyder $
#ifndef XAODROOTACCESS_TAUXSTORE_H
#define XAODROOTACCESS_TAUXSTORE_H
......@@ -21,6 +21,8 @@
// Local include(s):
#include "xAODRootAccess/tools/TReturnCode.h"
#include "Rtypes.h"
// Forward declaration(s):
class TTree;
class TBranch;
......@@ -43,8 +45,8 @@ namespace xAOD {
///
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 793319 $
/// $Date: 2017-01-21 17:21:46 +0100 (Sat, 21 Jan 2017) $
/// $Revision: 793778 $
/// $Date: 2017-01-25 05:06:29 +0100 (Wed, 25 Jan 2017) $
///
class TAuxStore : public SG::IAuxStore,
public SG::IAuxStoreIO {
......@@ -147,6 +149,10 @@ namespace xAOD {
virtual void reserve( size_t size );
/// Shift the contents of the stored arrays
virtual void shift( size_t pos, ptrdiff_t offs );
/// Insert contents of another store via move.
virtual bool insertMove (size_t pos,
IAuxStore& other,
const SG::auxid_set_t& ignore);
/// @}
......
......@@ -4,12 +4,13 @@
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: TAuxVector.h 793319 2017-01-21 16:21:46Z ssnyder $
// $Id: TAuxVector.h 793778 2017-01-25 04:06:29Z ssnyder $
#ifndef XAODROOTACCESS_TOOLS_TAUXVECTOR_H
#define XAODROOTACCESS_TOOLS_TAUXVECTOR_H
// EDM include(s):
#include "AthContainersInterfaces/IAuxTypeVector.h"
#include "AthContainersInterfaces/IAuxTypeVectorFactory.h"
// Forward declaration(s):
class TClass;
......@@ -31,8 +32,8 @@ namespace xAOD {
/// @author Scott Snyder <Scott.Snyder@cern.ch>
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 793319 $
/// $Date: 2017-01-21 17:21:46 +0100 (Sat, 21 Jan 2017) $
/// $Revision: 793778 $
/// $Date: 2017-01-25 05:06:29 +0100 (Wed, 25 Jan 2017) $
///
class TAuxVector : public SG::IAuxTypeVector {
......@@ -68,6 +69,8 @@ namespace xAOD {
virtual void reserve( size_t sz );
/// Shift the elements of the vector
virtual void shift( size_t pos, ptrdiff_t offs );
/// Insert a range of elements via move.
virtual bool insertMove (size_t pos, void* beg, void* end) override;
/// @}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment