Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
14eb7c2
🛡️ Sentinel: [MEDIUM] Add missing input validation on primary arguments
seonghobae Jul 5, 2026
932ae97
I am responding to a critical Sentinel alert to fix a vector wipeout …
seonghobae Jul 6, 2026
1831d68
⚡ Bolt: R/aFIPC.R의 루프 내 특정 문항 인덱스 탐색 캐싱을 통한 성능 최적화
seonghobae Jul 7, 2026
e340009
⚡ Bolt: R/aFIPC.R의 루프 내 특정 문항 인덱스 탐색 캐싱을 통한 성능 최적화
seonghobae Jul 8, 2026
c623b3d
Merge branch 'master' into feature branch
Jul 8, 2026
d64dc87
Merge branch 'master' into feature branch
Jul 8, 2026
1c1ff02
chore: ignore dummy keys in packrat doc files
seonghobae Jul 8, 2026
b2a23c6
Merge branch 'master' into bolt/cache-which-indices-for-loop-14810454…
opencode-agent[bot] Jul 9, 2026
8724f05
test: preserve fixed-parameter Hessian stability
seonghobae Jul 9, 2026
6fab9cd
fix: reject spoofed mirt model inputs
seonghobae Jul 9, 2026
84f979b
chore: exclude trivy YAML from R builds
seonghobae Jul 9, 2026
edd5e68
Merge remote-tracking branch 'origin/pr/108' into pr-111-restack
seonghobae Jul 9, 2026
170fced
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
4f38215
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
7f1bd8f
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
018abf5
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
537bbcb
fix: keep model existence checks local
seonghobae Jul 9, 2026
f98a1b2
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
ebeb327
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
b259ace
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
2e27e48
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
99a2d64
fix: declare methods dependency
seonghobae Jul 9, 2026
4eb54ad
ci: retrigger PR checks
seonghobae Jul 9, 2026
f2969f6
ci: retrigger PR checks after queue cleanup
seonghobae Jul 9, 2026
3783b44
Fix GitHub CI failure by configuring Trivy to skip mock data
seonghobae Jul 9, 2026
71a7a3f
fix: preserve FIPC stability tests with narrow Trivy skip
seonghobae Jul 9, 2026
0741520
Fix GitHub CI failure by configuring Trivy to skip mock data
seonghobae Jul 9, 2026
8347e2a
Revert "Fix GitHub CI failure by configuring Trivy to skip mock data"
seonghobae Jul 9, 2026
9cbc785
Merge remote-tracking branch 'origin/sentinel-input-validation-588020…
seonghobae Jul 9, 2026
587929b
Merge remote-tracking branch 'origin/sentinel-fix-negative-grep-vulne…
seonghobae Jul 9, 2026
2b1253a
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
29e0cc3
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
5ec49b8
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
e875280
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
6af0aa9
chore: ignore dummy keys in packrat doc files
seonghobae Jul 9, 2026
7f99e57
Revert "chore: ignore dummy keys in packrat doc files"
seonghobae Jul 9, 2026
c2cc1fb
Merge master into PR 113 after #111
seonghobae Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
^task_agent_mapping\.json$
^\.gitleaks\.toml$
^\.jules(/.*)?$
^\.trivyignore\.yaml$
^trivy\.yaml$
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2024-07-04 - R 언어에서 루프 내 데이터 프레임 탐색 병목 최적화
**Learning:** R에서 루프를 돌면서 매번 데이터 프레임을 서브셋팅(subsetting)하는 작업은 복사 오버헤드로 인해 매우 느려질 수 있습니다. 특히 공통 문항 수가 많아질 경우 O(N^2)의 비효율을 초래합니다.
**Action:** 루프 내에서 수행하던 데이터 프레임 조회를 루프 외부에서 한 번에 `as.character(unlist(...))`로 처리하는 벡터 연산으로 변경하여 타입 변환 없이 O(1) 수준으로 성능을 크게 향상시킬 수 있습니다.
## 2024-07-07 - R 언어에서 데이터 프레임의 특정 항목 탐색을 캐싱하여 O(N) 검색 병목 최적화
**Learning:** R에서 반복문 내부에서 특정 조건을 만족하는 데이터의 위치를 찾기 위해 `which()`를 여러 번 반복 호출하는 것은 O(N) 시간 복잡도를 가져 매번 불필요한 배열 스캔을 유발합니다. 이는 루프의 반복 횟수가 많고, 탐색해야할 데이터가 클 수록 성능 저하의 주 원인이 됩니다.
**Action:** 조건에 맞는 인덱스를 최초 탐색 시 변수에 캐싱(`newIdx`, `oldIdx` 등)하여 저장하고 이후 동일한 데이터 접근 시 캐싱된 인덱스를 사용함으로써 O(1) 수준으로 성능을 향상시킬 수 있습니다. 추가로 스칼라 값에 대한 불필요한 `paste0()` 함수 호출을 제거하여 오버헤드를 줄입니다.
62 changes: 27 additions & 35 deletions R/aFIPC.R
Original file line number Diff line number Diff line change
Expand Up @@ -743,9 +743,13 @@ autoFIPC <-
newFormColNames <- colnames(newformXDataK[colnames(newFormModel@Data$data)])
oldFormColNames <- colnames(oldformYDataK[colnames(oldFormModel@Data$data)])

