Skip to content

feat(engine): Pagination 기능을 가진 CSM Dictionary Builder 구현#917

Merged
SingTheCode merged 3 commits into
core/CSMDictfrom
feature/#916_build-csm-with-pagination
Oct 5, 2025
Merged

feat(engine): Pagination 기능을 가진 CSM Dictionary Builder 구현#917
SingTheCode merged 3 commits into
core/CSMDictfrom
feature/#916_build-csm-with-pagination

Conversation

@SingTheCode

Copy link
Copy Markdown
Contributor

🎯 목적

대규모 저장소에서 효율적인 지연 로딩(lazy loading)을 위해 커서 기반 페이지네이션을 지원하는 CSM Dictionary Builder를 구현합니다.

📋 주요 변경사항

1. buildPaginatedCSMDict 함수 추가

  • 커서 기반 페이지네이션: lastCommitId를 커서로 사용하여 다음 페이지 탐색
  • 페이지 크기 제어: perPage 파라미터로 한 번에 로드할 커밋 수 조절
  • 유효성 검증: perPage, stemDict, lastCommitId에 대한 포괄적인 검증
  • PR 통합: 기존 buildCSMDict와 동일하게 Pull Request 정보 통합

2. 코드 품질 개선 (리팩토링)

  • 중복 제거: buildPRDict 유틸리티 함수 추출
  • 코드 재사용성: buildCSMNodesWithPR 함수 추출로 공통 로직 공유
  • JSDoc 개선: 모든 함수에 상세한 문서화 및 예제 추가
  • 일관성: 변수명 통일 (prDict, baseStem) 및 검증 로직 일관화

3. 테스트 커버리지 강화

  • 8개의 테스트 케이스 추가 (csm.spec.ts)
    • 기본 페이지네이션 동작
    • 커서 기반 탐색
    • 경계값 처리 (마지막 페이지, 빈 페이지)
    • 에러 케이스 (잘못된 perPage, lastCommitId)
    • PR 통합 검증

4. 패키지 엔트리포인트 업데이트

  • buildPaginatedCSMDictindex.ts에서 export
  • 외부 패키지에서 사용 가능하도록 API 노출

📊 영향 범위

  • Analysis Engine: CSM 빌드 로직 확장
  • 파일 변경: 3개
    • csm.ts: +90줄 (새 함수 및 리팩토링)
    • csm.spec.ts: +148줄 (테스트 추가)
    • index.ts: +2줄 (export 추가)
  • 하위 호환성: 유지 (기존 buildCSMDict 동작 변경 없음)

🚀 성능 개선

  • 메모리 사용량 감소: 전체 커밋을 한 번에 로드하지 않고 필요한 만큼만 로드
  • 초기 로딩 속도 향상: 첫 페이지만 로드하여 초기 렌더링 시간 단축
  • 대규모 저장소 지원: 수천 개의 커밋이 있는 저장소에서도 원활한 동작

📝 API 사용 예시

// 첫 페이지 로드 (최신 10개 커밋)
const firstPage = buildPaginatedCSMDict(
  commitDict,
  stemDict,
  'main',
  10  // perPage
);

// 다음 페이지 로드
const lastCommit = firstPage['main'][9];
const secondPage = buildPaginatedCSMDict(
  commitDict,
  stemDict,
  'main',
  10,
  lastCommit.base.commit.id  // lastCommitId
);

✅ 체크리스트

  • 모든 테스트 통과 확인 (8개 신규 테스트 포함)
  • 기존 buildCSMDict 동작 유지 확인

🔗 관련 이슈

📚 기술적 세부사항

페이지네이션 로직

  1. lastCommitId가 없으면 startIndex = 0 (첫 페이지)
  2. lastCommitId가 있으면 해당 커밋의 다음 인덱스부터 시작
  3. perPage 개수만큼 slice하여 페이지 노드 추출
  4. CSM 노드 생성 및 PR 정보 통합

에러 처리

  • perPage <= 0: "perPage must be greater than 0"
  • stemDict.size === 0: "no stem"
  • baseStem이 없음: "no master-stem"
  • 잘못된 lastCommitId: "Invalid lastCommitId"

🔄 마이그레이션 가이드

기존 코드는 변경 없이 동작합니다. 페이지네이션이 필요한 경우에만 새 함수를 사용하세요:

