Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
e6e29122
Commit
e6e29122
authored
Sep 25, 2016
by
Kenton Varda
Committed by
Kenton Varda
Apr 07, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better-optimize Vector and ArrayBuilder for trivial types.
parent
8f858fc4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
96 additions
and
26 deletions
+96
-26
array.h
c++/src/kj/array.h
+85
-14
vector.h
c++/src/kj/vector.h
+11
-12
No files found.
c++/src/kj/array.h
View file @
e6e29122
...
@@ -376,10 +376,11 @@ public:
...
@@ -376,10 +376,11 @@ public:
template
<
typename
Container
>
template
<
typename
Container
>
void
addAll
(
Container
&&
container
)
{
void
addAll
(
Container
&&
container
)
{
addAll
(
container
.
begin
(),
container
.
end
());
addAll
<
decltype
(
container
.
begin
()),
!
isReference
<
Container
>
()
>
(
container
.
begin
(),
container
.
end
());
}
}
template
<
typename
Iterator
>
template
<
typename
Iterator
,
bool
move
=
false
>
void
addAll
(
Iterator
start
,
Iterator
end
);
void
addAll
(
Iterator
start
,
Iterator
end
);
void
removeLast
()
{
void
removeLast
()
{
...
@@ -387,6 +388,44 @@ public:
...
@@ -387,6 +388,44 @@ public:
kj
::
dtor
(
*--
pos
);
kj
::
dtor
(
*--
pos
);
}
}
void
truncate
(
size_t
size
)
{
KJ_IREQUIRE
(
size
<=
this
->
size
(),
"can't use truncate() to expand"
);
T
*
target
=
ptr
+
size
;
if
(
__has_trivial_destructor
(
T
))
{
pos
=
target
;
}
else
{
while
(
pos
>
target
)
{
kj
::
dtor
(
*--
pos
);
}
}
}
void
resize
(
size_t
size
)
{
KJ_IREQUIRE
(
size
<=
capacity
(),
"can't resize past capacity"
);
T
*
target
=
ptr
+
size
;
if
(
target
>
pos
)
{
// expand
if
(
__has_trivial_constructor
(
T
))
{
pos
=
target
;
}
else
{
while
(
pos
<
target
)
{
kj
::
ctor
(
*
pos
++
);
}
}
}
else
{
// truncate
if
(
__has_trivial_destructor
(
T
))
{
pos
=
target
;
}
else
{
while
(
pos
>
target
)
{
kj
::
dtor
(
*--
pos
);
}
}
}
}
Array
<
T
>
finish
()
{
Array
<
T
>
finish
()
{
// We could safely remove this check if we assume that the disposer implementation doesn't
// We could safely remove this check if we assume that the disposer implementation doesn't
// need to know the original capacity, as is thes case with HeapArrayDisposer since it uses
// need to know the original capacity, as is thes case with HeapArrayDisposer since it uses
...
@@ -615,11 +654,11 @@ T* HeapArrayDisposer::allocateUninitialized(size_t count) {
...
@@ -615,11 +654,11 @@ T* HeapArrayDisposer::allocateUninitialized(size_t count) {
return
Allocate_
<
T
,
true
,
true
>::
allocate
(
0
,
count
);
return
Allocate_
<
T
,
true
,
true
>::
allocate
(
0
,
count
);
}
}
template
<
typename
Element
,
typename
Iterator
,
bool
=
canMemcpy
<
Element
>
()
>
template
<
typename
Element
,
typename
Iterator
,
bool
move
,
bool
=
canMemcpy
<
Element
>
()
>
struct
CopyConstructArray_
;
struct
CopyConstructArray_
;
template
<
typename
T
>
template
<
typename
T
,
bool
move
>
struct
CopyConstructArray_
<
T
,
T
*
,
true
>
{
struct
CopyConstructArray_
<
T
,
T
*
,
move
,
true
>
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
T
*
start
,
T
*
end
)
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
T
*
start
,
T
*
end
)
{
memcpy
(
pos
,
start
,
reinterpret_cast
<
byte
*>
(
end
)
-
reinterpret_cast
<
byte
*>
(
start
));
memcpy
(
pos
,
start
,
reinterpret_cast
<
byte
*>
(
end
)
-
reinterpret_cast
<
byte
*>
(
start
));
return
pos
+
(
end
-
start
);
return
pos
+
(
end
-
start
);
...
@@ -627,15 +666,15 @@ struct CopyConstructArray_<T, T*, true> {
...
@@ -627,15 +666,15 @@ struct CopyConstructArray_<T, T*, true> {
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
CopyConstructArray_
<
T
,
const
T
*
,
true
>
{
struct
CopyConstructArray_
<
T
,
const
T
*
,
false
,
true
>
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
const
T
*
start
,
const
T
*
end
)
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
const
T
*
start
,
const
T
*
end
)
{
memcpy
(
pos
,
start
,
reinterpret_cast
<
const
byte
*>
(
end
)
-
reinterpret_cast
<
const
byte
*>
(
start
));
memcpy
(
pos
,
start
,
reinterpret_cast
<
const
byte
*>
(
end
)
-
reinterpret_cast
<
const
byte
*>
(
start
));
return
pos
+
(
end
-
start
);
return
pos
+
(
end
-
start
);
}
}
};
};
template
<
typename
T
,
typename
Iterator
>
template
<
typename
T
,
typename
Iterator
,
bool
move
>
struct
CopyConstructArray_
<
T
,
Iterator
,
true
>
{
struct
CopyConstructArray_
<
T
,
Iterator
,
move
,
true
>
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
Iterator
start
,
Iterator
end
)
{
static
inline
T
*
apply
(
T
*
__restrict__
pos
,
Iterator
start
,
Iterator
end
)
{
// Since both the copy constructor and assignment operator are trivial, we know that assignment
// Since both the copy constructor and assignment operator are trivial, we know that assignment
// is equivalent to copy-constructing. So we can make this case somewhat easier for the
// is equivalent to copy-constructing. So we can make this case somewhat easier for the
...
@@ -648,7 +687,7 @@ struct CopyConstructArray_<T, Iterator, true> {
...
@@ -648,7 +687,7 @@ struct CopyConstructArray_<T, Iterator, true> {
};
};
template
<
typename
T
,
typename
Iterator
>
template
<
typename
T
,
typename
Iterator
>
struct
CopyConstructArray_
<
T
,
Iterator
,
false
>
{
struct
CopyConstructArray_
<
T
,
Iterator
,
false
,
false
>
{
struct
ExceptionGuard
{
struct
ExceptionGuard
{
T
*
start
;
T
*
start
;
T
*
pos
;
T
*
pos
;
...
@@ -683,16 +722,48 @@ struct CopyConstructArray_<T, Iterator, false> {
...
@@ -683,16 +722,48 @@ struct CopyConstructArray_<T, Iterator, false> {
};
};
template
<
typename
T
,
typename
Iterator
>
template
<
typename
T
,
typename
Iterator
>
inline
T
*
copyConstructArray
(
T
*
dst
,
Iterator
start
,
Iterator
end
)
{
struct
CopyConstructArray_
<
T
,
Iterator
,
true
,
false
>
{
return
CopyConstructArray_
<
T
,
Decay
<
Iterator
>>::
apply
(
dst
,
start
,
end
);
// Actually move-construct.
}
struct
ExceptionGuard
{
T
*
start
;
T
*
pos
;
inline
explicit
ExceptionGuard
(
T
*
pos
)
:
start
(
pos
),
pos
(
pos
)
{}
~
ExceptionGuard
()
noexcept
(
false
)
{
while
(
pos
>
start
)
{
dtor
(
*--
pos
);
}
}
};
static
T
*
apply
(
T
*
__restrict__
pos
,
Iterator
start
,
Iterator
end
)
{
// Verify that T can be *implicitly* constructed from the source values.
if
(
false
)
implicitCast
<
T
>
(
kj
::
mv
(
*
start
));
if
(
noexcept
(
T
(
kj
::
mv
(
*
start
))))
{
while
(
start
!=
end
)
{
ctor
(
*
pos
++
,
kj
::
mv
(
*
start
++
));
}
return
pos
;
}
else
{
// Crap. This is complicated.
ExceptionGuard
guard
(
pos
);
while
(
start
!=
end
)
{
ctor
(
*
guard
.
pos
,
kj
::
mv
(
*
start
++
));
++
guard
.
pos
;
}
guard
.
start
=
guard
.
pos
;
return
guard
.
pos
;
}
}
};
}
// namespace _ (private)
}
// namespace _ (private)
template
<
typename
T
>
template
<
typename
T
>
template
<
typename
Iterator
>
template
<
typename
Iterator
,
bool
move
>
void
ArrayBuilder
<
T
>::
addAll
(
Iterator
start
,
Iterator
end
)
{
void
ArrayBuilder
<
T
>::
addAll
(
Iterator
start
,
Iterator
end
)
{
pos
=
_
::
copyConstructArra
y
(
pos
,
start
,
end
);
pos
=
_
::
CopyConstructArray_
<
RemoveConst
<
T
>
,
Decay
<
Iterator
>
,
move
>::
appl
y
(
pos
,
start
,
end
);
}
}
template
<
typename
T
>
template
<
typename
T
>
...
...
c++/src/kj/vector.h
View file @
e6e29122
...
@@ -95,12 +95,7 @@ public:
...
@@ -95,12 +95,7 @@ public:
inline
void
resize
(
size_t
size
)
{
inline
void
resize
(
size_t
size
)
{
if
(
size
>
builder
.
capacity
())
grow
(
size
);
if
(
size
>
builder
.
capacity
())
grow
(
size
);
while
(
builder
.
size
()
<
size
)
{
builder
.
resize
(
size
);
builder
.
add
(
T
());
}
while
(
builder
.
size
()
>
size
)
{
builder
.
removeLast
();
}
}
}
inline
void
operator
=
(
decltype
(
nullptr
))
{
inline
void
operator
=
(
decltype
(
nullptr
))
{
...
@@ -114,8 +109,12 @@ public:
...
@@ -114,8 +109,12 @@ public:
}
}
inline
void
truncate
(
size_t
size
)
{
inline
void
truncate
(
size_t
size
)
{
while
(
builder
.
size
()
>
size
)
{
builder
.
truncate
(
size
);
builder
.
removeLast
();
}
inline
void
reserve
(
size_t
size
)
{
if
(
size
>
builder
.
capacity
())
{
setCapacity
(
size
);
}
}
}
}
...
@@ -126,11 +125,11 @@ private:
...
@@ -126,11 +125,11 @@ private:
setCapacity
(
kj
::
max
(
minCapacity
,
capacity
()
==
0
?
4
:
capacity
()
*
2
));
setCapacity
(
kj
::
max
(
minCapacity
,
capacity
()
==
0
?
4
:
capacity
()
*
2
));
}
}
void
setCapacity
(
size_t
newSize
)
{
void
setCapacity
(
size_t
newSize
)
{
ArrayBuilder
<
T
>
newBuilder
=
heapArrayBuilder
<
T
>
(
newSize
);
if
(
builder
.
size
()
>
newSize
)
{
size_t
moveCount
=
kj
::
min
(
newSize
,
builder
.
size
());
builder
.
truncate
(
newSize
);
for
(
size_t
i
=
0
;
i
<
moveCount
;
i
++
)
{
newBuilder
.
add
(
kj
::
mv
(
builder
[
i
]));
}
}
ArrayBuilder
<
T
>
newBuilder
=
heapArrayBuilder
<
T
>
(
newSize
);
newBuilder
.
addAll
(
kj
::
mv
(
builder
));
builder
=
kj
::
mv
(
newBuilder
);
builder
=
kj
::
mv
(
newBuilder
);
}
}
};
};
...
...
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