Commit a76bef0d by Maarten L. Hekkelman

backup

parent 4a1d9c8f
...@@ -157,7 +157,7 @@ class category_t ...@@ -157,7 +157,7 @@ class category_t
// } // }
// } // }
auto r = create_row(m_head, nullptr); auto r = create_row();
if (m_head == nullptr) if (m_head == nullptr)
m_head = m_tail = r; m_head = m_tail = r;
...@@ -261,6 +261,104 @@ class category_t ...@@ -261,6 +261,104 @@ class category_t
private: private:
// --------------------------------------------------------------------
// Internal storage, strictly forward linked list with minimal space
// requirements. Strings of size 7 or shorter are stored internally.
// Typically, more than 99% of the strings in an mmCIF file are less
// than 8 bytes in length.
struct item_value
{
item_value(uint16_t column_ix, uint16_t length)
: m_next(nullptr)
, m_length(length)
{
}
item_value() = delete;
item_value(const item_value &) = delete;
item_value &operator=(const item_value &) = delete;
item_value *m_next;
uint16_t m_column_ix;
uint16_t m_length;
union
{
char m_local_data[8];
char *m_data;
};
static constexpr size_t kBufferSize = sizeof(m_local_data);
std::string_view text() const
{
return { m_length >= kBufferSize ? m_data : m_local_data, m_length };
}
const char *c_str() const
{
return m_length >= kBufferSize ? m_data : m_local_data;
}
};
static_assert(sizeof(item_value) == 24, "sizeof(item_value) should be 24 bytes");
using char_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
using char_allocator_traits = std::allocator_traits<char_allocator_type>;
using item_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<item_value>;
using item_allocator_traits = std::allocator_traits<item_allocator_type>;
item_allocator_traits::pointer get_item()
{
item_allocator_type ia(get_allocator());
return item_allocator_traits::allocate(ia, 1);
}
item_value *create_item(uint16_t column_ix, std::string_view text)
{
size_t text_length = text.length();
if (text_length + 1 > std::numeric_limits<uint16_t>::max())
throw std::runtime_error("libcifpp does not support string lengths longer than " + std::to_string(std::numeric_limits<uint16_t>::max()) + " bytes");
auto p = this->get_item();
item_allocator_type ia(get_allocator());
item_allocator_traits::construct(ia, p, column_ix, static_cast<uint16_t>(text_length));
char_allocator_type ca(get_allocator());
char *data;
if (text_length >= item_value::kBufferSize)
data = p->m_data = char_allocator_traits::allocate(ca, text_length + 1);
else
data = p->m_local_data;
std::copy(text.begin(), text.end(), data);
data[text_length] = 0;
return p;
}
item_value *create_item(const item &i)
{
uint16_t ix = get_column_ix(i.name());
return create_item(ix, i.value());
}
void delete_item(item_value *iv)
{
if (iv->m_length >= item_value::kBufferSize)
{
char_allocator_type ca(get_allocator());
char_allocator_traits::deallocate(ca, iv->m_data, iv->m_length + 1);
}
item_allocator_type ia(get_allocator());
item_allocator_traits::destroy(ia, iv);
item_allocator_traits::deallocate(ia, iv, 1);
}
struct row struct row
{ {
// row() = default; // row() = default;
...@@ -275,6 +373,13 @@ class category_t ...@@ -275,6 +373,13 @@ class category_t
template <typename R> template <typename R>
friend class item_handle; friend class item_handle;
row()
: m_next(nullptr)
, m_head(nullptr)
, m_tail(nullptr)
{
}
row(row *next, item_value *data) row(row *next, item_value *data)
: m_next(next) : m_next(next)
, m_head(data) , m_head(data)
...@@ -292,18 +397,6 @@ class category_t ...@@ -292,18 +397,6 @@ class category_t
item_value *m_head = nullptr, *m_tail = nullptr; item_value *m_head = nullptr, *m_tail = nullptr;
}; };
struct item_column
{
std::string m_name;
ValidateItem *m_validator;
item_column(std::string_view name, ValidateItem *validator)
: m_name(name)
, m_validator(validator)
{
}
};
using row_allocator_type = typename std::allocator_traits<allocator_type>::template rebind_alloc<row>; using row_allocator_type = typename std::allocator_traits<allocator_type>::template rebind_alloc<row>;
using row_allocator_traits = std::allocator_traits<row_allocator_type>; using row_allocator_traits = std::allocator_traits<row_allocator_type>;
...@@ -329,47 +422,19 @@ class category_t ...@@ -329,47 +422,19 @@ class category_t
row_allocator_traits::deallocate(ra, r, 1); row_allocator_traits::deallocate(ra, r, 1);
} }
using item_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<item_value>;
using item_allocator_traits = std::allocator_traits<item_allocator_type>;
// struct item_allocator_traits : std::allocator_traits<item_allocator_type>
// {
// using base_type = std::allocator_traits<item_allocator_type>;
// static constexpr typename base_type::pointer
// allocate(item_allocator_type &a, typename base_type::size_type n)
// {
// return base_type::allocate(a, n);
// }
// };
item_allocator_traits::pointer get_item() struct item_column
{
item_allocator_type ia(get_allocator());
return item_allocator_traits::allocate(ia, 1);
}
item_value *create_item(uint16_t column_ix, std::string_view text)
{ {
auto p = this->get_item(); std::string m_name;
item_allocator_type ia(get_allocator()); ValidateItem *m_validator;
item_allocator_traits::construct(ia, p, column_ix, text);
return p;
}
item_value *create_item(const item &i) item_column(std::string_view name, ValidateItem *validator)
: m_name(name)
, m_validator(validator)
{ {
uint16_t ix = get_column_ix(i.name());
return create_item(ix, i.c_str());
} }
};
void delete_item(item_value *iv)
{
item_allocator_type ia(get_allocator());
item_allocator_traits::destroy(ia, iv);
item_allocator_traits::deallocate(ia, iv, 1);
}
allocator_type m_allocator; allocator_type m_allocator;
std::string m_name; std::string m_name;
......
...@@ -106,72 +106,6 @@ class item ...@@ -106,72 +106,6 @@ class item
std::string m_value; std::string m_value;
}; };
// --------------------------------------------------------------------
// Internal storage, strictly forward linked list with minimal space
// requirements. Strings of size 7 or shorter are stored internally.
// Typically, more than 99% of the strings in an mmCIF file are less
// than 8 bytes in length.
struct item_value
{
item_value(uint16_t column_ix, const char *value)
: item_value(column_ix, std::string_view{value})
{
}
item_value(uint16_t column_ix, std::string_view value)
: m_next(nullptr)
, m_length(value.length())
{
if (value.length() > std::numeric_limits<uint16_t>::max())
throw std::runtime_error("libcifpp does not support string lengths longer than " + std::to_string(std::numeric_limits<uint16_t>::max()) + " bytes");
char *data;
if (m_length >= kBufferSize)
data = m_data = new char[m_length];
else
data = m_local_data;
std::copy(value.begin(), value.end(), data);
data[m_length] = 0;
}
~item_value()
{
if (m_length >= kBufferSize)
delete [] m_data;
}
item_value() = delete;
item_value(const item_value &) = delete;
item_value &operator=(const item_value &) = delete;
item_value *m_next;
uint16_t m_column_ix;
uint16_t m_length;
union
{
char m_local_data[8];
char *m_data;
};
static constexpr size_t kBufferSize = sizeof(m_local_data);
std::string_view text() const
{
return { m_length >= kBufferSize ? m_data : m_local_data, m_length };
}
const char *c_str() const
{
return m_length >= kBufferSize ? m_data : m_local_data;
}
};
static_assert(sizeof(item_value) == 24, "sizeof(item_value) should be 24 bytes");
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Transient object to access stored data // Transient object to access stored data
......
...@@ -83,15 +83,26 @@ BOOST_AUTO_TEST_CASE(r_1) ...@@ -83,15 +83,26 @@ BOOST_AUTO_TEST_CASE(r_1)
{ "f-1", 1 }, { "f-1", 1 },
{ "f-2", "two" }, { "f-2", "two" },
{ "f-3", 3.0 }, { "f-3", 3.0 },
// { "f-4", 3.0, 3 }
}); });
// cif::v2::datablock db("test"); auto row = c.front();
// db.emplace_back(std::move(c)); BOOST_CHECK_EQUAL(row["f-1"].compare(1), 0;)
BOOST_CHECK_EQUAL(row["f-2"].compare(1), "two";)
BOOST_CHECK_EQUAL(row["f-3"].compare(1), 3.0;)
}
// std::cout << db << std::endl;
BOOST_AUTO_TEST_CASE(r_2)
{
cif::v2::category c("foo");
for (size_t i = 1; i < 256; ++i)
{
c.emplace({
{ "id", i },
{ "txt", std::string(i, 'x') }
});
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment