brpc uses [butil::IOBuf](https://github.com/brpc/brpc/blob/master/src/butil/iobuf.h) as data structure for attachment storage and HTTP body. It is a non-contiguous zero copy buffer, which has been proved in other projects as excellent performance. The interface of `IOBuf` is similar to `std::string`, but not the same.
[中文版](../cn/iobuf.md)
If you used the `BufHandle` in Kylin before, you should notice the difference in convenience of `IOBuf`: the former hardly had any encapsulation, leaving the internal structure directly in front of the user. The user must carefully handle the reference count, which is very error prone, leading to lots of bugs.
brpc uses [butil::IOBuf](https://github.com/brpc/brpc/blob/master/src/butil/iobuf.h) as data structure for attachment in some protocols and HTTP body. It's a non-contiguous zero-copied buffer, proved in previous projects, and good at performance. The interface of `IOBuf` is similar to `std::string`, but not the same.
# What IOBuf can:
If you've used the `BufHandle` in Kylin before, you should notice the convenience of `IOBuf`: the former one is badly encapsulated, leaving the internal structure directly in front of users, who must carefully handle the referential countings, very error prone and leading to bugs.
- Default constructor doesn't involve copying.
# What IOBuf can:
- Explicit copy doesn't change source IOBuf. Only copy the management structure of IOBuf instead of the data.
- Append another IOBuf without copy.
- Append string involves copy.
- Read from/Write into fd.
- Convert to protobuf and vice versa.
- IOBufBuilder可以把IOBuf当std::ostream用。
# What IOBuf can't:
- Default constructor does not allocate memory.
- Copyable. Modifications to the copy doesn't affect the original one. Copy the managing structure of IOBuf only rather the payload.
- Append another IOBuf without copying payload.
- Can append string, by copying payload.
- Read from or write into file descriptors.
- Serialize to or parse from protobuf messages.
- constructible like a std::ostream using IOBufBuilder.
- Used as general storage structure. IOBuf should not keep a long life cycle to prevent multiple memory blocks (8K each) being locked by one IOBuf object.
# What IOBuf can't:
# Slice
- Used as universal string-like structure in the program. Lifetime of IOBuf should be short, to prevent the referentially counted blocks(8K each) in IOBuf lock too many memory.
Slice 16 bytes from IOBuf:
# Cut
Cut 16 bytes from front-side of source_buf and append to dest_buf:
```c++
```c++
source_buf.cut(&heading_iobuf,16);// cut all bytes of source_buf when its length < 16
source_buf.cut(&dest_buf,16);// cut all bytes of source_buf when its length < 16
```
```
Remove 16 bytes:
Just pop 16 bytes from front-side of source_buf:
```c++
```c++
source_buf.pop_front(16);// Empty source_buf when its length < 16
source_buf.pop_front(16);// Empty source_buf when its length < 16
```
```
# Concatenate
# Append
Append to another IOBuf:
Append another IOBuf to back-side:
```c++
```c++
buf.append(another_buf);// no data copy
buf.append(another_buf);// no data copy
```
```
Append std::string
Append std::string to back-sie
```c++
```c++
buf.append(str);// copy data of str into buf
buf.append(str);// copy data of str into buf
...
@@ -46,14 +48,14 @@ buf.append(str); // copy data of str into buf
...
@@ -46,14 +48,14 @@ buf.append(str); // copy data of str into buf