Exemplo n.º 1
0
  /**
   * 获取下一个语义单元
   *
   * @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());
    }
  }