Class: Array::Compositing::ParentIndexMap

Inherits:
Object
  • Object
show all
Defined in:
lib/array/compositing/parent_index_map.rb

Instance Method Summary collapse

Constructor Details

#initializeParentIndexMap

initialize #



8
9
10
11
12
13
14
15
16
17
# File 'lib/array/compositing/parent_index_map.rb', line 8

def initialize
  
  @parent_local_map = [ ]
  @local_parent_map = [ ]
  
  @parent_lazy_lookup = [ ]
  
  @parent_and_interpolated_object_count = 0
  
end

Instance Method Details

#index_for_offset(index_offset) ⇒ Object

index_for_offset #



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/array/compositing/parent_index_map.rb', line 23

def index_for_offset( index_offset )
  
  index = nil
  
  if index_offset >= 0
    index = index_offset
  else
    index = @local_parent_map.count + index_offset
  end    

  if index < 0
    index = 0
  end
  
  return index
  
end

#indexes_requiring_lookupObject

indexes_requiring_lookup #



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/array/compositing/parent_index_map.rb', line 118

def indexes_requiring_lookup
  
  indexes = [ ]
  
  @parent_lazy_lookup.each_with_index do |true_or_false, this_index|
    if true_or_false
      indexes.push( this_index )
    end
  end
  
  return indexes
  
end

#inside_parent_elements?(local_index) ⇒ Boolean

inside_parent_elements? #

Returns:

  • (Boolean)


45
46
47
48
49
50
51
# File 'lib/array/compositing/parent_index_map.rb', line 45

def inside_parent_elements?( local_index )
  
  local_index = index_for_offset( local_index )
  
  return local_index < @parent_and_interpolated_object_count
  
end

#local_delete_at(local_index) ⇒ Object

local_delete_at #



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/array/compositing/parent_index_map.rb', line 356

def local_delete_at( local_index )

  local_index = index_for_offset( local_index )

  parent_index = @local_parent_map.delete_at( local_index )
  @parent_lazy_lookup.delete_at( local_index )

  if inside_parent_elements?( local_index )

    # if we don't have a parent index corresponding to this index, find the next one that corresponds
    unless parent_index
      next_local_index = local_index
      begin
        parent_index = @local_parent_map[ next_local_index ]
        next_local_index += 1
      end while parent_index.nil? and next_local_index < @local_parent_map.count
    end

    if parent_index
      remaining_count = @parent_local_map.count - parent_index
      remaining_count.times do |this_time|
        this_parent_index = parent_index + this_time
        @parent_local_map[ this_parent_index ] -= 1
      end
      if @parent_and_interpolated_object_count > 0
        @parent_and_interpolated_object_count -= 1
      end
    end
    
  end

end

#local_index(parent_index) ⇒ Object

local_index #



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/array/compositing/parent_index_map.rb', line 160

def local_index( parent_index )
  
  parent_index = index_for_offset( parent_index )
  
  if local_index = @parent_local_map[ parent_index ] and
     local_index < 0
    local_index = 0
  end
  
  return local_index
  
end

#local_insert(local_index, object_count) ⇒ Object

local_insert #



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/array/compositing/parent_index_map.rb', line 237

def local_insert( local_index, object_count )

  local_index = index_for_offset( local_index )

  # account for insert in parent-local    
  # if we're inside the set of parent elements then we need to tell the parent map to adjust
  if inside_parent_elements?( local_index )

    unless parent_insert_index = @local_parent_map[ local_index ]
      next_local_index = local_index
      begin
        parent_insert_index = @local_parent_map[ next_local_index ]
        next_local_index += 1
      end while parent_insert_index.nil? and next_local_index < @local_parent_map.count
    end
    
    if parent_insert_index
      remaining_count = @parent_local_map.count - parent_insert_index
      remaining_count.times do |this_time|
        this_parent_index = parent_insert_index + this_time
        @parent_local_map[ this_parent_index ] += object_count
      end
    end
    
  end
  
  # account for insert in local-parent
  object_count.times do |this_time|
    this_local_insert_index = local_index + this_time
    @local_parent_map.insert( this_local_insert_index, nil )
    @parent_lazy_lookup.insert( this_local_insert_index, false )
  end
  
end

#local_set(local_index) ⇒ Object

local_set #



299
300
301
302
303
304
305
306
307
308
309
# File 'lib/array/compositing/parent_index_map.rb', line 299

def local_set( local_index )

  local_index = index_for_offset( local_index )

  if parent_index = @local_parent_map[ local_index ]
    @local_parent_map[ local_index ] = nil
  end
  
  @parent_lazy_lookup[ local_index ] = false

end

#looked_up!(local_index) ⇒ Object

looked_up! #



136
137
138
139
140
141
142
# File 'lib/array/compositing/parent_index_map.rb', line 136

def looked_up!( local_index )
  
  local_index = index_for_offset( local_index )

  @parent_lazy_lookup[ local_index ] = false
  
end

#parent_delete_at(parent_delete_at_index) ⇒ Object

parent_delete_at #



315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/array/compositing/parent_index_map.rb', line 315

