가장 중요한 질문은 파일에 액세스하는 방법입니다. 순차적 액세스 또는 임의 액세스?
순차 액세스 (일종의) 또는 소수의 데이터
파일의 각 객체를 구분하는 가장 좋은 방법은 무엇
. 예를 들어, 텍스트 파일에서 개행 문자로 각 객체를 분리 할 수 있습니다. 바이너리 파일에도이 방법이 유효합니까?
분명히 ;-). 그러나 더 나은 솔루션이 있다는 것에 대해 걱정하지 마십시오. 데이터 목록을 저장하려면 문자 그대로 list<data>
을 저장할 수 있습니다. 우리는 여전히 읽고 한 번에 모든 것을 쓰기 때문에
struct foo { 1: string field, 2: i32 otherfield }
struct bar { 1: map<string,wtf> seinfield, 2: double cloverfield }
struct wtf { 1: list<double> even_more_fields }
union MyDataRecord {
1: foo foo
2: bar bar
3: wtf wtf
}
list<MyDataRecord>
: 즉, 뭔가 같은 :
struct foo { 1: string field, 2: i32 otherfield }
list<foo>
데이터는 foo
하지만, 유형을 변화의 사이에 노동 조합을 넣어하지 않는 경우 인공 리미터가 필요 없습니다.
(역 직렬화 중에 사용할) 각 개체의 형식을 표시하려면 각 바이트 시퀀스의 시작 부분에 형식 필드를 추가 할 계획입니다. 더 나은 접근 방법이 있습니까?
위에서 설명한 것처럼 데이터를 list<>
에 넣으면 Thrift가 처리합니다. 전체 목록을 읽고 쓰는 것만으로도 충분합니다. 당신이 당신의 데이터에 대한 랜덤 액세스를 원하는 경우
랜덤 액세스 및/또는 데이터의 많은
상황이 극적으로 변경됩니다. 이 문제는 효율적이고 신속하게하기 위해서 항상 파일 전체를 스캔하지 않고 파일에서 주어진 요소의 위치를 결정해야합니다.1). 대부분의 경우, 기록되는 항목의 바이트 크기는 다양합니다. 그들 모두가 한 종류 foo
의 경우에도 단지, 하나는 여전히 foo
변수 크기의 데이터 멤버를 가지고 있기 때문에 특정 요소가
position = sizeof(foo) * index_of_desired_element
에 있다고 가정 할 수 다음 string
필드.
이 문제를 해결하기 위해 기본적으로 두 가지 옵션이 있습니다.
(1) 고정 크기 레코드 : 모든 요소가 미리 정의 된 최대 크기를 초과하지 않도록하고 파일 레코드 크기로 사용할 수 있습니다. list<>
을 더 이상 사용하지 않고 파일의 올바른 위치에 데이터를 기록합니다. n 번째 요소의 위치는 다시
position = N * predefined_record_size
단점 우리가 잠재적으로 많은 공간 플러스 데이터의 제한된 크기를 낭비하는 것이보다 분명하다.
(2) 인덱스 파일 : 두 번째 옵션은 데이터 파일의 각 항목의 위치를 보유하는 별도의 인덱스 파일을 유지 관리하는 것입니다. 이것은 다시 정수의 간단한 목록 수 :
list<i32>
여기 단점은, 인덱스 특히 삽입에 적절한 모양에 있는지 확인 파일의 중간에 삭제 작업을 업데이트 할 필요가있다 .
위의 두 가지 옵션의 일반적인 문제는 많은 데이터를 이동해야하기 때문에 삽입 및 삭제 작업이 어려워 질 수 있다는 것입니다. 이를 처리하기 위해 마커 삭제와 같은 특수 효과를 솔루션에 추가하는 것을 발견하게됩니다.
당신의 데이터 만 잔뜩 가지고
경우 결론은 list<union>
접근 방식은 당신이 찾고있는 무엇을 수 있습니다. union
은 언제든지 확장 가능하므로 나중에 다른 요소를 추가 할 수 있습니다.
데이터에만 순차적으로 액세스하려는 경우 list<union>
접근 방식을 선택하거나 union
요소를 하나씩 읽거나 쓰십시오. Thrift는 불필요한 데이터를 건너 뛸 수있는 기능을 지원합니다 (Skip()
).
그러나 임의로 데이터에 액세스하고 많은 양의 데이터를 처리하려는 경우 실제 데이터베이스가 더 적합 할 수 있습니다. 레코드 구분자에 대한 잠재적 큰 파일을 검색
는
1)the kind of O(?) you want 아니다.
설명해 주셔서 감사합니다. 나의 유스 케이스는 순차적 접근이다. 그러나 인덱스 파일을 유지 관리하는 대신 레코드 크기와 레코드 크기를 함께 저장하는 것이 좋습니다. 예를 들어 모든 레코드의 처음 4 바이트는 레코드를 구성하는 바이트 수를 나타냅니다 (레코드가 4GB보다 크지 않다고 가정). 이렇게하면 절대 오프셋을 저장할 필요가 없으며 삽입/삭제를 더 쉽게 수행 할 수 있습니다. – jithinpt
'124.657.013' 레코드의 인덱스 '15.883.127'에있는 항목을 검색, 삽입 또는 삭제하는 것이 실제로는 O (1) 작업인지 아니면 적어도 O (1) 작업인지에 관계없이 데이터 파일이 몇 GB에 걸쳐 있다고 가정하십시오. (logN)'알고리즘을 사용하고 있습니까? ** 데이터 항목이 10 개 밖에없는 경우 거의 모든 알고리즘이 빠릅니다. **. – JensG
아직도하고 싶다면'TFramedProtocol'을보십시오. 그것은 정확하게 그것을 수행하고 출력 스트림에 i32로 따라갈 데이터 프레임의 크기를 씁니다. – JensG