/// <summary>Checks if a list of reads conflicts with at least one write performed in this transaction window</summary> /// <param name="reads">List of reads to check for conflicts</param> /// <param name="version">Sequence number of the transaction that performed the reads</param> /// <returns>True if at least one read is conflicting with a write with a higher sequence number; otherwise, false.</returns> public bool Conflicts(ColaRangeSet <Slice> reads, ulong version) { Contract.Requires(reads != null); //Debug.WriteLine("* Testing for conflicts for: " + String.Join(", ", reads)); if (version > m_maxVersion) { // all the writes are before the reads, so no possible conflict! //Debug.WriteLine(" > cannot conflict"); return(false); } using (var scratch = new UnmanagedSliceBuilder()) { //TODO: do a single-pass version of intersection checking ! foreach (var read in reads) { scratch.Clear(); scratch.Append(read.Begin); var p = scratch.Count; scratch.Append(read.End); var begin = scratch.ToUSlice(p); var end = scratch.ToUSlice(p, scratch.Count - p); if (m_writeConflicts.Intersect(begin, end, version, (v, min) => v > min)) { Debug.WriteLine(" > Conflicting read: " + read); return(true); } } } //Debug.WriteLine(" > No conflicts found"); return(false); }
public void MergeWrites(ColaRangeSet <Slice> writes, ulong version) { Contract.Requires(!m_closed && writes != null && version >= m_minVersion && (!m_closed || version <= m_maxVersion)); if (m_disposed) { ThrowDisposed(); } if (m_closed) { throw new InvalidOperationException("This transaction has already been closed"); } //Debug.WriteLine("* Merging writes conflicts for version " + version + ": " + String.Join(", ", writes)); foreach (var range in writes) { var begin = range.Begin; var end = range.End; USlice beginKey, endKey; if (begin.Offset == end.Offset && object.ReferenceEquals(begin.Array, end.Array) && end.Count >= begin.Count) { // overlapping keys endKey = Store(end); beginKey = endKey.Substring(0, (uint)begin.Count); } else { beginKey = Store(begin); endKey = Store(end); } m_writeConflicts.Mark(beginKey, endKey, version); } ++m_commitCount; if (version > m_maxVersion) { m_maxVersion = version; } }