Skip to content

Commit

Permalink
fixup! Polish documentation for the binary module
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorng committed Mar 6, 2025
1 parent 1482d40 commit 1873401
Showing 1 changed file with 46 additions and 39 deletions.
85 changes: 46 additions & 39 deletions lib/stdlib/src/binary.erl
Original file line number Diff line number Diff line change
Expand Up @@ -579,22 +579,26 @@ part(_, _) ->
-doc """
Extracts the part of binary `Subject` described by `PosLen`.

A negative length can be used to extract bytes at the end of a binary:

```erlang
> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
> binary:part(Bin, {byte_size(Bin), -5}).
<<6,7,8,9,10>>
```
A negative length can be used to extract bytes at the end of a binary.

> #### Note {: .info }
>
> `part/2` and `part/3` are also available in the `m:erlang` module under the
> names [`binary_part/2`](`binary_part/2`) and
> [`binary_part/3`](`binary_part/3`). Those BIFs are allowed in guard tests.

If `PosLen` in any way references outside the binary, a `badarg` exception is
raised.
If `Pos` and `Len` in any way references outside the binary, a
`badarg` exception is raised.

## Examples

```erlang
> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
> binary:part(Bin, 1, 3).
<<2,3,4>>
> binary:part(Bin, byte_size(Bin), -5).
<<6,7,8,9,10>>
```
""".
-doc(#{since => <<"OTP R14B">>}).
-spec part(Subject, Pos, Len) -> binary() when
Expand All @@ -614,32 +618,44 @@ used in a program to trigger the use of `copy/1`. By copying
a binary, one can dereference the original, possibly large, binary that a
smaller binary is a reference to.

If a binary references a larger binary (often called a subbinary), it
can be useful to determine the size of the referenced binary. This
function can be used to decide when to trigger `copy/1`. Copying a
binary allows dereferencing the original, potentially large, binary
that the smaller binary refers to.

> #### Note {: .info }
>
> Binary data is shared among processes. If another process still
> references the larger binary, copying only the part used by this
> process will consume more memory without freeing the larger binary for
> garbage collection. Use these intrusive functions with extreme care,
> and only when a real problem has been identified.

## Examples

```erlang
store(Binary, GBSet) ->
NewBin =
case binary:referenced_byte_size(Binary) of
Large when Large > 2 * byte_size(Binary) ->
binary:copy(Binary);
_ ->
Binary
end,
gb_sets:insert(NewBin,GBSet).
NewBin =
case binary:referenced_byte_size(Binary) of
Large when Large > 2 * byte_size(Binary) ->
binary:copy(Binary);
_ ->
Binary
end,
gb_sets:insert(NewBin, GBSet).
```

In this example, we chose to copy the binary content before inserting it in
[`gb_sets:set()`](`t:gb_sets:set/0`) if it references a binary more than twice
the data size we want to keep. Of course, different rules apply when copying to
different programs.

Binary sharing occurs whenever binaries are taken apart. This is the fundamental
reason why binaries are fast, decomposition can always be done with O(1)
complexity. In rare circumstances this data sharing is however undesirable, why
this function together with [`copy/1`](`copy/1`) can be useful when optimizing
for memory use.
In this example, we choose to copy the binary content before inserting
it into [`gb_sets:set()`](`t:gb_sets:set/0`) if it references a binary
more than twice the size of the data we want to retain. Naturally,
different rules apply when copying in different applications.

Example of binary sharing:
Binary sharing occurs whenever binaries are taken apart. This is the
fundamental reason why binaries are fast; decomposition always has
`O(1)` complexity. However, in rare circumstances this data sharing
is undesirable. In such situations, this function, along with
[`copy/1`](`copy/1`) can be useful for optimizing memory usage.

```erlang
> A = binary:copy(<<1>>, 1000).
Expand All @@ -649,23 +665,14 @@ Example of binary sharing:
> binary:referenced_byte_size(A).
1000
> <<B:10/binary, C/binary>> = A.
_
> {byte_size(B), binary:referenced_byte_size(B)}.
{10,10}
> {byte_size(C), binary:referenced_byte_size(C)}.
{990,1000}
```

In the above example, the small binary `B` was copied while the larger binary
`C` references binary `A`.

> #### Note {: .info }
>
> Binary data is shared among processes. If another process still references the
> larger binary, copying the part this process uses only consumes more memory
> and does not free up the larger binary for garbage collection. Use this kind
> of intrusive functions with extreme care and only if a real problem is
> detected.
In the above example, the small binary `B` was copied, while the larger binary
`C` still references binary `A`.
""".
-doc(#{since => <<"OTP R14B">>}).
-spec referenced_byte_size(Binary) -> non_neg_integer() when
Expand Down

0 comments on commit 1873401

Please sign in to comment.