[Fastcat] FullIndex를 알아보자. (2)
SegmentWriter에 대해 알아보는 시간이다.
SegmentWriter에는 문서 텍스트 및 포스팅 정보, 렉시콘, 필터, 정렬, 그룹에 필요한 정보를 가공하는 역할을 한다.
SourceReader에서 하나의 문서를 schema.xml에서 정의한 속성대로 저장한다.
한문서를 읽을 때마다 DocumentWriter, SearchWriter, FilterWriter, SortWriter, GroupWriter의 write를 실행한다.
while(!requestStop && sourceReader.hasNext()){
Document doc = sourceReader.next();
int docNo = documentWriter.write(doc);
if(lastDocNo != docNo)
throw new IRException("~~~");
searchWriter.write(doc);
filterWriter.write(doc);
sortWriter.write(doc);
groupWriter.write(doc);
lastDocNo++;
if(lastDocNo % 10000 == 0){
lapTime = System.currentTimeMillis();
}
}
먼저 DocumentWriter를 알아보자
압축된 문서를 저장하는 docOutput, docOutput에서 문서 위치를 저장하는 positionOutput, 삭제할 문서 목록을 저장하는 deleteSet,
마지막으로 PrimaryKey를 저장하는 pkIndexWriter DocumentWriter를 실행하면 총 4개의 파일이 생성된다.
우선 문서 저장(docOutput, positionOutput)에 대해 알아보자.
for (int i = 0; i < document.size(); i++) {
Field f = document.get(i);
..............
if (fields.get(i).store) {
IOUtil.writeVariableByte(fbaos, buffer.pos());
fbaos.writeBytes(buffer.array(), 0, buffer.pos());
} else {
IOUtil.writeVariableByte(fbaos, 0);
}
}
하나의 문서에 대해서 Schema에서 지정한 필드 수만큼 for문을 돈다.
Field를 하나씩 돌면서 이 데이타를 저장할지 말지를 { if(fields.get(i).store)} 결정하고 byte 배열 fbaos 에 저장한다.
if((localDocNo + 1) % DOCUMENT_BLOCK_SIZE == 0){
writeInternal();
}
내부문서 번호+1이 DOCUMENT_BLOCK_SIZE의 배수일 경우 writeInternal을 실행하는데 writeInternal을 보면 알겠지만 fbaos을
위 그림이 압축된 문서와 압축된 문서의 위치 정보를 저장할때의 구조이다.
int preDocNo = pkIndexWriter.put(buffer.array(), buffer.pos(), localDocNo);
bucket과 keyPos는 int형 배열이고, array는 byte형 배열이다.
bucket의 배열 인덱스는 필드데이터를 해싱한 결과이고, 값은 keyPos 배열의 인덱스가 저장되어있다.
keyPos의 배열 인덱스는 sequence 저장이 되고, 값은 데이터가 저장된 array의 시작 인덱스가 저장되어있다.
intValueArray의 배열 인덱스는 keyPos의 인덱스와 동일하다. 배열의 값은 내부 문서번호가 저장되어있다.
keyPos의 4번째 데이타와 intValueArray의 4번째 내부문서번호는 서로 연결된(?) 데이터이다.
int형 배열 nextIdx도 있는데, 해싱의 중복이 발생하기 때문에 이를 해결하기 위해 만든 변수이다.
해싱한 결과들이 중복이 없다면, bucket과 keyPos는 1:1관계가 되어서 바로바로 찾으면 된다.
하지만 중복이 발생한다면 1:N관계가 된다. bucket은 하나의 keyPos만 가리킬수가 있어서 데이타가 다를경우
검색할때, indexOutput에 있는 data를 비교하면서 indexOutput의 data보다 크거나 같은 부분을 찾고
마지막으로 알아볼건 삭제 문서파일 생성이다.
int preDocNo = pkIndexWriter.put(buffer.array(),buffer.pos(), localDocNo);
대강의 전체 문서의 갯수를 구한후 하나의 long 변수는 64개의 문서를 체크한다.
이 되는것이다.