File: _HashNode%2BInvariants.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (107 lines) | stat: -rw-r--r-- 3,413 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2022 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

extension _HashNodeHeader {
#if COLLECTIONS_INTERNAL_CHECKS
  @usableFromInline @inline(never)
  internal func _invariantCheck() {
    precondition(bytesFree <= byteCapacity)
    if isCollisionNode {
      precondition(itemMap == childMap)
      precondition(!itemMap.isEmpty)
    } else {
      precondition(itemMap.intersection(childMap).isEmpty)
    }
  }
#else
  @inlinable @inline(__always)
  internal func _invariantCheck() {}
#endif
}

extension _HashNode {
#if COLLECTIONS_INTERNAL_CHECKS
  @usableFromInline @inline(never)
  internal func _invariantCheck() {
    raw.storage.header._invariantCheck()
    read {
      let itemBytes = $0.itemCount * MemoryLayout<Element>.stride

      if $0.isCollisionNode {
        let hashBytes = MemoryLayout<_Hash>.stride
        assert($0.itemCount >= 1)
        assert($0.childCount == 0)
        assert(itemBytes + $0.bytesFree + hashBytes == $0.byteCapacity)

        assert($0.collisionHash == _Hash($0[item: .zero].key))
      } else {
        let childBytes = $0.childCount * MemoryLayout<_HashNode>.stride
        assert(itemBytes + $0.bytesFree + childBytes == $0.byteCapacity)
      }

      let actualCount = $0.children.reduce($0.itemCount, { $0 + $1.count })
      assert(actualCount == self.count)
    }
  }
#else
  @inlinable @inline(__always)
  internal func _invariantCheck() {}
#endif

  @inlinable @inline(__always)
  public func _fullInvariantCheck() {
    self._fullInvariantCheck(.top, .emptyPath)
  }

#if COLLECTIONS_INTERNAL_CHECKS
  @inlinable @inline(never)
  internal func _fullInvariantCheck(_ level: _HashLevel, _ path: _Hash) {
    _invariantCheck()
    read {
      precondition(level.isAtRoot || !hasSingletonItem)
      precondition(!isAtrophied)
      if $0.isCollisionNode {
        precondition(count == $0.itemCount)
        precondition(count > 0)
        let hash = $0.collisionHash
        precondition(
          hash.isEqual(to: path, upTo: level),
          "Misplaced collision node: \(path) isn't a prefix of \(hash)")
        for item in $0.reverseItems {
          precondition(_Hash(item.key) == hash)
        }
      }
      var itemSlot: _HashSlot = .zero
      var childSlot: _HashSlot = .zero
      for b in 0 ..< UInt(_Bitmap.capacity) {
        let bucket = _Bucket(b)
        let path = path.appending(bucket, at: level)
        if $0.itemMap.contains(bucket) {
          let key = $0[item: itemSlot].key
          let hash = _Hash(key)
          precondition(
            hash.isEqual(to: path, upTo: level.descend()),
            "Misplaced key '\(key)': \(path) isn't a prefix of \(hash)")
          itemSlot = itemSlot.next()
        }
        if $0.hasChildren && $0.childMap.contains(bucket) {
          $0[child: childSlot]._fullInvariantCheck(level.descend(), path)
          childSlot = childSlot.next()
        }
      }
    }
  }
#else
  @inlinable @inline(__always)
  internal func _fullInvariantCheck(_ level: _HashLevel, _ path: _Hash) {}
#endif
}