/** * 获取下一个语义单元 * * @return 没有更多的词元,则返回null * @throws IOException */ public synchronized Lexeme next() throws IOException { if (context.getResultSize() == 0) { /* * 从reader中读取数据,填充buffer * 如果reader是分次读入buffer的,那么buffer要进行移位处理 * 移位处理上次读入的但未处理的数据 */ int available = fillBuffer(input); if (available <= 0) { context.resetContext(); return null; } else { // 分词处理 int analyzedLength = 0; for (int buffIndex = 0; buffIndex < available; buffIndex++) { // 移动缓冲区指针 context.setCursor(buffIndex); // 进行字符规格化(全角转半角,大写转小写处理) segmentBuff[buffIndex] = CharacterHelper.regularize(segmentBuff[buffIndex]); // 遍历子分词器 for (ISegmenter segmenter : segmenters) { segmenter.nextLexeme(segmentBuff, context); } analyzedLength++; /* * 满足一下条件时, * 1.available == BUFF_SIZE 表示buffer满载 * 2.buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL表示当前指针处于临界区内 * 3.!context.isBufferLocked()表示没有segmenter在占用buffer * 要中断当前循环(buffer要进行移位,并再读取数据的操作) */ if (available == BUFF_SIZE && buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL && !context.isBufferLocked()) { break; } } for (ISegmenter segmenter : segmenters) { segmenter.reset(); } // System.out.println(available + " : " + buffIndex); // 记录最近一次分析的字符长度 context.setLastAnalyzed(analyzedLength); // 同时累计已分析的字符长度 context.setBuffOffset(context.getBuffOffset() + analyzedLength); // 如果使用最大切分,则过滤交叠的短词元 if (context.isMaxWordLength()) { context.excludeOverlap(); } // 读取词元池中的词元 return buildLexeme(context.firstLexeme()); } } else { // 读取词元池中的已有词元 return buildLexeme(context.firstLexeme()); } }