@@ -33,25 +33,30 @@ var write = true
33
33
var zeroTS = hlc.Timestamp {}
34
34
35
35
func spans (from , to string , write bool ) * spanset.SpanSet {
36
- var span roachpb.Span
36
+ var spans spanset.SpanSet
37
+ add (& spans , from , to , write )
38
+ return & spans
39
+ }
40
+
41
+ func add (spans * spanset.SpanSet , from , to string , write bool ) {
42
+ var start , end roachpb.Key
37
43
if to == "" {
38
- span = roachpb.Span { Key : roachpb . Key (from )}
44
+ start = roachpb .Key (from )
39
45
} else {
40
- span = roachpb.Span {Key : roachpb .Key (from ), EndKey : roachpb .Key (to )}
46
+ start = roachpb .Key (from )
47
+ end = roachpb .Key (to )
41
48
}
42
49
if strings .HasPrefix (from , "local" ) {
43
- span . Key = append (keys .LocalRangePrefix , span . Key ... )
44
- if span . EndKey != nil {
45
- span . EndKey = append (keys .LocalRangePrefix , span . EndKey ... )
50
+ start = append (keys .LocalRangePrefix , start ... )
51
+ if end != nil {
52
+ end = append (keys .LocalRangePrefix , end ... )
46
53
}
47
54
}
48
- var spans spanset.SpanSet
49
55
access := spanset .SpanReadOnly
50
56
if write {
51
57
access = spanset .SpanReadWrite
52
58
}
53
- spans .Add (access , span )
54
- return & spans
59
+ spans .Add (access , roachpb.Span {Key : start , EndKey : end })
55
60
}
56
61
57
62
func testLatchSucceeds (t * testing.T , lgC <- chan * Guard ) * Guard {
@@ -118,7 +123,7 @@ func TestLatchManager(t *testing.T) {
118
123
defer leaktest .AfterTest (t )()
119
124
var m Manager
120
125
121
- // Try latches with no overlapping already-acquired lathes .
126
+ // Try latches with no overlapping already-acquired latches .
122
127
lg1 := m .MustAcquire (spans ("a" , "" , write ), zeroTS )
123
128
m .Release (lg1 )
124
129
@@ -137,6 +142,50 @@ func TestLatchManager(t *testing.T) {
137
142
testLatchSucceeds (t , lg4C )
138
143
}
139
144
145
+ func TestLatchManagerAcquireOverlappingSpans (t * testing.T ) {
146
+ defer leaktest .AfterTest (t )()
147
+ var m Manager
148
+
149
+ // Acquire overlapping latches with different access patterns.
150
+ // |----------| <- Read latch [a-c)@t1
151
+ // |----------| <- Write latch [b-d)@t1
152
+ //
153
+ // ^ ^ ^ ^
154
+ // | | | |
155
+ // a b c d
156
+ //
157
+ var ts0 , ts1 = hlc.Timestamp {WallTime : 0 }, hlc.Timestamp {WallTime : 1 }
158
+ var spanSet spanset.SpanSet
159
+ add (& spanSet , "a" , "c" , read )
160
+ add (& spanSet , "b" , "d" , write )
161
+ lg1 := m .MustAcquire (& spanSet , ts1 )
162
+
163
+ lg2C := m .MustAcquireCh (spans ("a" , "b" , read ), ts0 )
164
+ lg2 := testLatchSucceeds (t , lg2C )
165
+ m .Release (lg2 )
166
+
167
+ // We acquire reads at lower timestamps than writes to check for blocked
168
+ // acquisitions based on the original latch, not the latches declared in
169
+ // earlier test cases.
170
+ var latchCs []<- chan * Guard
171
+ latchCs = append (latchCs , m .MustAcquireCh (spans ("a" , "b" , write ), ts1 ))
172
+ latchCs = append (latchCs , m .MustAcquireCh (spans ("b" , "c" , read ), ts0 ))
173
+ latchCs = append (latchCs , m .MustAcquireCh (spans ("b" , "c" , write ), ts1 ))
174
+ latchCs = append (latchCs , m .MustAcquireCh (spans ("c" , "d" , write ), ts1 ))
175
+ latchCs = append (latchCs , m .MustAcquireCh (spans ("c" , "d" , read ), ts0 ))
176
+
177
+ for _ , lgC := range latchCs {
178
+ testLatchBlocks (t , lgC )
179
+ }
180
+
181
+ m .Release (lg1 )
182
+
183
+ for _ , lgC := range latchCs {
184
+ lg := testLatchSucceeds (t , lgC )
185
+ m .Release (lg )
186
+ }
187
+ }
188
+
140
189
func TestLatchManagerNoWaitOnReadOnly (t * testing.T ) {
141
190
defer leaktest .AfterTest (t )()
142
191
var m Manager
@@ -207,11 +256,11 @@ func TestLatchManagerMultipleOverlappingSpans(t *testing.T) {
207
256
lg4 := m .MustAcquire (spans ("g" , "" , write ), zeroTS )
208
257
209
258
// Attempt to acquire latches overlapping each of them.
210
- var spans spanset.SpanSet
211
- spans . Add ( spanset . SpanReadWrite , roachpb. Span { Key : roachpb . Key ( "a" )} )
212
- spans . Add ( spanset . SpanReadWrite , roachpb. Span { Key : roachpb . Key ( "b" )} )
213
- spans . Add ( spanset . SpanReadWrite , roachpb. Span { Key : roachpb . Key ( "e" )} )
214
- lg5C := m .MustAcquireCh (& spans , zeroTS )
259
+ var spanSet spanset.SpanSet
260
+ add ( & spanSet , "a" , "" , write )
261
+ add ( & spanSet , "b" , "" , write )
262
+ add ( & spanSet , "e" , "" , write )
263
+ lg5C := m .MustAcquireCh (& spanSet , zeroTS )
215
264
216
265
// Blocks until the first three prerequisite latches release.
217
266
testLatchBlocks (t , lg5C )
0 commit comments