Commit 40a24cb6 authored by Helios Alonso Cabanillas's avatar Helios Alonso Cabanillas Committed by Jordan DeLong

Add samples to FBVector documentation

Summary: Added two samples of use for FBVector in docs

Test Plan: just check if FBVector.md looks good.

Reviewed By: njormrod@fb.com

FB internal diff: D636813
parent 3e8d7341
...@@ -8,10 +8,20 @@ common coding patterns. The improvements are always non-negative, ...@@ -8,10 +8,20 @@ common coding patterns. The improvements are always non-negative,
almost always measurable, frequently significant, sometimes almost always measurable, frequently significant, sometimes
dramatic, and occasionally spectacular. dramatic, and occasionally spectacular.
### Sample
***
folly::fbvector<int> numbers({0, 1, 2, 3});
numbers.reserve(10);
for (int i = 4; i < 10; i++) {
numbers.push_back(i * 2);
}
assert(numbers[6] == 12);
### Motivation ### Motivation
*** ***
std::vector is the stalwart abstraction many use for `std::vector` is the stalwart abstraction many use for
dynamically-allocated arrays in C++. It is also the best known dynamically-allocated arrays in C++. It is also the best known
and most used of all containers. It may therefore seem a and most used of all containers. It may therefore seem a
surprise that `std::vector` leaves important - and sometimes surprise that `std::vector` leaves important - and sometimes
...@@ -51,17 +61,13 @@ Continuing this process we'll then have a chunk of size k * k * C ...@@ -51,17 +61,13 @@ Continuing this process we'll then have a chunk of size k * k * C
to the right and so on. That leads to a series of the form (using to the right and so on. That leads to a series of the form (using
^^ for power): ^^ for power):
```
C, C*k, C*k^^2, C*k^^3, ... C, C*k, C*k^^2, C*k^^3, ...
```
If we choose k = 2 we know that every element in the series will If we choose k = 2 we know that every element in the series will
be strictly larger than the sum of all previous ones because of be strictly larger than the sum of all previous ones because of
the remarkable equality: the remarkable equality:
```
1 + 2^^1 + 2^^2 + 2^^3... + 2^^n = 2^^(n+1) - 1 1 + 2^^1 + 2^^2 + 2^^3... + 2^^n = 2^^(n+1) - 1
```
What that really means is that the new request for a chunk will What that really means is that the new request for a chunk will
be never satisfiable by coalescing all previously-used chunks. be never satisfiable by coalescing all previously-used chunks.
...@@ -73,9 +79,7 @@ chunks. Any number smaller than 2 guarantees that you'll be able ...@@ -73,9 +79,7 @@ chunks. Any number smaller than 2 guarantees that you'll be able
at some point to reuse the previous chunks. Going through the at some point to reuse the previous chunks. Going through the
math reveals the equation: math reveals the equation:
```
k^^n <= 1 + k + k^^2 + ... + k^^(n-2) k^^n <= 1 + k + k^^2 + ... + k^^(n-2)
```
If some number n satisfies that equation, it means you can reuse If some number n satisfies that equation, it means you can reuse
memory after n reallocations. The graphical solver below reveals memory after n reallocations. The graphical solver below reveals
...@@ -160,15 +164,12 @@ Only a tiny minority of objects are genuinely non-relocatable: ...@@ -160,15 +164,12 @@ Only a tiny minority of objects are genuinely non-relocatable:
* Objects that use internal pointers, e.g.: * Objects that use internal pointers, e.g.:
``` Cpp
class Ew { class Ew {
char buffer[1024]; char buffer[1024];
char * pointerInsideBuffer; char * pointerInsideBuffer;
public: public:
Ew() : pointerInsideBuffer(buffer) {} Ew() : pointerInsideBuffer(buffer) {}
... ...
};
```
* Objects that need to update "observers" that store pointers to them. * Objects that need to update "observers" that store pointers to them.
...@@ -194,12 +195,10 @@ trait `folly::IsRelocatable` defined in `"folly/Traits.h"`. By default, ...@@ -194,12 +195,10 @@ trait `folly::IsRelocatable` defined in `"folly/Traits.h"`. By default,
you know that your type `Widget` is in fact relocatable, go right you know that your type `Widget` is in fact relocatable, go right
after `Widget`'s definition and write this: after `Widget`'s definition and write this:
``` Cpp
// at global namespace level // at global namespace level
namespace folly { namespace folly {
struct IsRelocatable<Widget> : boost::true_type {}; struct IsRelocatable<Widget> : boost::true_type {};
} }
```
If you don't do this, `fbvector<Widget>` will fail to compile If you don't do this, `fbvector<Widget>` will fail to compile
with a `BOOST_STATIC_ASSERT`. with a `BOOST_STATIC_ASSERT`.
...@@ -215,11 +214,9 @@ already present in the C++ standard (well, currently in Boost). ...@@ -215,11 +214,9 @@ already present in the C++ standard (well, currently in Boost).
To summarize, in order to work with `fbvector`, a type `Widget` To summarize, in order to work with `fbvector`, a type `Widget`
must pass: must pass:
``` Cpp
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(
IsRelocatable<Widget>::value && IsRelocatable<Widget>::value &&
(boost::has_trivial_assign<T>::value || boost::has_nothrow_constructor<T>::value)); (boost::has_trivial_assign<T>::value || boost::has_nothrow_constructor<T>::value));
```
These traits go hand in hand; for example, it would be very These traits go hand in hand; for example, it would be very
difficult to design a class that satisfies one branch of the difficult to design a class that satisfies one branch of the
...@@ -240,3 +237,5 @@ directions may be in improving raw memory copying (`memcpy` is ...@@ -240,3 +237,5 @@ directions may be in improving raw memory copying (`memcpy` is
not an intrinsic in gcc and does not work terribly well for not an intrinsic in gcc and does not work terribly well for
large chunks) and in furthering the collaboration with large chunks) and in furthering the collaboration with
jemalloc. Have fun! jemalloc. Have fun!
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