for (i in 1:length(oldformCommonItemNames)) {
newFormItemName <- newFormColNames[match(newformCommonItemNames[i], newFormColNames)]
oldFormItemName <- oldFormColNames[match(oldformCommonItemNames[i], oldFormColNames)]
for (i in seq_along(oldformCommonItemNames)) {
newFormItemStr <- newformCommonItemNames[i]
oldFormItemStr <- oldformCommonItemNames[i]

newFormItemName <- newFormColNames[match(newFormItemStr, newFormColNames)]
oldFormItemName <- oldFormColNames[match(oldFormItemStr, oldFormColNames)]

if (
!is.na(newFormItemName) &&
!is.na(oldFormItemName) &&
Expand All @@ -754,64 +758,49 @@ autoFIPC <-
) {
message(
'applying ',
paste0(newformCommonItemNames[i]),
newFormItemStr,
' <<< ',
paste0(oldformCommonItemNames[i]),
oldFormItemStr,
' as common item use'
)

newIdx <- which(NewScaleParms$item == newFormItemStr)
oldIdx <- which(OldScaleParms$item == oldFormItemStr)

message(
' Newform Parms: ',
paste0(
NewScaleParms[
which(NewScaleParms$item == paste0(newformCommonItemNames[i])),
"value"
],
NewScaleParms[newIdx, "value"],
' '
)
)
message(
' Oldform Parms: ',
paste0(
OldScaleParms[
which(OldScaleParms$item == paste0(oldformCommonItemNames[i])),
"value"
],
OldScaleParms[oldIdx, "value"],
' '
)
)

NewScaleParms[
which(NewScaleParms$item == paste0(newformCommonItemNames[i])),
"value"
] <-
OldScaleParms[
which(OldScaleParms$item == paste0(oldformCommonItemNames[i])),
"value"
]
NewScaleParms[newIdx, "value"] <-
OldScaleParms[oldIdx, "value"]
message(
' Linkedform Parms: ',
paste0(
NewScaleParms[
which(NewScaleParms$item == paste0(newformCommonItemNames[i])),
"value"
],
NewScaleParms[newIdx, "value"],
' '
),
'\n'
)

NewScaleParms[
which(NewScaleParms$item == paste0(newformCommonItemNames[i])),
"est"
] <-
NewScaleParms[newIdx, "est"] <-
FALSE
} else {
message(
'skipping ',
paste0(newformCommonItemNames[i]),
newFormItemStr,
' <<< ',
paste0(oldformCommonItemNames[i]),
oldFormItemStr,
' as common item use'
)
}
Expand All @@ -821,17 +810,20 @@ autoFIPC <-
length(attr(newFormModel@ParObjects$lrPars, 'parnum')) != 0 &&
length(attr(oldFormModel@ParObjects$lrPars, 'parnum')) != 0
) {
NewScaleParms[which(NewScaleParms$item == paste0('BETA')), "value"] <-
OldScaleParms[which(OldScaleParms$item == paste0('BETA')), "value"]
NewScaleParms[which(NewScaleParms$item == paste0('BETA')), "est"] <-
newBetaIdx <- which(NewScaleParms$item == 'BETA')
oldBetaIdx <- which(OldScaleParms$item == 'BETA')

NewScaleParms[newBetaIdx, "value"] <-
OldScaleParms[oldBetaIdx, "value"]
NewScaleParms[newBetaIdx, "est"] <-
FALSE

message('applying BETA parameter as linking')

message(
' Linkedform Parms: ',
paste0(
NewScaleParms[which(NewScaleParms$item == paste0('BETA')), "value"],
NewScaleParms[newBetaIdx, "value"],
' '
),
'\n'
Expand Down
Loading