def parent_delete_at( parent_delete_at_index )

  parent_delete_at_index = index_for_offset( parent_delete_at_index )

  # get local index for parent index where delete is occuring
  local_delete_at_index = @parent_local_map.delete_at( parent_delete_at_index )
  
  # update any correspondences whose parent indexes are below the delete
  remaining_count = @parent_local_map.count - parent_delete_at_index
  remaining_count.times do |this_time|
    this_parent_index = parent_delete_at_index + this_time
    @parent_local_map[ this_parent_index ] -= 1
  end

  remaining_count = @local_parent_map.count - local_delete_at_index
  remaining_count.times do |this_time|
    this_local_index = local_delete_at_index + this_time
    if parent_index = @local_parent_map[ this_local_index ]
      @local_parent_map[ this_local_index ] = parent_index - 1
    end
  end

  if @parent_and_interpolated_object_count > 0
    @parent_and_interpolated_object_count -= 1
  end
  
  # if local => parent is already nil then we've overridden the corresponding index already
  # (we used to call this "replaced_parents")
  unless @local_parent_map[ local_delete_at_index ].nil?
    @local_parent_map.delete_at( local_delete_at_index )
    @parent_lazy_lookup.delete_at( local_delete_at_index )
  end

  return local_delete_at_index
  
end

#parent_index(local_index) ⇒ Object

parent_index #



148
149
150
151
152
153
154
# File 'lib/array/compositing/parent_index_map.rb', line 148

def parent_index( local_index )
  
  local_index = index_for_offset( local_index )
  
  return @local_parent_map[ local_index ]
  
end

#parent_insert(parent_insert_index, object_count) ⇒ Object

parent_insert #



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/array/compositing/parent_index_map.rb', line 177

def parent_insert( parent_insert_index, object_count )

  parent_insert_index = index_for_offset( parent_insert_index )

  local_insert_index = nil

  # It's possible we have no parent map yet (if the first insert is from an already-initialized parent
  # that did not previously have any members).
  case parent_insert_index
    when 0
      local_insert_index = @parent_local_map[ parent_insert_index ] || 0
    else
      unless local_insert_index = @parent_local_map[ parent_insert_index ]
        local_insert_index = @parent_and_interpolated_object_count
      end
  end
  
  if local_insert_index < 0
    local_insert_index = 0
  end
  
  # Insert new parent index correspondences.
  object_count.times do |this_time|
    this_parent_index = parent_insert_index + this_time
    this_local_index = local_insert_index + this_time
    @parent_local_map.insert( this_parent_index, this_local_index )
    @local_parent_map.insert( this_local_index, this_parent_index )
    @parent_lazy_lookup.insert( this_local_index, true )
  end
  
  # Update any correspondences whose parent indexes are above the insert.
  parent_index_at_end_of_insert = parent_insert_index + object_count
  remaining_count = @parent_local_map.count - parent_index_at_end_of_insert
  remaining_count.times do |this_time|
    this_parent_index = parent_index_at_end_of_insert + this_time
    @parent_local_map[ this_parent_index ] += object_count
  end

  local_index_at_end_of_insert = local_insert_index + object_count

  remaining_count = @local_parent_map.count - local_index_at_end_of_insert
  remaining_count.times do |this_time|
    this_local_index = local_index_at_end_of_insert + this_time
    if existing_parent_index = @local_parent_map[ this_local_index ]
      existing_parent_index += object_count
      @local_parent_map[ this_local_index ] += object_count
    end
  end
  
  # Update count of parent + interpolated objects since we inserted inside the collection.
  @parent_and_interpolated_object_count += object_count

  return local_insert_index
  
end

#parent_set(parent_index) ⇒ Object

parent_set #



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/array/compositing/parent_index_map.rb', line 276

def parent_set( parent_index )

  parent_index = index_for_offset( parent_index )
  
  # if we are setting an index that already exists then we have a parent to local map - we never delete those
  # except when we delete the parent
  if local_index = @parent_local_map[ parent_index ]
    unless replaced_parent_element_with_local_index?( local_index )
      @parent_lazy_lookup[ local_index ] = true
    end
  else
    local_index = @parent_and_interpolated_object_count
    parent_insert( local_index, 1 )
  end
  
  return local_index
  
end

#replaced_parent_element_with_local_index?(local_index) ⇒ Boolean

replaced_parent_element_with_local_index? #

Returns:

  • (Boolean)


94
95
96
97
98
99
100
# File 'lib/array/compositing/parent_index_map.rb', line 94

def replaced_parent_element_with_local_index?( local_index )
  
  local_index = index_for_offset( local_index )
  
  return parent_index( local_index ).nil?
  
end

#replaced_parent_element_with_parent_index?(parent_index) ⇒ Boolean

replaced_parent_element_with_parent_index? #

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/array/compositing/parent_index_map.rb', line 57

def replaced_parent_element_with_parent_index?( parent_index )
  
  replaced = false

  parent_index = index_for_offset( parent_index )

  # if parent index is greater than interpolated count we have a new parent, so not replaced
  if @parent_and_interpolated_object_count == 0
    
    if @local_parent_map.count > 0
      replaced = true
    end

  elsif parent_index < @parent_and_interpolated_object_count

    if local_index_for_parent = @parent_local_map[ parent_index ] and local_index_for_parent >= 0
      replaced = replaced_parent_element_with_local_index?( local_index_for_parent )
    else
      replaced = true
    end
  
  elsif parent_index == @parent_and_interpolated_object_count
    
    if local_index_for_parent = @parent_local_map[ parent_index ] and local_index_for_parent >= 0
      replaced = replaced_parent_element_with_local_index?( local_index_for_parent )
    end

  end

  return replaced
  
end

#requires_lookup?(local_index) ⇒ Boolean

requires_lookup? #

Returns:

  • (Boolean)


106
107
108
109
110
111
112
# File 'lib/array/compositing/parent_index_map.rb', line 106

def requires_lookup?( local_index )
  
  local_index = index_for_offset( local_index )
  
  return @parent_lazy_lookup[ local_index ]
  
end