Skip to content
Snippets Groups Projects
Commit aa83bfa3 authored by scott snyder's avatar scott snyder
Browse files

AthContainers: Backport developments from master.

Implementing createVectorFromData.
parent 6cb4dff9
No related merge requests found
Showing
with 325 additions and 3 deletions
......@@ -344,6 +344,19 @@ protected:
bool no_lock_check);
/**
* @brief Explicitly add a vector to the store.
* @param auxid The identifier of the aux data item being added.
* @param vec Vector data being added.
* @param isDecoration Should this variable be marked as a decoration?
*
* For internal use. The @c auxid must not already exist in the store.
*/
void addVector (SG::auxid_t auxid,
std::unique_ptr<IAuxTypeVector> vec,
bool isDecoration);
private:
/// Implementation of getDataInternal; no locking.
virtual void* getDataInternal_noLock (SG::auxid_t auxid,
......
......@@ -135,6 +135,9 @@ public:
* @param auxid The desired aux data item.
* @param size Initial size of the new vector.
* @param capacity Initial capacity of the new vector.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
IAuxTypeVector* makeVector (SG::auxid_t auxid,
size_t size,
......@@ -147,6 +150,9 @@ public:
* @param auxid The desired aux data item.
* @param size Initial size of the new vector.
* @param capacity Initial capacity of the new vector.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
IAuxTypeVector* makeVector (lock_t& lock,
SG::auxid_t auxid,
......@@ -154,6 +160,27 @@ public:
size_t capacity) const;
/**
* @brief Construct an @c IAuxTypeVector object from a vector.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* If the element type is T, then @c data should be a pointer
* to a std::vector<T> object, which was obtained with @c new.
* But if @c isPacked is @c true, then @c data
* should instead point at an object of type @c SG::PackedContainer<T>.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
IAuxTypeVector* makeVectorFromData (SG::auxid_t auxid,
void* data,
bool isPacked,
bool ownFlag) const;
/**
* @brief Return the name of an aux data item.
* @param auxid The desired aux data item.
......
......@@ -39,10 +39,33 @@ public:
* @brief Create a vector object of this type.
* @param size Initial size of the new vector.
* @param capacity Initial capacity of the new vector.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
virtual IAuxTypeVector* create (size_t size, size_t capacity) const;
/**
* @brief Create a vector object of this type from a data blob.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* If the element type is T, then @c data should be a pointer
* to a std::vector<T> object, which was obtained with @c new.
* But if @c isPacked is @c true, then @c data
* should instead point at an object of type @c SG::PackedContainer<T>.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
virtual IAuxTypeVector* createFromData (void* data,
bool isPacked,
bool ownFlag) const;
/**
* @brief Copy an element between vectors.
* @param dst Pointer to the start of the destination vector's data.
......@@ -95,6 +118,14 @@ public:
* if the std::vector code is used directly.
*/
virtual bool isDynamic() const;
private:
/// Helpers for creating vector from a data blob,
IAuxTypeVector* createFromData (void* data, bool isPacked, bool ownFlag,
std::true_type) const;
IAuxTypeVector* createFromData (void* data, bool isPacked, bool ownFlag,
std::false_type) const;
};
......
......@@ -27,6 +27,85 @@ AuxTypeVectorFactory<T>::create (size_t size, size_t capacity) const
}
/**
* @brief Create a vector object of this type from a data blob.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* This is for types which are packable.
*/
template <class T>
IAuxTypeVector*
AuxTypeVectorFactory<T>::createFromData (void* data,
bool isPacked,
bool ownFlag,
std::true_type) const
{
if (isPacked) {
typedef typename SG::AuxDataTraits<T>::vector_type unpacked_vector_type;
typedef typename unpacked_vector_type::value_type element_type;
typedef SG::PackedContainer<element_type> vector_type;
return new AuxTypeVectorHolder<T, vector_type >
(reinterpret_cast<vector_type*>(data), ownFlag);
}
else {
typedef typename AuxTypeVectorHolder<T>::vector_type vector_type;
return new AuxTypeVectorHolder<T> (reinterpret_cast<vector_type*>(data), true);
}
}
/**
* @brief Create a vector object of this type from a data blob.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* This is for types which are not packable.
*/
template <class T>
IAuxTypeVector*
AuxTypeVectorFactory<T>::createFromData (void* data,
bool isPacked,
bool ownFlag,
std::false_type) const
{
if (isPacked) std::abort();
typedef typename AuxTypeVectorHolder<T>::vector_type vector_type;
return new AuxTypeVectorHolder<T>
(reinterpret_cast<vector_type*>(data), ownFlag);
}
/**
* @brief Create a vector object of this type from a data blob.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* If the element type is T, then @c data should be a pointer
* to a std::vector<T> object, which was obtained with @c new.
* But if @c isPacked is @c true, then @c data
* should instead point at an object of type @c SG::PackedContainer<T>.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
template <class T>
IAuxTypeVector*
AuxTypeVectorFactory<T>::createFromData (void* data,
bool isPacked,
bool ownFlag) const
{
return createFromData (data, isPacked, ownFlag,
typename DataModel_detail::can_pack<T>::type());
}
/**
* @brief Copy an element between vectors.
* @param dst Pointer to the start of the destination vector's data.
......
......@@ -124,6 +124,44 @@ void* AuxStoreInternal::getData (auxid_t auxid, size_t size, size_t capacity)
}
/**
* @brief Explicitly add a vector to the store.
* @param auxid The identifier of the aux data item being added.
* @param vec Vector data being added.
* @param isDecoration Should this variable be marked as a decoration?
*
* For internal use. The @c auxid must not already exist in the store.
*/
void
AuxStoreInternal::addVector (auxid_t auxid,
std::unique_ptr<IAuxTypeVector> vec,
bool isDecoration)
{
guard_t guard (m_mutex);
if (m_locked)
throw ExcStoreLocked (auxid);
// Resize the vectors if needed.
if (m_vecs.size() <= auxid) {
m_vecs.resize (auxid+1);
m_isDecoration.resize (auxid+1);
}
// Give up if the variable is already present in the store.
if (m_vecs[auxid]) std::abort();
// Make sure the length is consistent with the rest of the store.
size_t sz = this->size_noLock();
if (vec->size() < sz)
vec->resize (sz);
// Add it to the store.
m_vecs[auxid] = vec.release();
m_isDecoration[auxid] = isDecoration;
addAuxID (auxid);
}
/**
* @brief Return the data vector for one aux data decoration item.
* @param auxid The identifier of the desired aux data item.
......
......@@ -111,6 +111,33 @@ IAuxTypeVector* AuxTypeRegistry::makeVector (lock_t& lock,
}
/**
* @brief Construct an @c IAuxTypeVector object from a vector.
* @param data The vector object.
* @param isPacked If true, @c data is a @c PackedContainer.
* @param ownFlag If true, the newly-created IAuxTypeVector object
* will take ownership of @c data.
*
* If the element type is T, then @c data should be a pointer
* to a std::vector<T> object, which was obtained with @c new.
* But if @c isPacked is @c true, then @c data
* should instead point at an object of type @c SG::PackedContainer<T>.
*
* Returns a newly-allocated object.
* FIXME: Should return a unique_ptr.
*/
IAuxTypeVector* AuxTypeRegistry::makeVectorFromData (SG::auxid_t auxid,
void* data,
bool isPacked,
bool ownMode) const
{
const SG::IAuxTypeVectorFactory* factory = getFactory (auxid);
assert (factory != 0);
return factory->createFromData (data, isPacked, ownMode);
}
/**
* @brief Return the name of an aux data item.
* @param auxid The desired aux data item.
......
test1
test2
test3
test4
test5
test_threading
......@@ -15,8 +15,8 @@
#include "AthContainers/AuxStoreInternal.h"
#include "AthContainers/AuxTypeRegistry.h"
#include "AthContainers/exceptions.h"
#include "AthContainers/tools/AuxTypeVector.h"
#include "AthContainers/tools/threading.h"
#include "AthContainers/tools/foreach.h"
#include "TestTools/expect_exception.h"
#ifndef ATHCONTAINERS_NO_THREADS
#include "boost/thread/shared_mutex.hpp"
......@@ -56,6 +56,7 @@ class AuxStoreInternalTest
{
public:
using SG::AuxStoreInternal::addAuxID;
using SG::AuxStoreInternal::addVector;
};
......@@ -393,6 +394,41 @@ void test5()
}
// Test addVector
void test4()
{
std::cout << "test4\n";
AuxStoreInternalTest s;
SG::auxid_t ityp1 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt");
SG::auxid_t ityp2 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt2");
SG::auxid_t ityp3 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt3");
assert (s.size() == 0);
auto vec1 = std::make_unique<SG::AuxTypeVector<int> > (10, 10);
SG::IAuxTypeVector* vec1ptr = vec1.get();
s.addVector (ityp1, std::move(vec1), false);
assert (s.size() == 10);
assert (s.getIOData(ityp1) == vec1ptr->toVector());
assert (s.getData(ityp1) == vec1ptr->toPtr());
assert (vec1ptr->size() == 10);
auto vec2 = std::make_unique<SG::AuxTypeVector<int> > (5, 5);
SG::IAuxTypeVector* vec2ptr = vec2.get();
s.addVector (ityp2, std::move(vec2), true);
assert (s.size() == 10);
assert (vec2ptr->size() == 10);
assert (s.getIOData(ityp2) == vec2ptr->toVector());
assert (s.getData(ityp2) == vec2ptr->toPtr());
s.lock();
auto vec3 = std::make_unique<SG::AuxTypeVector<int> > (5, 5);
EXPECT_EXCEPTION (SG::ExcStoreLocked, s.addVector (ityp3, std::move(vec3), false));
EXPECT_EXCEPTION (SG::ExcStoreLocked, s.getDecoration (ityp1, 10, 10));
s.getDecoration (ityp2, 10, 10);
}
class ThreadingTest
{
public:
......@@ -443,7 +479,7 @@ ThreadingTest::ThreadingTest()
void ThreadingTest::worker()
{
ATHCONTAINERS_FOREACH (SG::auxid_t id, m_ids) {
for (SG::auxid_t id : m_ids) {
int* data = reinterpret_cast<int*> (m_store.getData (id, m_nelt, m_nelt));
assert (m_store.getData (id) == data);
data[0] = id;
......@@ -452,7 +488,7 @@ void ThreadingTest::worker()
const SG::auxid_set_t& ids = m_store.getAuxIDs();
assert (ids.size() == m_ids.size());
ATHCONTAINERS_FOREACH (SG::auxid_t id, m_ids) {
for (SG::auxid_t id : m_ids) {
const int* data = reinterpret_cast<const int*> (m_store.getData (id));
assert (data[0] == static_cast<int>(id));
assert (ids.count (id) == 1);
......@@ -498,6 +534,7 @@ int main()
test1();
test2();
test3();
test4();
test5();
test_threading();
return 0;
......
......@@ -214,6 +214,40 @@ void test_type_extlock(const std::string& typname,
}
template <class T>
void test_makeVector (const std::string& name)
{
SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
SG::auxid_t auxid = r.getAuxID<T> (name);
typedef typename SG::AuxTypeVectorHolder<T>::vector_type vector_type;
vector_type* vec1 = new vector_type;
vec1->push_back (makeT(1));
vec1->push_back (makeT(2));
vec1->push_back (makeT(3));
SG::IAuxTypeVector* v1 = r.makeVectorFromData (auxid, vec1, false, true);
assert (v1->size() == 3);
T* ptr1 = reinterpret_cast<T*> (v1->toPtr());
assert (ptr1[0] == makeT(1));
assert (ptr1[1] == makeT(2));
assert (ptr1[2] == makeT(3));
SG::PackedContainer<T>* vec2 = new SG::PackedContainer<T>;
vec2->push_back (makeT(3));
vec2->push_back (makeT(2));
vec2->push_back (makeT(1));
SG::IAuxTypeVector* v2 = r.makeVectorFromData (auxid, vec2, true, true);
assert (v2->size() == 3);
T* ptr2 = reinterpret_cast<T*> (v2->toPtr());
assert (ptr2[0] == makeT(3));
assert (ptr2[1] == makeT(2));
assert (ptr2[2] == makeT(1));
delete v1;
delete v2;
}
void test2()
{
std::cout << "test2\n";
......@@ -222,6 +256,7 @@ void test2()
test_type<double> ("double", "aFloat", "xclass");
test_type<bool> ("bool", "aBool");
test_type<Payload> ("Payload", "aPayload");
test_makeVector<int> ("anInt");
test_type_extlock<int> ("int", "anInt");
}
......
......@@ -60,6 +60,37 @@ void test_vector()
fac.clear (ptr2, 0);
assert (ptr2[0] == makeT());
assert (ptr2[1] == makeT(11));
typedef typename SG::AuxTypeVectorHolder<T>::vector_type vector_type;
vector_type* vec3 = new vector_type;
vec3->push_back (makeT(3));
vec3->push_back (makeT(2));
vec3->push_back (makeT(1));
SG::IAuxTypeVector* v3 = fac.createFromData (vec3, false, true);
assert (v3->size() == 3);
T* ptr3 = reinterpret_cast<T*> (v3->toPtr());
assert (ptr3[0] == makeT(3));
assert (ptr3[1] == makeT(2));
assert (ptr3[2] == makeT(1));
}
template <class T>
void test_vector2()
{
SG::AuxTypeVectorFactory<T> fac;
SG::PackedContainer<T>* vec4 = new SG::PackedContainer<T>;
vec4->push_back (makeT(4));
vec4->push_back (makeT(3));
vec4->push_back (makeT(2));
vec4->push_back (makeT(1));
SG::IAuxTypeVector* v4 = fac.createFromData (vec4, true, true);
assert (v4->size() == 4);
T* ptr4 = reinterpret_cast<T*> (v4->toPtr());
assert (ptr4[0] == makeT(4));
assert (ptr4[1] == makeT(3));
assert (ptr4[2] == makeT(2));
assert (ptr4[3] == makeT(1));
}
......@@ -67,8 +98,10 @@ void test1()
{
std::cout << "test1\n";
test_vector<int>();
test_vector2<int>();
test_vector<bool>();
test_vector<float>();
test_vector2<float>();
}
......
......@@ -18,6 +18,7 @@
#include <vector>
#include <iostream>
#include <cassert>
#include <memory>
template <class T>
......
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