2010-11-24 3 views
1

ets 테이블을 상태로 유지하려는 gen_server를 작성한 후 다른 테이블에서 ets 테이블을 만들었습니다. 어떻게 이것을 gen_server의 상태에 추가해야합니까?gen_server 상태에 대한 ets 테이블 사용

메모리를 절약하기 때문에 ets 테이블을 대신 사용하여 새 사전을 만들려고합니다.

또한 어떻게 ets 테이블을 반복합니까? 테이블의 각 값을 반복하거나 읽은 다음 값을 확인하려면 값에 따라 두 가지 옵션 중 하나를 수행하려고합니다.

ets 테이블을 목록으로 바꾸고 목록을 순회하는 것이 더 쉬울까요?

감사

답변

4

제안 :

  • 는 ETS 맨 페이지를 읽기 : erl -man ets ETS 테이블합니다 (named_table 옵션의 경우) 중 하나의 이름으로 식별 또는입니다
  • 의 테이블 ID. gen_server에 정보를 전달하고 상태에 보관 :

    -record(state, { ..., tbl = none }). 
    
    
    init([TableID]) -> 
        ..., 
        {ok, #state { tbl = TableID }}. 
    

ETS는 아마도 그 많은 메모리를 저장하지 않습니다. ETL 테이블은 compressed이 될 수있는 Erlang/OTP 릴리스를위한 새 플래그가 있습니다. 따라서 내용이 저장 전에 압축되고 읽기가 수행 될 때 압축이 풀립니다 (계산 오버 헤드가 있음).

ETS 테이블을 반복하려면 몇 가지 옵션이 있습니다. ets:first/1 ets:next/2은 그러한 인터페이스 중 하나입니다. ets:foldl/3 ets:foldr/3 another. ets:match/3은 계속할 수있는 연속 (커서)을 제공합니다. ets:select은 성냥보다 훨씬 더 일반적입니다.

목록으로 바꾸는 것이 더 쉬울까요? 이것은 다릅니다. ETS 테이블의 기능은 요소가 저장된 키를 정의하는 옵션이 {keypos, N}이라는 것입니다. ets:lookup(?TAB, Key)은 매우 빠르므로 키를 빠르게 검색 할 수 있습니다. 목록에서는 그렇지 않습니다. 그러나 다른 한편으로는, 당신이 항상 모든 목록을 거쳐 간다면 더 간단한 해결책이 될 것입니다. (프로세스간에 큰 목록을 전달하지 않는 한).

전체 테이블을 목록으로 변환하고 탐색하는 것은 피해야합니다. 메모리에 목록을 생성 한 다음이를 트래버스하면 값 비쌉니다. 라이브 메모리의 양이 적기 때문에 한 번에 조금씩 트래버스하는 것이 좋습니다.

+0

감사합니다. 올바르게하고 싶은 몇 가지 문제. 이진 비트 필드를 생성하기 전에 토렌 표현을위한 ets 테이블을 생성합니다. ets 테이블을 읽고 필요한 청크에서 큐를 만들고 싶습니다. 이 대기열은 중복 요청을 피하기 위해 피어 처리기가 액세스합니다. 청크가 올바르게 수신되면 항목이 대기열에서 제거되고 비트 필드 또는 토런트 상태가 업데이트됩니다. 진행률 표시 줄 등을 표시하는 GUI에 대한 토렌트 상태를 추적하고 싶습니다. 제가 ets 테이블에서 사전을 만들거나 직접 테이블을 편집해야하는지 궁금합니다. – jarryd

+0

etorrent는 2 단계 프로세스를 사용합니다. 각 피어는 개별적으로 ETS 테이블을 읽고 결정합니다. 하지만 테이블은 '보호 됨'이므로 모든 실제 할당이 두 번째 단계에서 발생합니다. 지배하는 청크 관리자가 호출되며 테이블에 대한 액세스가 순차적으로 처리되므로 두 프로세스가 우연히 같은 청크를 차지하지 않습니다. 진보와 안전성을 제공함과 동시에 효과적인 병렬 처리를 제공합니다. –

+0

좋아, 우리는 필요한 덩어리에서 대기열을 만들려고합니다.청크가 메모리에없는 경우 디스크에 상주하지 않습니다. ets 테이블. 나는 덩어리 관리자가 붙잡혀있는 것을 추적하고 중복 잡기를 차단할 수 있다고 생각하지만, 전체 바이너리가 전송 될 때까지 데이터를 가져 오거나 액세스하는 것으로 끝나는 것입니까? – jarryd

관련 문제