# `Electric.Postgres.Lsn`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.5.1/packages/sync-service/lib/electric/postgres/lsn.ex#L1)

Encoding, decoding and helper functions for the pg_lsn type.

# `int32`

```elixir
@type int32() :: 0..4_294_967_295
```

# `t`

```elixir
@type t() :: %Electric.Postgres.Lsn{offset: int32(), segment: int32()}
```

# `compare`

```elixir
@spec compare(t(), t()) :: :eq | :gt | :lt
```

Compare two Lsns and determine if one is less or greater or both are equal.

## Examples

    iex> compare(from_integer(0), from_integer(1))
    :lt
    iex> compare(from_string("1/0"), from_string("2/0"))
    :lt

    iex> compare(from_integer(99), from_integer(98))
    :gt
    iex> compare(from_string("2/0"), from_string("1/0"))
    :gt

    iex> compare(from_integer(127_000_256), from_string("0/791DEC0"))
    :eq

# `decode_bin`

```elixir
@spec decode_bin(binary()) :: t()
```

Decode a binary representation of the LSN into a struct. Reverses `encode_bin/1`

## Examples

    iex> decode_bin(encode_bin(%Elixir.Electric.Postgres.Lsn{}))
    %Elixir.Electric.Postgres.Lsn{}

# `encode_bin`

```elixir
@spec encode_bin(t()) :: binary()
```

# `from_integer`

```elixir
@spec from_integer(non_neg_integer()) :: t()
```

Convert the non-negative byte offset into Lsn.

## Examples

    iex> from_integer(0)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0}

    iex> from_integer(1_000_000)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 1_000_000}

    iex> from_integer(0xFFFFFFFF)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 4294967295}

    iex> from_integer(0xFFFFFFFFF)
    %Elixir.Electric.Postgres.Lsn{segment: 15, offset: 4294967295}

    iex> from_integer(-1)
    ** (FunctionClauseError) no function clause matching in Electric.Postgres.Lsn.from_integer/1

# `from_string`

```elixir
@spec from_string(String.t()) :: t()
```

Parse the given string as a pg_lsn value.

## Examples

    iex> from_string("0/0")
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0}

    iex> from_string("7F/400")
    %Elixir.Electric.Postgres.Lsn{segment: 127, offset: 1024}

# `increment`

```elixir
@spec increment(t(), integer()) :: t()
```

Add the given byte offset to the Lsn value.

The result is capped at the bottom to not go below #Lsn<0/0>.

## Examples

    iex> increment(from_integer(0), 8_000_000)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 8_000_000}

    iex> increment(from_integer(4_000_000_000), 1_000_000_000)
    %Elixir.Electric.Postgres.Lsn{segment: 1, offset: 705_032_704}

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 1, offset: 705_032_704})
    5_000_000_000

    iex> increment(from_integer(4_000_000_000), 10_000_000_000)
    %Elixir.Electric.Postgres.Lsn{segment: 3, offset: 1_115_098_112}

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 3, offset: 1_115_098_112})
    14_000_000_000

    iex> increment(from_integer(14_000_000_000), -8_000_000_000)
    %Elixir.Electric.Postgres.Lsn{segment: 1, offset: 1_705_032_704}

    iex> increment(from_integer(100), -99)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 1}

    iex> increment(from_integer(100), -100)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0}

    iex> increment(from_integer(100), -101)
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0}

# `is_larger`
*macro* 

Determine if the first Lsn is larger than the second.

## Examples

  iex> lsn1 = %Lsn{segment: 2, offset: 10}
  iex> lsn2 = %Lsn{segment: 1, offset: 50}
  iex> is_larger(lsn1, lsn2)
  true

  iex> lsn1 = %Lsn{segment: 3, offset: 5}
  iex> lsn2 = %Lsn{segment: 3, offset: 4}
  iex> is_larger(lsn1, lsn2)
  true

  iex> lsn1 = Lsn.from_string("166A/91FDFDE8")
  iex> lsn2 = Lsn.from_string("1667/FFFFFCC8")
  iex> is_larger(lsn1, lsn2)
  true

  iex> lsn1 = Lsn.from_string("FFFFFFFB/91FDFDE8")
  iex> lsn2 = Lsn.from_string("FFFFFFFA/FFFFFCC8")
  iex> is_larger(lsn1, lsn2)
  true

  iex> lsn1 = %{segment: 2, offset: 100}
  iex> lsn2 = %{segment: 2, offset: 200}
  iex> is_larger(lsn1, lsn2)
  false

  iex> lsn1 = %{segment: 1, offset: 30}
  iex> lsn2 = %{segment: 1, offset: 30}
  iex> is_larger(lsn1, lsn2)
  false

# `max`

```elixir
@spec max(Enumerable.t(t())) :: t()
```

Returns the highest Lsn from the given list of Lsns.

When the list is empty, it returns #Lsn<0/0>.

## Examples
    iex> max([%Elixir.Electric.Postgres.Lsn{segment: 0, offset: 1}, %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 2}])
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 2}

    iex> max([%Elixir.Electric.Postgres.Lsn{segment: 1, offset: 1}, %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 2}])
    %Elixir.Electric.Postgres.Lsn{segment: 1, offset: 1}

    iex> max([])
    %Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0}

# `to_integer`

```elixir
@spec to_integer(t()) :: non_neg_integer()
```

Convert the Lsn into an equivalent byte offset.

## Examples

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 0, offset: 0})
    0

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 0, offset: 1_000_000})
    1_000_000

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 0, offset: 4294967295})
    0xFFFFFFFF

    iex> to_integer(%Elixir.Electric.Postgres.Lsn{segment: 15, offset: 4294967295})
    0xFFFFFFFFF

# `to_iolist`

```elixir
@spec to_iolist(t()) :: iolist()
```

Format Lsn to its text representation in an iolist.

## Examples

    iex> to_iolist(%Elixir.Electric.Postgres.Lsn{})
    ["0", ?/, "0"]

    iex> to_iolist(%Elixir.Electric.Postgres.Lsn{segment: 127, offset: 1024})
    ["7F", ?/, "400"]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
