# -------------------------------------------------------------
# In this test we create a lock wait-queue for a key. We then
# have the head of the queue discover an existing lock on the
# key. The lock is part of the same transaction as one of the
# queued writes. The writer should stop waiting on the lock.
#
# NOTE: this test is somewhat synthetic and it's not clear that
# there's currently a way to trigger this behavior if all lock
# acquisitions are observed sequentially when starting from an
# empty lock-table, given the current policy on how wait-queues
# form in the lock-table. Still, this is worth handling correctly
# in case this ever changes.
#
# Setup: txn1 acquires lock
#        txn2 and txn3 enter wait-queue
#        txn1 releases lock, txn2 becomes reservation holder
#
# Test:  discover lock from txn3
#        txn3 should exit wait-queue
# -------------------------------------------------------------

new-lock-table maxlocks=10000
----

new-txn txn=txn1 ts=10 epoch=0
----

new-txn txn=txn2 ts=10 epoch=0
----

new-txn txn=txn3 ts=10 epoch=0
----

new-request r=req1 txn=txn1 ts=10,1 spans=exclusive@a
----

scan r=req1
----
start-waiting: false

acquire r=req1 k=a durability=u strength=exclusive
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

dequeue r=req1
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

new-request r=req2 txn=txn2 ts=10,1 spans=intent@a
----

new-request r=req3 txn=txn3 ts=10,1 spans=intent@a
----

scan r=req2
----
start-waiting: true

scan r=req3
----
start-waiting: true

release txn=txn1 span=a
----
num=1
 lock: "a"
   queued locking requests:
    active: false req: 2, strength: Intent, txn: 00000000-0000-0000-0000-000000000002
    active: true req: 3, strength: Intent, txn: 00000000-0000-0000-0000-000000000003

# When uncontented=false one or more active waiters marks the lock as contented.
query span=a,c
----
num locks: 1, bytes returned: 79, resume reason: RESUME_UNKNOWN, resume span: <nil>
 locks:
  range_id=3 key="a" holder=<nil> durability=Unreplicated duration=0s
   waiters:
    waiting_txn:00000000-0000-0000-0000-000000000002 active_waiter:false strength:Exclusive wait_duration:0s
    waiting_txn:00000000-0000-0000-0000-000000000003 active_waiter:true strength:Exclusive wait_duration:0s

guard-state r=req2
----
new: state=doneWaiting

guard-state r=req3
----
new: state=waitFor txn=txn2 key="a" held=false guard-strength=Intent

# --------------------------------
# Setup complete, test starts here
# --------------------------------

add-discovered r=req2 k=a txn=txn3
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000003 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: repl [Intent]
   queued locking requests:
    active: false req: 2, strength: Intent, txn: 00000000-0000-0000-0000-000000000002

scan r=req2
----
start-waiting: true

guard-state r=req2
----
new: state=waitFor txn=txn3 key="a" held=true guard-strength=Intent

guard-state r=req3
----
new: state=doneWaiting

dequeue r=req3
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000003 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: repl [Intent]
   queued locking requests:
    active: true req: 2, strength: Intent, txn: 00000000-0000-0000-0000-000000000002

release txn=txn3 span=a
----
num=1
 lock: "a"
   queued locking requests:
    active: false req: 2, strength: Intent, txn: 00000000-0000-0000-0000-000000000002

# When uncontented=false no reader and no active waiter marks the lock as uncontented.
query span=a,c
----
num locks: 0, bytes returned: 0, resume reason: RESUME_UNKNOWN, resume span: <nil>

guard-state r=req2
----
new: state=doneWaiting

dequeue r=req2
----
num=0
