Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
4a1d9c8f
Unverified
Commit
4a1d9c8f
authored
Jul 31, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New storage layout for item_value
parent
26c86282
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
35 deletions
+82
-35
include/cif++/v2/category.hpp
+29
-28
include/cif++/v2/item.hpp
+53
-7
No files found.
include/cif++/v2/category.hpp
View file @
4a1d9c8f
...
...
@@ -83,6 +83,14 @@ class category_t
auto
r
=
m_head
;
while
(
r
!=
nullptr
)
{
auto
i
=
r
->
m_head
;
while
(
i
!=
nullptr
)
{
auto
ti
=
i
->
m_next
;
delete_item
(
i
);
i
=
ti
;
}
auto
t
=
r
->
m_next
;
delete_row
(
r
);
r
=
t
;
...
...
@@ -149,19 +157,23 @@ class category_t
// }
// }
auto
r
=
create_row
(
m_head
,
nullptr
);
std
::
vector
<
item_value
*>
item_values
;
// std::transform(b, e, std::back_inserter(item_values), [this](Item &i) { return this->create_item(i); });
if
(
m_head
==
nullptr
)
m_head
=
m_tail
=
r
;
else
m_tail
=
m_tail
->
m_next
=
r
;
for
(
auto
i
=
b
;
i
!=
e
;
++
i
)
item_values
.
push_back
(
this
->
create_item
(
*
i
));
{
std
::
unique_ptr
<
item_value
>
new_item
(
this
->
create_item
(
*
i
));
if
(
r
->
m_head
==
nullptr
)
r
->
m_head
=
r
->
m_tail
=
new_item
.
release
();
else
r
->
m_tail
=
r
->
m_tail
->
m_next
=
new_item
.
release
();
}
for
(
auto
p
:
item_values
)
delete_item
(
p
);
return
{};
...
...
@@ -203,9 +215,9 @@ class category_t
// --------------------------------------------------------------------
/// \brief Return the index number for \a column_name
uint
32
_t
get_column_ix
(
std
::
string_view
column_name
)
const
uint
16
_t
get_column_ix
(
std
::
string_view
column_name
)
const
{
uint
32
_t
result
;
uint
16
_t
result
;
for
(
result
=
0
;
result
<
m_columns
.
size
();
++
result
)
{
...
...
@@ -223,7 +235,7 @@ class category_t
return
result
;
}
uint
32
_t
add_column
(
std
::
string_view
column_name
)
uint
16
_t
add_column
(
std
::
string_view
column_name
)
{
using
namespace
std
::
literals
;
...
...
@@ -317,17 +329,6 @@ class category_t
row_allocator_traits
::
deallocate
(
ra
,
r
,
1
);
}
constexpr
static
size_t
calculate_item_size
(
const
char
*
text
)
{
return
calculate_item_size
(
strlen
(
text
));
}
constexpr
static
size_t
calculate_item_size
(
size_t
text_len
)
{
size_t
raw_size
=
sizeof
(
item_value
)
+
text_len
+
1
-
4
;
return
raw_size
/
sizeof
(
item_value
)
+
((
raw_size
%
sizeof
(
item_value
))
?
1
:
0
);
}
using
item_allocator_type
=
typename
std
::
allocator_traits
<
Alloc
>::
template
rebind_alloc
<
item_value
>
;
using
item_allocator_traits
=
std
::
allocator_traits
<
item_allocator_type
>
;
...
...
@@ -343,15 +344,15 @@ class category_t
// };
item_allocator_traits
::
pointer
get_item
(
size_t
item_size
)
item_allocator_traits
::
pointer
get_item
()
{
item_allocator_type
ia
(
get_allocator
());
return
item_allocator_traits
::
allocate
(
ia
,
item_size
);
return
item_allocator_traits
::
allocate
(
ia
,
1
);
}
item_value
*
create_item
(
uint
32_t
column_ix
,
const
char
*
text
)
item_value
*
create_item
(
uint
16_t
column_ix
,
std
::
string_view
text
)
{
auto
p
=
this
->
get_item
(
calculate_item_size
(
text
)
);
auto
p
=
this
->
get_item
();
item_allocator_type
ia
(
get_allocator
());
item_allocator_traits
::
construct
(
ia
,
p
,
column_ix
,
text
);
return
p
;
...
...
@@ -359,7 +360,7 @@ class category_t
item_value
*
create_item
(
const
item
&
i
)
{
uint
32
_t
ix
=
get_column_ix
(
i
.
name
());
uint
16
_t
ix
=
get_column_ix
(
i
.
name
());
return
create_item
(
ix
,
i
.
c_str
());
}
...
...
include/cif++/v2/item.hpp
View file @
4a1d9c8f
...
...
@@ -31,6 +31,7 @@
#include <iomanip>
#include <memory>
#include <optional>
#include <limits>
namespace
cif
::
v2
{
...
...
@@ -109,22 +110,67 @@ class item
// --------------------------------------------------------------------
// Internal storage, strictly forward linked list with minimal space
// requirements.
// 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
(
uint
32
_t
column_ix
,
const
char
*
value
)
:
m_column_ix
(
column_ix
)
item_value
(
uint
16
_t
column_ix
,
const
char
*
value
)
:
item_value
(
column_ix
,
std
::
string_view
{
value
}
)
{
strcpy
(
m_text
,
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
;
uint32_t
m_column_ix
;
char
m_text
[
4
];
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
)
==
2
*
sizeof
(
void
*
),
"Item value should be two pointers in size...
"
);
static_assert
(
sizeof
(
item_value
)
==
2
4
,
"sizeof(item_value) should be 24 bytes
"
);
// --------------------------------------------------------------------
// Transient object to access stored data
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment