@@ -33,25 +33,30 @@ var write = true
3333var zeroTS = hlc.Timestamp {}
3434
3535func 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
3743 if to == "" {
38- span = roachpb.Span { Key : roachpb . Key (from )}
44+ start = roachpb .Key (from )
3945 } else {
40- span = roachpb.Span {Key : roachpb .Key (from ), EndKey : roachpb .Key (to )}
46+ start = roachpb .Key (from )
47+ end = roachpb .Key (to )
4148 }
4249 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 ... )
4653 }
4754 }
48- var spans spanset.SpanSet
4955 access := spanset .SpanReadOnly
5056 if write {
5157 access = spanset .SpanReadWrite
5258 }
53- spans .Add (access , span )
54- return & spans
59+ spans .Add (access , roachpb.Span {Key : start , EndKey : end })
5560}
5661
5762func testLatchSucceeds (t * testing.T , lgC <- chan * Guard ) * Guard {
@@ -118,7 +123,7 @@ func TestLatchManager(t *testing.T) {
118123 defer leaktest .AfterTest (t )()
119124 var m Manager
120125
121- // Try latches with no overlapping already-acquired lathes .
126+ // Try latches with no overlapping already-acquired latches .
122127 lg1 := m .MustAcquire (spans ("a" , "" , write ), zeroTS )
123128 m .Release (lg1 )
124129
@@ -137,6 +142,50 @@ func TestLatchManager(t *testing.T) {
137142 testLatchSucceeds (t , lg4C )
138143}
139144
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+
140189func TestLatchManagerNoWaitOnReadOnly (t * testing.T ) {
141190 defer leaktest .AfterTest (t )()
142191 var m Manager
@@ -207,11 +256,11 @@ func TestLatchManagerMultipleOverlappingSpans(t *testing.T) {
207256 lg4 := m .MustAcquire (spans ("g" , "" , write ), zeroTS )
208257
209258 // 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 )
215264
216265 // Blocks until the first three prerequisite latches release.
217266 testLatchBlocks (t , lg5C )
0 commit comments