Skip to content

Commit 38611e9

Browse files
authored
Merge pull request #319 from tayloraswift/abi-hashes
compute and track the ABI hash for each snapshot
2 parents eb7b307 + 8ce15b7 commit 38611e9

21 files changed

+531
-338
lines changed

Sources/SymbolGraphs/Planes/SymbolGraph.Layer.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,17 @@ extension SymbolGraph.Layer
6464
extension SymbolGraph.Layer
6565
{
6666
@inlinable public
67-
func link<T>(
68-
static transform:(Int32) throws -> T,
67+
func link<T>(_ transform:(Node.ID, Int32) throws -> T,
6968
dynamic link:(Node.ID) throws -> T) rethrows -> SymbolGraph.Table<Node.Plane, T>
7069
{
7170
var elements:[T] = [] ; elements.reserveCapacity(self.symbols.count)
7271

7372
for index:Int32 in self.symbols.indices
7473
{
75-
elements.append(self.contains(citizen: index) ? try transform(index) :
76-
try link(self.symbols[index]))
74+
let id:Node.ID = self.symbols[index]
75+
elements.append(self.contains(citizen: index)
76+
? try transform(id, index)
77+
: try link(id))
7778
}
7879

7980
return .init(viewing: elements)

Sources/SymbolGraphs/SymbolGraph.swift

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,16 @@ extension SymbolGraph
7171
extension SymbolGraph
7272
{
7373
@inlinable public
74-
func link<T>(
75-
static transform:(Int32) throws -> T,
74+
func link<T>(_ transform:(Symbol.Module, Int32) throws -> T,
7675
dynamic link:(Symbol.Module) throws -> T) rethrows -> [T]
7776
{
7877
var elements:[T] = [] ; elements.reserveCapacity(self.namespaces.count)
7978

80-
for index:Int in self.cultures.indices
79+
for (index, id):(Int, Symbol.Module) in zip(self.namespaces.indices, self.namespaces)
8180
{
82-
elements.append(try transform(index * .module))
83-
}
84-
for colony:Symbol.Module in self.namespaces[self.cultures.endIndex...]
85-
{
86-
elements.append(try link(colony))
81+
elements.append(self.cultures.indices.contains(index)
82+
? try transform(id, index * .module)
83+
: try link(id))
8784
}
8885

8986
return elements

Sources/Symbols/Identifiers/Symbol.Module.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
extension Symbol
22
{
33
@frozen public
4-
struct Module:LosslessStringConvertible, Equatable, Hashable, Sendable
4+
struct Module:Equatable, Hashable, Sendable
55
{
66
public
7-
let description:String
7+
let mangled:String
88

99
@inlinable public
10-
init(_ description:String)
10+
init(_ mangled:String)
1111
{
12-
self.description = description
12+
self.mangled = mangled
1313
}
1414
}
1515
}
16+
extension Symbol.Module:CustomStringConvertible
17+
{
18+
@inlinable public
19+
var description:String { self.mangled }
20+
}
21+
extension Symbol.Module:LosslessStringConvertible
22+
{
23+
}
1624
extension Symbol.Module:ExpressibleByStringLiteral
1725
{
1826
@inlinable public
@@ -24,10 +32,7 @@ extension Symbol.Module:ExpressibleByStringLiteral
2432
extension Symbol.Module:Comparable
2533
{
2634
@inlinable public static
27-
func < (lhs:Self, rhs:Self) -> Bool
28-
{
29-
lhs.description < rhs.description
30-
}
35+
func < (a:Self, b:Self) -> Bool { a.mangled < b.mangled }
3136
}
3237
extension Symbol.Module
3338
{

Sources/UnidocDB/Editions/Unidoc.DB.EditionDependencies.swift

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import MD5
12
import MongoDB
23
import UnidocRecords
34

@@ -9,7 +10,7 @@ extension Unidoc.DB
910
public
1011
let database:Mongo.Database
1112

12-
@inlinable internal
13+
@inlinable
1314
init(database:Mongo.Database)
1415
{
1516
self.database = database
@@ -18,15 +19,26 @@ extension Unidoc.DB
1819
}
1920
extension Unidoc.DB.EditionDependencies
2021
{
21-
public static
22-
let indexSource:Mongo.CollectionIndex = .init("Source",
22+
public
23+
static let indexSourceChangedABI:Mongo.CollectionIndex = .init("SourceChangedABI",
24+
collation: SimpleCollation.spec)
25+
{
26+
$0[Unidoc.EditionDependency[.id] / Unidoc.Edge<Unidoc.Edition>[.source]] = (+)
27+
}
28+
where:
29+
{
30+
$0[Unidoc.EditionDependency[.targetChanged]] = true
31+
}
32+
33+
public
34+
static let indexSource:Mongo.CollectionIndex = .init("Source",
2335
collation: SimpleCollation.spec)
2436
{
2537
$0[Unidoc.EditionDependency[.id] / Unidoc.Edge<Unidoc.Edition>[.source]] = (+)
2638
}
2739

28-
public static
29-
let indexTarget:Mongo.CollectionIndex = .init("Target",
40+
public
41+
static let indexTarget:Mongo.CollectionIndex = .init("Target",
3042
collation: SimpleCollation.spec)
3143
{
3244
$0[Unidoc.EditionDependency[.id] / Unidoc.Edge<Unidoc.Edition>[.target]] = (+)
@@ -37,29 +49,30 @@ extension Unidoc.DB.EditionDependencies:Mongo.CollectionModel
3749
public
3850
typealias Element = Unidoc.EditionDependency
3951

40-
@inlinable public static
41-
var name:Mongo.Collection { "EditionDependencies" }
52+
@inlinable public
53+
static var name:Mongo.Collection { "EditionDependencies" }
4254

43-
@inlinable public static
44-
var indexes:[Mongo.CollectionIndex]
55+
@inlinable public
56+
static var indexes:[Mongo.CollectionIndex]
4557
{
4658
[
59+
Self.indexSourceChangedABI,
4760
Self.indexSource,
4861
Self.indexTarget
4962
]
5063
}
5164
}
5265
extension Unidoc.DB.EditionDependencies
5366
{
54-
func insert(dependencies:[Unidoc.VolumeMetadata.Dependency],
55-
dependent source:Unidoc.Edition,
67+
func create(dependent:Unidoc.Edition,
68+
from boundaries:[Unidoc.Mesh.Boundary],
5669
with session:Mongo.Session) async throws
5770
{
58-
let dependencies:[Unidoc.EditionDependency] = dependencies.reduce(into: [])
71+
let dependencies:[Unidoc.EditionDependency] = boundaries.reduce(into: [])
5972
{
60-
if let edition:Unidoc.Edition = $1.pin?.edition
73+
if let edition:Unidoc.Edition = $1.target.pin?.edition
6174
{
62-
$0.append(.init(source: source, target: edition))
75+
$0.append(.init(source: dependent, target: edition, targetABI: $1.targetABI))
6376
}
6477
}
6578

@@ -75,7 +88,7 @@ extension Unidoc.DB.EditionDependencies
7588
let _:Mongo.Insertions = try response.insertions()
7689
}
7790

78-
func clear(dependent source:Unidoc.Edition, with session:Mongo.Session) async throws
91+
func clear(dependent:Unidoc.Edition, with session:Mongo.Session) async throws
7992
{
8093
let response:Mongo.DeleteResponse = try await session.run(
8194
command: Mongo.Delete<Mongo.Many>.init(Self.name)
@@ -86,12 +99,41 @@ extension Unidoc.DB.EditionDependencies
8699
$0[.hint] = Self.indexSource.id
87100
$0[.q]
88101
{
89-
$0[Element[.id] / Unidoc.Edge<Unidoc.Edition>[.source]] = source
102+
$0[Element[.id] / Unidoc.Edge<Unidoc.Edition>[.source]] = dependent
90103
}
91104
}
92105
},
93106
against: self.database)
94107

95108
let _:Mongo.Deletions = try response.deletions()
96109
}
110+
111+
/// Selects all edges whose target matches `dependency` and marks them as dirty if their
112+
/// ``Unidoc.EditionDependency/targetABI`` does not match `dependencyABI`.
113+
@discardableResult
114+
func update(dependencyABI:MD5,
115+
dependency:Unidoc.Edition,
116+
with session:Mongo.Session) async throws -> Int
117+
{
118+
try await self.updateMany(with: session)
119+
{
120+
$0
121+
{
122+
$0[.multi] = true
123+
$0[.q]
124+
{
125+
$0[Element[.id] / Unidoc.Edge<Unidoc.Edition>[.target]] = dependency
126+
$0[Element[.targetABI]] { $0[.ne] = dependencyABI }
127+
}
128+
$0[.u]
129+
{
130+
$0[.set]
131+
{
132+
$0[Element[.targetABI]] = dependencyABI
133+
$0[Element[.targetChanged]] = true
134+
}
135+
}
136+
}
137+
}
138+
}
97139
}

Sources/UnidocDB/Mongo.CollectionModel.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,21 @@ extension Mongo.CollectionModel
577577
let updates:Mongo.Updates<Element.ID> = try response.updates()
578578
return updates.selected == 0 ? nil : updates.modified == 1
579579
}
580+
581+
@inlinable package
582+
func updateMany(with session:Mongo.Session,
583+
do encode:(inout Mongo.UpdateListEncoder<Mongo.Many>) throws -> ()) async throws -> Int
584+
{
585+
let response:Mongo.UpdateResponse<Element.ID> = try await session.run(
586+
command: Mongo.Update<Mongo.Many, Element.ID>.init(Self.name)
587+
{
588+
try encode(&$0)
589+
},
590+
against: self.database)
591+
592+
let updates:Mongo.Updates<Element.ID> = try response.updates()
593+
return updates.modified
594+
}
580595
}
581596

582597
extension Mongo.CollectionModel where Element:Mongo.MasterCodingModel
@@ -651,7 +666,7 @@ extension Mongo.CollectionModel
651666
try await self.delete(with: session) { $0["_id"] = id }
652667
}
653668

654-
@inlinable internal
669+
@inlinable
655670
func delete(with session:Mongo.Session,
656671
matching predicate:(inout Mongo.PredicateEncoder) -> ()) async throws -> Bool
657672
{

Sources/UnidocDB/Packages/Unidoc.DB.PackageDependencies.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ extension Unidoc.DB.PackageDependencies:Mongo.RecodableModel
6363
}
6464
extension Unidoc.DB.PackageDependencies
6565
{
66-
func update(dependencies:[Unidoc.VolumeMetadata.Dependency],
67-
dependent source:Unidoc.Edition,
66+
func update(dependent source:Unidoc.Edition,
67+
from boundaries:[Unidoc.Mesh.Boundary],
6868
with session:Mongo.Session) async throws
6969
{
70-
let dependencies:[Unidoc.PackageDependency] = dependencies.reduce(into: [])
70+
let dependencies:[Unidoc.PackageDependency] = boundaries.reduce(into: [])
7171
{
72-
if let package:Unidoc.Package = $1.pin?.edition.package
72+
if let package:Unidoc.Package = $1.target.pin?.edition.package
7373
{
7474
$0.append(.init(source: source, target: package))
7575
}

0 commit comments

Comments
 (0)