Skip to content

Commit 0254959

Browse files
reduce db query
1 parent 082b3a8 commit 0254959

1 file changed

Lines changed: 62 additions & 30 deletions

File tree

lib/components/base-components/NormalComponent/NormalComponent_doInitialSilkscreenOverlapAdjustment.ts

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@ interface SilkscreenElementWithBounds {
1313
* Adjust silkscreen reference designators for passive components to avoid overlaps
1414
* This phase runs after PCB layout is complete but before final rendering
1515
*
16-
* PERFORMANCE OPTIMIZATIONS:
17-
* 1. Direct silkscreen element access: Uses rootCircuit.selectAll("silkscreen*") to get all elements directly
18-
* 2. Spatial filtering: Only processes silkscreen elements within search radius
19-
* 3. Component-aware database access: Direct .get(id) calls for fresh state
16+
* APPROACH:
17+
* 1. Uses component.selectAll("silkscreentext") to discover silkscreen text components
18+
* 2. Links components to database records for position data and update operations
19+
* 3. Performs overlap detection and position adjustment as needed
2020
*
21-
* Performance improvement: From O(N*M*K) to O(S) where:
22-
* - S = number of silkscreen component instances (much smaller than total DB records)
23-
* - No component discovery overhead - get silkscreen elements directly
24-
* - No complex component hierarchy traversal needed
21+
* PERFORMANCE BENEFITS:
22+
* - Uses selectAll() for component discovery (avoids database traversal)
23+
* - Targeted database queries only for components that exist
24+
* - Minimal database access compared to full table scanning approaches
25+
*
26+
* Note: Some database access is still required because:
27+
* - Database records contain the authoritative position data
28+
* - Position updates must be written back to the database
29+
* - Component-DB linking timing issues require fallback record matching
2530
*/
2631
export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
2732
component: NormalComponent<any>,
@@ -32,35 +37,62 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
3237
// Only adjust silkscreen text for components that opt in
3338
if (!component._adjustSilkscreenTextAutomatically) return
3439

35-
// Get this component's silkscreen texts (minimal DB query)
36-
const componentSilkscreenTexts = component.pcb_component_id
37-
? db.pcb_silkscreen_text
38-
.list()
39-
.filter((text) => text.pcb_component_id === component.pcb_component_id)
40-
: []
40+
// Use selectAll to find silkscreen text components (avoids database traversal)
41+
const silkscreenTextComponents = component.selectAll("silkscreentext")
4142

42-
if (componentSilkscreenTexts.length === 0) return
43+
if (silkscreenTextComponents.length === 0) return
4344

4445
// Get component center early to avoid repeated lookups
4546
const componentCenter = getComponentCenterFromCache(component, db)
4647
if (!componentCenter) return
4748

48-
// Get all silkscreen elements from database (using selectAll for component discovery)
49-
const nearbySilkscreenElements = getAllSilkscreenElementsFromDB(
50-
component.root,
51-
db,
52-
)
49+
// For each silkscreen text component found, get its database record for processing
50+
for (const textComponent of silkscreenTextComponents) {
51+
// Skip if this component doesn't have the required data
52+
if (!textComponent.props?.text) continue
53+
54+
// Get the database record for this specific text component
55+
// Note: We need the DB record for accurate position data and update operations
56+
let textDbRecord: any = null
57+
58+
// Try direct ID lookup first (most efficient)
59+
if ((textComponent as any).pcb_silkscreen_text_id) {
60+
textDbRecord = db.pcb_silkscreen_text.get(
61+
(textComponent as any).pcb_silkscreen_text_id,
62+
)
63+
}
64+
65+
// If direct lookup fails, we need to find the matching database record
66+
// This is necessary because the component-DB linking might not be complete yet
67+
if (!textDbRecord && component.pcb_component_id) {
68+
// Use a targeted database query (filter by component ID, not full table scan)
69+
const candidateTexts = db.pcb_silkscreen_text
70+
.list()
71+
.filter((t) => t.pcb_component_id === component.pcb_component_id)
72+
73+
// Match by text content to find the right record
74+
textDbRecord = candidateTexts.find(
75+
(t) => t.text === textComponent.props.text,
76+
)
77+
}
78+
79+
if (!textDbRecord) continue
80+
81+
const textBounds = getSilkscreenTextBounds(textDbRecord)
82+
83+
// Get all silkscreen elements from database (using selectAll for component discovery)
84+
const nearbySilkscreenElements = getAllSilkscreenElementsFromDB(
85+
component.root,
86+
db,
87+
)
5388

54-
// For each silkscreen text, check for overlaps and adjust if needed
55-
for (const refText of componentSilkscreenTexts) {
56-
const textBounds = getSilkscreenTextBounds(refText)
5789
let hasOverlap = false
5890

5991
// Check overlap with nearby silkscreen elements only (much faster than checking all)
6092
for (const element of nearbySilkscreenElements) {
6193
if (
62-
element.layer === refText.layer &&
63-
element.element_id !== refText.pcb_silkscreen_text_id
94+
element.layer === textDbRecord.layer &&
95+
element.element_id !== textDbRecord.pcb_silkscreen_text_id
6496
) {
6597
if (boundsOverlap(textBounds, element.bounds)) {
6698
hasOverlap = true
@@ -72,8 +104,8 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
72104
if (hasOverlap) {
73105
// Try flipping to the opposite side
74106
const currentOffset = {
75-
x: refText.anchor_position.x - componentCenter.x,
76-
y: refText.anchor_position.y - componentCenter.y,
107+
x: textDbRecord.anchor_position.x - componentCenter.x,
108+
y: textDbRecord.anchor_position.y - componentCenter.y,
77109
}
78110

79111
const flippedPosition = {
@@ -96,8 +128,8 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
96128
// Check the flipped position against nearby elements only
97129
for (const element of nearbySilkscreenElements) {
98130
if (
99-
element.layer === refText.layer &&
100-
element.element_id !== refText.pcb_silkscreen_text_id
131+
element.layer === textDbRecord.layer &&
132+
element.element_id !== textDbRecord.pcb_silkscreen_text_id
101133
) {
102134
if (boundsOverlap(flippedTextBounds, element.bounds)) {
103135
flippedHasOverlap = true
@@ -108,7 +140,7 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
108140

109141
if (!flippedHasOverlap) {
110142
// Update to the flipped position
111-
db.pcb_silkscreen_text.update(refText.pcb_silkscreen_text_id, {
143+
db.pcb_silkscreen_text.update(textDbRecord.pcb_silkscreen_text_id, {
112144
anchor_position: flippedPosition,
113145
})
114146
}

0 commit comments

Comments
 (0)