| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- 아랍어
- sim 스와핑
- Typesetting
- 양쪽 맞춤
- 카시다
- 의무이행심판
- 스마트국민제보
- 장소의명사
- 저면관수
- 법률상이익
- 설계원칙
- 두음현상
- 안전신문고
- 법정명
- rdb
- Clean Architecture
- 언어와 권력
- 손현보목사
- 클린아키텍처
- 해킹 사건
- 유심 해킹
- 언어
- 통신사 보안
- 대장동
- 식물집사
- 정치와종교
- bpfdoor
- 정교유착
- 두음규정
- 로그인정책
- Today
- Total
그루터기
Wrap-around된 수열을 정렬하는 방법 본문
어떤 수의 값이 지정된 범위를 넘어갈 때 가장 작은 값으로 되돌아오는 것을 wrap-around라고 합니다. 예를 들어서, 어떤 자료형이 0부터 9의 범위를 가지고 wrap-around할 때, 이 자료형에 1씩 계속 더하면
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, ...
이와 같이 9 다음에 0의 값을 가지게 될 것입니다.
위성 데이터에 관한 표준 권고안인 CCSDS Blue Book에서는 위성 데이터가 여러 개의 패킷으로 분할되어 지상으로 전송되며, 각 패킷은 연속적으로 증가하는 Packet Sequence Count라는 값을 갖도록 되어 있습니다. 그러나 이 값은 무한히 증가할 수 없기 때문에, 최댓값 16383의 다음 패킷은 0의 sequence count를 갖게 됩니다. 즉, 16384에서 wrap-around합니다. 문서에서는 다음과 같이 설명하고 있습니다.

패킷이 위성에서 지상으로 전송될 때, 패킷 간의 순서는 보장되지 않습니다. 따라서, 지상에서는 수신한 패킷을 packet sequence count 값에 따라서 정렬해서 사용해야 합니다. 하지만 패킷에 기록된 sequence counter 값은 16384로 나눈 나머지이기 때문에, 단순한 정렬로는 제대로 정렬을 수행할 수 없습니다.
| Packet | P0 | P1 | P2 | P3 | P4 | P5 | P6 | P7 |
| 실제 counter | 16380 | 16381 | 16382 | 16383 | 16384 | 16385 | 16386 | 16387 |
| Packet Sequence Count 필드 값 | 16380 | 16381 | 16382 | 16383 | 0 | 1 | 2 | 3 |
이렇게 여덟 개의 패킷이 전송된 경우, Packet Sequence Count 필드 값을 기준으로 정렬을 수행하면
P4, P5, P6, P7, P0, P1, P2, P3
의 이상한 순서가 되어 버릴 것입니다.
이러한 경우에 제대로 정렬을 수행하기 위해서는 먼저 한 가지 가정이 필요합니다. 패킷의 순서가 완전히 뒤죽박죽이 되어서는 안 된다는 것입니다. 조금 더 formal하게 기술해 보면, n번째에 생산된 패킷이 m번째로 수신되었을 때, 어떤 양의 정수 K에 대해서 |n - m| < K여야 한다는 것입니다. 이런 조건이 만족된다고 할 때, 패킷은 두 가지 중요한 정보를 갖게 됩니다. 바로 수신 순서와 Packet Sequence Count 값입니다. 즉, 수신 순서라는 부가적인 정보를 통해 Packet Sequence Count가 갖고 있는 불완전한 정보를 보완할 수 있습니다.
패킷의 실제 순서를 복원하기 위해서는 K 값에 일정한 조건이 필요합니다. (N은 wrap-around가 일어나는 최댓값입니다. 위의 예에서는 N = 16384입니다.)
- 같은 Packet Sequence Count 값을 갖는 패킷들 사이의 순서는 실제 패킷 순서와 같아야 합니다. 그렇지 않으면 패킷의 실제 순서를 복원할 수 없습니다. 이를 만족하기 위해서는, K < N / 2여야 합니다.
- 어떤 패킷을 기준으로 앞뒤 2t개의 패킷 중 같은 Packet Sequence Count 값을 갖는 패킷은 한 개만 존재할 수 있어야 합니다. 이렇게 되면 t 크기의 window 내에서는 Packet Sequence Count를 이용해서 비교하고, 그 밖에서는 수신 순서를 가지고 비교할 수 있습니다. 이를 만족하기 위해서는 K < (N - 2t) / 4이어야 합니다.
이러한 조건을 만족하는 패킷들의 리스트가 있을 때, 이를 정렬하기 위해서 다음과 같은 비교 함수를 작성할 수 있습니다. (reception_index는 수신 순서를, sequence_count는 Packet Sequence Count 필드의 값을 의미합니다.)
bool compare(const Packet& a, const Packet& b) {
if (a.reception_index + t < b.reception_index) {
return true;
} else if (b.reception_index + t < a.reception_index) {
return false;
} else if (a.sequence_count < b.sequence_count) {
return a.sequence_count + N / 2 > b.sequence_count;
} else {
return a.sequence_count - N / 2 > b.sequence_count;
}
}
비교 대상인 두 패킷 a와 b의 수신 index가 t 이상 떨어져 있으면, 두 패킷의 순서는 수신 순서를 통해 알 수 있습니다. 만약 수신 순서가 t 이내로 인접해 있다면, 두 패킷의 원래 counter 값은 N / 2 이상 차이나지 않을 것입니다. 따라서, N / 2 이상 차이나는 경우는 wrap-around가 일어난 경우로 간주할 수 있습니다.
'개발' 카테고리의 다른 글
| SK텔레콤 유심 정보 유출 사건 정리: 무엇이 문제였고, 어떻게 대응해야 할까? (0) | 2025.04.27 |
|---|---|
| MySQL REPLACE와 ON DUPLICATE KEY UPDATE 구문 (0) | 2023.01.03 |
| Clean Architecture 스터디: 3부 설계 원칙 (SOLID 원칙) (0) | 2021.08.15 |
| Clean Architecture 스터디: 1, 2부 (0) | 2021.05.05 |