View Source Vtc.Ecto.Postgres.PgFramestamp.FastRange (vtc v0.17.5)

Framestamp_fastrange use floats for faster comparison operations and are defined as follows:

CREATE TYPE framestamp_fastrange AS RANGE (
  subtype = double precision,
  subtype_diff = float8mi
);

Framestamp fastranges can be created in SQL expressions like so:

SELECT framestamp_fastrange(stamp_1, stamp_2)

Indexing

framestamp_fastrange is considerably faster than framestamp_range when building GiST indexes.

Loading

Since FastRanges do not store framerate, they cannot be re-constituted to a normal framestamp range once cast. Trying to deserialize one using this type will fail.

fragments

Fragments

FastRange values must be explicitly cast from a Framestamp.Range using type/2:

stamp_in = Framestamp.with_frames!("01:00:00:00", Rates.f23_98())
stamp_out = Framestamp.with_frames!("02:00:00:00", Rates.f23_98())
stamp_range = Framestamp.Range.new!(stamp_in, stamp_out)

query = Query.from(
  f in fragment("SELECT ? as r", type(^stamp_range, Framerate.FastRange)), select: f.r
)

Casting in this way serializes our range in elixir, rather than asking the database to do so during a query.

When creating framestamp_fastrange values in this way, the range will always be converted to an EXCLUSIVE out point.

on-frame-accuracy

On frame-accuracy

Vtc's position is that rational values are necessary for frame-accurate timecode manipulation, so why does it put forth a float-based range type?

The main risk of using floats is unpredictable floating-point errors stacking up during arithmetic operations so that when you go to compare two values that SHOULD be equal, they aren't.

However, if you do all calculations with rational values -- up to the point where you need to compare them -- it is safe to cast to floats for the comparison operation, as equal rational values will always cast to the same float value.

Link to this section Summary

Types

Type of the raw composite value that will be sent to the database.

Ecto Migrations

The database type for PgFramerate.

Functions

Callback implementation for Ecto.Type.embed_as/1.

Callback implementation for Ecto.Type.equal?/2.

Link to this section Types

@type db_record() :: %Postgrex.Range{
  lower: float(),
  lower_inclusive: boolean(),
  upper: float(),
  upper_inclusive: boolean()
}

Type of the raw composite value that will be sent to the database.

Link to this section Ecto Migrations

@spec type() :: atom()

The database type for PgFramerate.

Can be used in migrations as the fields type.

Link to this section Functions

Callback implementation for Ecto.Type.embed_as/1.

Callback implementation for Ecto.Type.equal?/2.