Class: GeoTreeModule::PtBuffer

Inherits:
Object
  • Object
show all
Includes:
ExternalSortModule
Defined in:
lib/geotree/ptbuffer.rb

Overview

Support for buffering new points to a file, then shuffling the points before adding them to (one or more) geotrees.

Constant Summary collapse

PT_SHUFFLER_ =
Proc.new do |x,y|
  rand(2) == 0 ? -1 : 1
end

Constants included from ExternalSortModule

ExternalSortModule::MAX_CHUNK_SIZE_

Instance Method Summary collapse

Constructor Details

#initialize(tree) ⇒ PtBuffer

Construct an inactive buffer

Parameters:

  • tree

    tree to receive the points; calls its add_buffered_point() method when the buffer is being closed



52
53
54
55
56
57
# File 'lib/geotree/ptbuffer.rb', line 52

def initialize(tree)
  @tree = tree
  @buffering = false
  @buff_file = nil
  @buffered_count = 0
end

Instance Method Details

#activeObject

Return true if buffer is active



60
61
62
# File 'lib/geotree/ptbuffer.rb', line 60

def active
  @buffering
end

#active=(val) ⇒ Object

Change buffer’s active state



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/geotree/ptbuffer.rb', line 65

def active=(val)
  db = false

  if @buffering != val

    @buffering = val

    # If we were buffering the points, then close the file,
    # shuffle the points, and send them to the receiving tree(s).
    if @buff_file
      @buff_file.close

      # Sort the buffered points into a random order
      so = Sorter.new(@buff_file.path,DATAPOINT_BYTES, PT_SHUFFLER_)
      so.sort

      !db || pr(" opening chunk reader for #@buffered_count points\n")

      @buff_file.open
      @buff_file.binmode

      r = ChunkReader.new(@buff_file, 0, DATAPOINT_BYTES * @buffered_count, DATAPOINT_BYTES)
      while !r.done
        by,off = r.peek
        dp = GeoTree.read_data_point_from(by,off / INT_BYTES)
        r.read
        !db||  pr("adding data point: #{dp}\n")
        @tree.add_buffered_point(dp)
      end
      @buff_file.close
    end
    @buff_file = nil
    @buffered_count = 0
  end

end

#add(data_point) ⇒ Object

Add point to buffer



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/geotree/ptbuffer.rb', line 103

def add(data_point)
  if !active
    @tree.add_buffered_point(data_point)
  else
    if @buffered_count == 0
      @buff_file = Tempfile.new('_geotree_')
      @buff_file.binmode
    end

    by = zero_bytes(DATAPOINT_BYTES)
    GeoTree.write_data_point(data_point, by, 0)
    nw = @buff_file.write(by)
    raise IOError if nw != by.size
    @buffered_count += 1
  end
end