리눅스 커널의 링크드리스트와 해시 테이블 구현을 이해하려고합니다. 구현 링크는 here입니다. 연결된 목록 구현을 이해했습니다. 하지만 난 왜 두 포인터가 hlist (** pprev)에서 사용되고 있는지 혼란 스럽다. hlist에 대한 링크는 here입니다. 나는 목록의 머리가 단지 하나의 포인터를 필요로하고 그것이 공간을 절약하기 때문에 hlist가 해시 테이블의 구현에 사용된다는 것을 이해한다. 단일 포인터 (링크 된 목록과 같은 * prev)를 사용하여 수행 할 수없는 이유는 무엇입니까? 도와주세요.리눅스 커널에서 더블 포인터 사용 해시리스트 구현
16
A
답변
19
그 이유는 코멘트 중 하나에서 찾을 수 있습니다
: 대신 pprev **의 * 이전 한 경우
547/*
548 * Double linked lists with a single pointer list head.
549 * Mostly useful for hash tables where the two pointer list head is
550 * too wasteful.
551 * You lose the ability to access the tail in O(1).
552 */
, 우리는 메모리를 저장하려고하기 때문에, 우리는에 * 이전에 포함되지 않습니다 머리는, 다음 우리 hlist 구현은 다음과 같습니다
이struct hlist_head {
struct hlist_node *first = null;
};
struct hlist_node {
struct hlist_node *next;
struct hlist_node *prev;
};
prev
포인터가 머리를 가리 할 수없는 공지 사항, 또는 (**pprev
달리) head->first
. prev
이 hlist_add_head()
의 위 imeplementation에, 가리 무관
void
hlist_init(struct hlist_head *head) {
head->first = null;
}
void
hlist_add_head(struct hlist_head *head, struct hlist_node *node) {
struct hlist_node *next = head->first;
head->first = node;
node->next = next;
node->prev = NULL;
if (next) {
next->prev = node;
}
}
주의하는 것이 우리가 hlist_add_before()
를 구현할 때 살펴 보 겠지만 이것은 hlist 구현을 복잡하게한다. 당신이 hlist_add_before()
을 구현할 때, 지금은 다음과 같습니다 : 지금 우리는 스택에 head
를 밀어 추가 push
명령을 필요로 hlist_add_before()
에뿐만 아니라 head
에 전달해야
void
hlist_add_before(struct hlist_head *head,
struct hlist_node *node,
struct hlist_next *next) {
hlist_node *prev = next->prev;
node->next = next;
node->prev = prev;
next->prev = node;
if (prev) {
prev->next = node;
} else {
head->first = node;
}
}
알 수 있습니다. 게다가 구현에 추가적인 조건부 검사가있어 상황이 더욱 느려집니다.
**pprev
대신 *prev
대신 다른 hlist 작업을 구현해보십시오. 그러면 구현이 Linux 커널에서 본 것보다 느려질 것입니다.
관련 문제
- 1. 리눅스 커널 ICMP 구현 질문 현재 리눅스 커널에서
- 2. 리눅스 커널에서 기존 모듈 수정하기
- 3. 리눅스 커널에서 파일에 데이터 추가하기
- 4. 리눅스 커널에서 패킷 생성을위한 튜토리얼
- 5. 리눅스 커널에서 인터럽트 핸들러의 반환 값
- 6. 리눅스 커널에서 파일 읽기 및 쓰기
- 7. 리눅스 커널에서 IPv6 구현에 관한 자료
- 8. 리눅스 커널에서 tcp 처리 후 패킷 처리
- 9. __KERNEL__이 (가) 리눅스 커널에서 사용되는 것은 무엇입니까?
- 10. ext3 리눅스 커널 구현
- 11. 리눅스 커널에서 첫 번째 프로세스는 어디에서 초기화 되었습니까?
- 12. OpenCL 커널에서 __constant qualifer 사용
- 13. CUDA 커널에서 가상 함수 사용
- 14. 리눅스 커널에서 spinlock이 ".subsection 1"(또는 ".text.lock.smth")에있는 이유는 무엇입니까?
- 15. 왜 인용 더블 나는 간단한 리눅스 스크립트가
- 16. 리눅스 커널에서 실행되는 서버. 스레드에서 발생해야하는지 말 것인가?
- 17. 리눅스 셸에서 파이프 라인 구현
- 18. 리눅스 나 다른 J2ME 구현
- 19. 리눅스 커널에서 4 개의 세그먼트의 기본 주소가 동일한 이유는 무엇입니까?
- 20. 커널 스레드를 사용할 때와 리눅스 커널에서 작업 큐를 사용하는 경우
- 21. 리눅스 커널에서 프로세스 코어 덤프 생성과 관련된 파일
- 22. Silverlight 4 Datagrid에서 더블 클릭 이벤트 구현
- 23. 더블 타입 배열은 J2ME에서 사용
- 24. Google지도에서 더블 클릭을 사용 중지합니다.
- 25. 리눅스 - ldconfig 사용
- 26. C# 포인터 사용
- 27. 포인터 및 구조체 사용
- 28. 함수 포인터 사용
- 29. 커널에서 qdisc를 관리하는 방법
- 30. 리눅스 기반 시스템 용 OSI TP4 구현
답변 해 주셔서 감사합니다. 하지만 의심의 여지가없는 이유는 * prev 및 이중 연결된 목록이 있습니다. 이 방법을 사용하면 두 가지 방법을 모두 통과 할 수 있습니다. O (1)에서 노드를 추가하고 삭제할 수 있습니다. 사용 된 메모리는 두 경우 모두 동일합니다. 나는 분명히 여기에 뭔가 빠져있다. 내 실수를 지적 해 주시겠습니까? – bala1486
정교한 답변이 도움이되는지 확인하십시오. :) – Sudhanshu
대단히 감사합니다 ... – bala1486