File: _HashNode%2BPrimitive%20Replacement.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 (90 lines) | stat: -rw-r--r-- 2,790 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
//===----------------------------------------------------------------------===//
//
// 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 _HashNode {
  @inlinable
  internal mutating func replaceItem(
    at bucket: _Bucket, _ slot: _HashSlot, with item: __owned Element
  ) {
    update {
      assert($0.isCollisionNode || $0.itemMap.contains(bucket))
      assert($0.isCollisionNode || slot == $0.itemMap.slot(of: bucket))
      assert(!$0.isCollisionNode || slot.value < $0.collisionCount)
      $0[item: slot] = item
    }
  }

  @inlinable
  internal mutating func replaceChild(
    at bucket: _Bucket, with child: __owned _HashNode
  ) -> Int {
    let slot = read { $0.childMap.slot(of: bucket) }
    return replaceChild(at: bucket, slot, with: child)
  }

  @inlinable
  internal mutating func replaceChild(
    at bucket: _Bucket, _ slot: _HashSlot, with child: __owned _HashNode
  ) -> Int {
    let delta: Int = update {
      assert(!$0.isCollisionNode)
      assert($0.childMap.contains(bucket))
      assert($0.childMap.slot(of: bucket) == slot)
      let p = $0.childPtr(at: slot)
      let delta = child.count &- p.pointee.count
      p.pointee = child
      return delta
    }
    self.count &+= delta
    return delta
  }

  @inlinable
  internal func replacingChild(
    _ level: _HashLevel,
    at bucket: _Bucket,
    _ slot: _HashSlot,
    with child: __owned Builder
  ) -> Builder {
    assert(child.level == level.descend())
    read {
      assert(!$0.isCollisionNode)
      assert($0.childMap.contains(bucket))
      assert(slot == $0.childMap.slot(of: bucket))
    }
    switch child.kind {
    case .empty:
      return _removingChild(level, at: bucket, slot)
    case let .item(item, _):
      if hasSingletonChild {
        return .item(level, item, at: bucket)
      }
      var node = self.copy(withFreeSpace: _HashNode.spaceForInlinedChild)
      _ = node.removeChild(at: bucket, slot)
      node.insertItem(item, at: bucket)
      node._invariantCheck()
      return .node(level, node)
    case let .node(node):
      var copy = self.copy()
      _ = copy.replaceChild(at: bucket, slot, with: node)
      return .node(level, copy)
    case let .collisionNode(node):
      if hasSingletonChild {
        // Compression
        assert(!level.isAtBottom)
        return .collisionNode(level, node)
      }
      var copy = self.copy()
      _ = copy.replaceChild(at: bucket, slot, with: node)
      return .node(level, copy)
    }
  }
}