49
50
51
52
53
54
55
56
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/fdbdirectory.rb', line 49
def allocate(db_or_tr)
db_or_tr.transact do |tr|
if !tr.instance_variable_defined?(:@__fdb_directory_layer_hca_state__)
@lock.synchronize do
if !tr.instance_variable_defined?(:@__fdb_directory_layer_hca_state__)
tr.instance_variable_set(:@__fdb_directory_layer_hca_state__, AllocatorTransactionState.new)
end
end
end
tr_state = tr.instance_variable_get(:@__fdb_directory_layer_hca_state__)
loop do
start, count =
tr.snapshot.get_range(@counters.range[0],
@counters.range[1],
{:limit => 1, :reverse => true})
.map { |kv|
[ @counters.unpack(kv.key)[0], kv.value.unpack('q<')[0] ]
}.first || [0,0]
window = 0
window_advanced = false
loop do
tr_state.lock.synchronize do
if window_advanced
tr.clear_range(@counters, @counters[start])
tr.options.set_next_write_no_write_conflict_range()
tr.clear_range(@recent, @recent[start])
end
tr.add(@counters[start], [1].pack('q<'))
count = tr.snapshot[@counters[start]]
end
count = count.nil? ? 0 : count.unpack('q<')[0]
window = window_size(start)
if count * 2 < window
break
end
start += window
window_advanced = true
end
candidate = 0
found = false
loop do
candidate = rand(start...start+window)
latest_counter = nil
candidate_value = nil
tr_state.lock.synchronize do
latest_counter = tr.snapshot.get_range(@counters.range[0],
@counters.range[1],
{:limit => 1, :reverse => true})
candidate_value = tr[@recent[candidate]]
tr.options.set_next_write_no_write_conflict_range()
tr[@recent[candidate]] = ''
end
latest_counter = latest_counter.map{ |kv| [ @counters.unpack(kv.key)[0] ] }.first || [0]
if latest_counter.length > 0 and latest_counter[0] > start
break
end
if candidate_value.nil?
found = true
tr.add_write_conflict_key(@recent[candidate])
break
end
end
if found
break FDB::Tuple.pack([candidate])
end
end
end
end
|