// Before (기존 방식)
const csmDict = buildCSMDict(commitDict, stemDict, 'main', pullRequests);

// After (페이지네이션이 필요한 경우)
const paginatedCsmDict = buildPaginatedCSMDict(
  commitDict,
  stemDict,
  'main',
  50,  // 한 번에 50개씩
  undefined,  // 첫 페이지
  pullRequests
);

SingTheCode and others added 2 commits September 30, 2025 23:08
- Add buildPaginatedCSMDict function with cursor-based pagination
- Support perPage parameter to control page size
- Implement lastCommitId cursor for next page navigation
- Add comprehensive test coverage (8 test cases)
- Extract buildPRDict utility function to reduce duplication
- Export buildPaginatedCSMDict from package entry point

The new function enables efficient lazy loading of CSM nodes
for large repositories, improving performance and memory usage.

Related: #916

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Extract buildCSMNodesWithPR to eliminate code duplication
- Add comprehensive JSDoc documentation with examples
- Improve validation consistency across functions
- Enhance variable naming (prDict, baseStem)
- Add stemDict.size validation to buildPaginatedCSMDict

This refactoring improves maintainability and reusability
while preserving all external behavior. All tests pass.

Related: #916

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@ytaek

ytaek commented Sep 30, 2025

Copy link
Copy Markdown
Contributor

아, 제가 pagination을 잘 이해 못 한것 같은데
아래 적어주신 코드 대로 하면,
view에서는 첫번째 페이지랑, 두번째 페이지 결과를 어떻게 합쳐서 보여줘야할까요?
(예를 들어, csm이 잘려서 표현되는 경우?)

// 첫 페이지 로드 (최신 10개 커밋)
const firstPage = buildPaginatedCSMDict(
  commitDict,
  stemDict,
  'main',
  10  // perPage
);

// 다음 페이지 로드
const lastCommit = firstPage['main'][9];
const secondPage = buildPaginatedCSMDict(
  commitDict,
  stemDict,
  'main',
  10,
  lastCommit.base.commit.id  // lastCommitId
);

@SingTheCode

Copy link
Copy Markdown
Contributor Author

@ytaek

아, 제가 pagination을 잘 이해 못 한것 같은데
아래 적어주신 코드 대로 하면,
view에서는 첫번째 페이지랑, 두번째 페이지 결과를 어떻게 합쳐서 보여줘야할까요?
(예를 들어, csm이 잘려서 표현되는 경우?)

=> Stem 을 이미 만들고 perPage 만큼 CSMDict를 만들어서 보여주기 때문에 CSMNode를 만들다가 중간에 잘리는 케이스는 없을 것이라고 생각했습니다!

@SingTheCode
SingTheCode requested a review from ytaek October 1, 2025 07:45
@ytaek

ytaek commented Oct 1, 2025

Copy link
Copy Markdown
Contributor

=> Stem 을 이미 만들고 perPage 만큼 CSMDict를 만들어서 보여주기 때문에 CSMNode를 만들다가 중간에 잘리는 케이스는 없을 것이라고 생각했습니다!

commit을 10개씩 자르면,
csm이 큰놈이 걸려서 20개씩 있다고 하면, 잘려서 안 보이지 않을까요?
그리고, 그 잘린놈을 앞페이지랑 연결하는 모듈도 필요하지 않을까용?

@SingTheCode

Copy link
Copy Markdown
Contributor Author

commit을 10개씩 자르면,
csm이 큰놈이 걸려서 20개씩 있다고 하면, 잘려서 안 보이지 않을까요?
그리고, 그 잘린놈을 앞페이지랑 연결하는 모듈도 필요하지 않을까용?

=> @ytaek CSMNode는 다 만들어진 Stem을 기준으로 만들어서 잘릴 일이 없을 것 같은데 이 내용도 혹시 일요일에 설명 해주실 수 있으실까요??

@ytaek ytaek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pagination 기능 확인했습니다!!!! 심플한 방법이 좋은 것 같아요!! LGGGGTM!

@SingTheCode
SingTheCode changed the base branch from refactor/csm-improvements to core/CSMDict October 5, 2025 14:26
@SingTheCode
SingTheCode merged commit 477a6f3 into core/CSMDict Oct 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants