Commit Graph
170 Commits
Author SHA1 Message Date
Alan Somers ff7c0a1d90 Bytes::unsplit (#182)
Add `Bytes::unsplit`, analogous to `BytesMut::unsplit`.
2018-02-26 09:19:20 -08:00
Carl Lerche 355a662976 Bump version 2018-01-29 09:40:45 -08:00
Carl Lerche 3d169f1f34 Update iovec dependency (#179)
Update to match master version of IoVec (0.2.0?), using
IoVec/IoVecMut instead of &IoVec and &mut IoVec.
2018-01-25 22:02:21 -08:00
Alan Somers c316c2433d Optionally disable inlining (#176)
Just document how `from(Vec<u8>)` can be used to disable inlining.
2018-01-14 21:53:07 -08:00
Carl Lerche e5c4c6028d Bump version to v0.4.6 2018-01-08 09:11:42 -08:00
jq-rs ba9a975358 Unsplit improvements (#173)
* Handle empty self and other for unsplit.
* Change extend() to extend_from_slice().
2018-01-05 16:20:59 -08:00
Stepan Koltsov 6a3d20bb8d Optimize shallow_clone for Bytes::split_{off,to} (#92)
If `shallow_clone` is called with `&mut self`, and `Bytes` contains
`Vec`, then expensive CAS can be avoided, because no other thread
have references to this `Bytes` object.

Bench `split_off_and_drop` difference:

Before the diff:

```
test split_off_and_drop             ... bench:      91,858 ns/iter (+/- 17,401)
```

With the diff:

```
test split_off_and_drop             ... bench:      81,162 ns/iter (+/- 17,603)
```
2018-01-03 11:41:33 -08:00
jq-rs 2ca61d881d Add support for unsplit() to BytesMut (#162)
Add support for unsplit() to BytesMut which combines splitted contiguous memory blocks efficiently.
2018-01-03 09:54:51 -08:00
Carl Lerche 8d6c2b61cc Document correct inline capacity in bytes.rs (#171)
Fixes #164
2017-12-15 18:10:30 -06:00
Carl Lerche 02891144be Add advance on Bytes and BytesMut (#166)
* Compact Bytes original capacity representation

In order to avoid unnecessary allocations, a `Bytes` structure remembers
the capacity with which it was first created. When a reserve operation
is issued, this original capacity value is used to as a baseline for
reallocating new storage.

Previously, this original capacity value was stored in its raw form. In
other words, the original capacity `usize` was stored as is. In order to
reclaim some `Bytes` internal storage space for additional features,
this original capacity value is compressed from requiring 16 bits to 3.

To do this, instead of storing the exact original capacity. The original
capacity is rounded down to the nearest power of two. If the original
capacity is less than 1024, then it is rounded down to zero. This
roughly means that the original capacity is now stored as a table:

0 => 0
1 => 1k
2 => 2k
3 => 4k
4 => 8k
5 => 16k
6 => 32k
7 => 64k

For the purposes that the original capacity feature was introduced, this
is sufficient granularity.

* Provide `advance` on Bytes and BytesMut

This is the `advance` function that would be part of a `Buf`
implementation. However, `Bytes` and `BytesMut` cannot impl `Buf` until
the next breaking release.

The implementation uses the additional storage made available by the
previous commit to store the number of bytes that the view was advanced.
The `ptr` pointer will point to the start of the window, avoiding any
pointer arithmetic when dereferencing the `Bytes` handle.
2017-12-13 13:30:03 -06:00
Dan Burkert 03d501b18d small fixups in bytes.rs (#145)
* Inner: make uninitialized construction explicit
* Remove Inner2
* Remove unnecessary transmutes
* Use AtomicPtr::get_mut where possible
* Some minor tweaks
2017-08-18 08:33:28 -07:00
Jef 34540be54c Add FromIterator impl (#148) 2017-08-17 10:32:59 -07:00
Sean McArthur cfca1c04fa print space normally in Debug for Bytes (#155) 2017-08-17 10:28:06 -07:00
Alex Crichton 7839100389 Inline as_ref functions on Bytes and BytesMut (#154) 2017-08-05 21:12:26 -07:00
Paul Collier 6750a26fd0 impl AsMut<[u8]> for BytesMut (#143) (#144) 2017-07-02 14:21:30 -07:00
Stepan Koltsov b9ccd2a866 Optimize Bytes::slice for short slices (#136)
Slice operation should return inline when possible

It is cheaper than atomic increment/decrement.

Before this patch:

```
test slice_avg_le_inline_from_arc   ... bench:      28,582 ns/iter (+/- 3,880)
test slice_empty                    ... bench:       8,797 ns/iter (+/- 1,325)
test slice_large_le_inline_from_arc ... bench:      27,684 ns/iter (+/- 5,920)
test slice_short_from_arc           ... bench:      27,439 ns/iter (+/- 5,783)
```

After this patch:

```
test slice_avg_le_inline_from_arc   ... bench:      18,872 ns/iter (+/- 2,937)
test slice_empty                    ... bench:       9,136 ns/iter (+/- 1,908)
test slice_large_le_inline_from_arc ... bench:      18,052 ns/iter (+/- 2,981)
test slice_short_from_arc           ... bench:      18,200 ns/iter (+/- 2,534)
```
2017-07-01 14:10:09 -07:00
Georg Brandl 544997958f Minor doc spelling and consistency fixes (#142) 2017-07-01 14:03:23 -07:00
Stepan Koltsov d315d00a3b Bytes::with_capacity (#137) 2017-06-30 20:33:35 -07:00
Clint Byrum fb2d8cf1c0 Add convenience PartialEq for BytesMut and Bytes (#141)
Saves the cognitive load of having to wrap them in slices to compare
them when that seems like what one would expect.

Signed-off-by: Clint Byrum <[email protected]>
2017-06-30 20:33:01 -07:00
Dan Burkert 7ed78cef47 Fix index-oob panic in Take::bytes (#138)
The panic happens when `inner.bytes()` returns a slice smaller than the
limit.
2017-06-27 11:23:29 -07:00
Sean McArthur 7e8373da8d Faster From<[u8]> for BytesMut, remove panic in fmt::Write (#133)
* use slice.to_vec instead of buf.put in From<[u8]>

* don't panic in fmt::Write for BytesMut
2017-06-15 10:55:02 -07:00
Stepan Koltsov 9ae51c9f0c Implement truncate, clear for Bytes (#128) 2017-05-26 09:29:31 -07:00
brianwp 2b0602e756 impl ExactSizeIterator for Iter<T: Buf> (#127) 2017-05-24 08:13:19 -07:00
Stepan Koltsov 3f5890be70 Optimize Bytes::slice(n, n) (#123)
Return empty `Bytes` object

Bench for `slice_empty` difference is

```
55 ns/iter (+/- 1) # before this patch
17 ns/iter (+/- 5) # with this patch
```

Bench for `slice_not_empty` is

```
25,058 ns/iter (+/- 1,099) # before this patch
25,072 ns/iter (+/- 1,593) # with this patch
```
2017-05-22 13:15:08 -07:00
Stepan Koltsov edf1af958a Minor doc fixes (#124) 2017-05-22 11:30:34 -07:00
Stepan Koltsov 7110d57b2f BytesMut::reserve should not overallocate (#117)
Round up to power of 2 is not necessary, because `reserve` already
doubles previous capacity in

```
	new_cap = cmp::max(
		cmp::max(v.capacity() << 1, new_cap),
		original_capacity);
```

which makes `reserve` calls constant in average. Avoiding rounding
up prevents `reserve` from wasting space when caller knows exactly
what space they need.

Patch adds three tests which would fail before this test. The most
important is this:

```
#[test]
fn reserve_in_arc_unique_does_not_overallocate() {
    let mut bytes = BytesMut::with_capacity(1000);
    bytes.take();

    // now bytes is Arc and refcount == 1

    assert_eq!(1000, bytes.capacity());
    bytes.reserve(2001);
    assert_eq!(2001, bytes.capacity());
}
```

It asserts that when user requests more than double of current
capacity, exactly the requested amount of memory is allocated and
is not wasted to next power of two.
2017-05-15 11:28:12 -07:00
Stepan Koltsov 07db74b009 Bytes::extend_from_slice (#120)
`extend_with_slice` is super-convenient operation on `Bytes`.

While `put_u8` would be expensive on `Bytes`, `extend_from_slice`
is OK, because it is batch, and it checks for kind only once.

Patch also adds `impl Extend for Bytes`.

cc #116
2017-05-15 11:27:45 -07:00
Jack O'Connor 6af66c4f21 fix a docs typo (#115) 2017-05-02 12:35:06 -07:00
Stepan Koltsov fa44c7e355 BytesMut::extend_from_slice shortcut (#112)
Similar to `Vec::extend_from_slice`: it a reserve followed by
memcopy.
2017-05-02 11:28:12 -07:00
Stepan Koltsov 2c0cb1b6b8 BytesMut::new constructor (#114) 2017-05-02 11:23:20 -07:00
Arthur Silva b196559818 Add serde support behind serde feature (#96) 2017-05-02 10:51:52 -07:00
Sean McArthur 37f6cabd96 implement Default for Bytes and BytesMut (#110) 2017-05-01 12:53:27 -07:00
Dan Burkert 30bd7c1f21 Vec::advance_mut can advance past the end of the buffer (#108) 2017-04-30 16:14:54 -07:00
Phil Ruffwind 0b4185c716 Fix typos in src/bytes.rs (#106) 2017-04-24 12:47:24 -07:00
jaystrictor e158160418 Remove calls to deprecated drain* methods from docs (#102) 2017-04-14 09:06:58 -07:00
Sean McArthur 4645f6ec4b implement put_u8 for BytesMut (#101) 2017-04-06 08:59:13 -07:00
Carl Lerche 9aa24ebea1 Bytes: only the vec repr is not shared (#100)
The shared debug_assert is to ensure that the internal Bytes
representation is such that offset views are supported. The only
representation that does not support offset views is vec.

Fixes #97
2017-03-30 14:49:30 -07:00
Stepan Koltsov 627864187c Bytes::split_{off,to} should panic if at > len (#91) 2017-03-28 12:38:48 -07:00
Stepan Koltsov b78bb3baaa Handle corner cases of Bytes::split_{off,to} (#87)
Before this commit `Bytes::split_{off,to}` always created a shallow copy if `self` is arc or vec.

However, in certain cases `split_off` or `split_to` is called with `len` or `0` parameter. E. g. if you are reading a frame from buffered stream, it is likely that buffer contains exactly the frame size bytes, so `split_to` will be called with `len` param.

Although, `split_off` and `split_to` functions are `O(1)`, shallow copy have downsides:

* shallow copy on vector does malloc and atomic cmpxchg
* after shallow copy, following operations (e. g. `drop`) on both `bytes` objects require atomics
* memory will be probably released to the system later
* `try_mut` will fail
* [into_vec](https://github.com/carllerche/bytes/issues/86) will copy
2017-03-27 20:45:22 -07:00
Alex Crichton 6c6c55d8e1 Flag Deref methods as #[inline] (#93) 2017-03-24 07:39:57 -07:00
Stepan Koltsov 613d4bd5d5 Reimplement fmt::Debug for Bytes and BytesMut (#84)
Standard `Debug` implementation for `[u8]` is comma separated list
of numbers. Since large amount of byte strings are in fact ASCII
strings or contain a lot of ASCII strings (e. g. HTTP), it is
convenient to print strings as ASCII when possible.
2017-03-20 21:09:44 -07:00
Carl Lerche bed128b2c0 Clarify when BufMut::bytes_mut can return &[]
Closes #79
2017-03-19 13:58:44 -07:00
Dan Burkert 5a265cc8eb Add inline attributes to Vec's MutBuf methods (#80)
I found this significantly improved a
[benchmark](https://gist.github.com/danburkert/34a7d6680d97bc86dca7f396eb8d0abf)
which calls `bytes_mut`, writes 1 byte, and advances the pointer with
`advance_mut` in a pretty tight loop. In particular, it seems to be the
inline annotation on `bytes_mut` which had the most effect. I also took
the opportunity to simplify the bounds checking in advance_mut.

before:

```
test encode_varint_small  ... bench:         540 ns/iter (+/- 85) = 1481 MB/s
```

after:

```
test encode_varint_small  ... bench:         422 ns/iter (+/- 24) = 1895 MB/s
```

As you can see, the variance is also significantly improved.

Interestingly, I tried to change the last statement in `bytes_mut` from

```
&mut slice::from_raw_parts_mut(ptr, cap)[len..]
```

to

```
slice::from_raw_parts_mut(ptr.offset(len as isize), cap - len)
```

but, this caused a very measurable perf regression (almost completely
negating the gains from marking bytes_mut inline).
2017-03-19 13:54:09 -07:00
Dan Burkert 4fe4e9429a Clarify BufMut::advance_mut docs (#78)
Also fixes an issue with a line wrap in the middle of an inline code
block.
2017-03-19 13:53:33 -07:00
Carl Lerche 99fba239db Tweak docs (#76) 2017-03-16 12:11:10 -07:00
Carl Lerche 2e319b51be Impl Extend for BytesMut 2017-03-07 15:06:47 -08:00
Carl Lerche 06b94c55b0 Remove buf::Source in favor of buf::IntoBuf
The `Source` trait was essentially covering the same case as `IntoBuf`,
so remove it.

While technically a breaking change, this should not have any impact due
to:

1) There are no reverse dependencies that currently depend on `bytes`
2) Source was not supposed to be implemented externally
3) IntoBuf provides the same implementations as `Source`

Given these points, the change should be safe to apply.
2017-03-07 11:30:08 -08:00
Carl Lerche d70f575afd Provide Debug impls for all types 2017-03-07 10:20:58 -08:00
Carl Lerche 933b8b26f6 BytesMut::reserve should avoid small allocations
This change tracks the original capacity requested when `BytesMut` is
first created. This capacity is used when a `reserve` needs to allocate
due to the current view being too small. The newly allocated buffer will
be sized the same as the original allocation.
2017-03-02 16:14:14 -08:00
Carl Lerche b44fc31463 Move Inner constructions to struct fns 2017-03-02 13:46:14 -08:00