~kb/sparse

6446592707f6409634b1746d9bb56962b7eb3a66 — Kim Burgess 3 years ago 5370ad6
Simplify element lookup
1 files changed, 24 insertions(+), 12 deletions(-)

M src/sparse/vector.cr
M src/sparse/vector.cr => src/sparse/vector.cr +24 -12
@@ 98,8 98,8 @@ module Sparse
    # Remove one stored element.
    def remove_element(index : Int) : T?
      check_index_out_of_bounds index
      pos = @idx.bsearch_index &.==(index)
      if del
      pos = unsafe_pos index
      if pos
        @idx.delete_at pos
        @val.delete_at pos
      end


@@ 108,10 108,7 @@ module Sparse
    # Extract one element of *self* into a scalar.
    def extract_element(index : Int) : T?
      check_index_out_of_bounds index
      pos = @idx.bsearch_index &.==(index)
      if pos
        @val.unsafe_fetch pos if pos
      end
      unsafe_fetch index
    end

    # Extract all elements with values assigned.


@@ 119,16 116,31 @@ module Sparse
      { @idx, @val }
    end

    @[AlwaysInline]
    private def unsafe_fetch(index : Int) : T?
      pos = @idx.bsearch_index &.==(index)
    # Perform a binary search across the tracked element indicies to locate the
    # internal offset of *index* in the vector.
    private def unsafe_pos(index)
      l = 0
      r = @idx.size
      while l < r
        pos = l + ((r - l) >> 1)
        case @idx.unsafe_fetch pos
        when index
          return pos
        when .< index
          l = pos + 1
        when
          r = pos
        end
      end
    end

    private def unsafe_fetch(index) : T?
      pos = unsafe_pos index
      @val.unsafe_fetch pos if pos
    end

    private def check_index_out_of_bounds(index)
      check_index_out_of_bounds index do
        raise IndexError.new "Invalid index (#{index})"
      end
      check_index_out_of_bounds index { raise IndexError.new }
    end

    private def check_index_out_of_bounds(index, &)