<commit_before>package com.funtest.analysis.dao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import com.funtest.analysis.bean.ColumnInfo;
import com.funtest.analysis.bean.DataConfig;
import com.funtest.analysis.bean.DataInfo;
import com.funtest.analysis.bean.FileInfo;
import com.funtest.analysis.bean.Report;
import com.funtest.analysis.exception.AnalysisException;
import com.funtest.analysis.exception.DataNotFoundException;
import com.funtest.analysis.exception.LimitLineNotMatchException;
import com.funtest.analysis.exception.TestItemLineNotMatchException;
import com.funtest.core.bean.constant.Constants;
import com.google.gson.Gson;

public class ReportBuilder {
	DataInfo dataInfo;
	DataConfig dataConfig;

	/**
	 * 根据ins解析出DataInfo  并删除false数据的多余部分将数据文件保存到本地
	 * @param fileNames 文件名  多个
	 * @param ins		InputStream 多个 与文件名个数相等
	 * @param chipName  芯片名 （可选）
	 * @param mode 		数据处理模式     FT  or  FT&RT
	 * @return DataInfo 包含了生成报告所需的所有信息，如 测试项名称，判限等
	 * @throws IOException 
	 */
	public DataInfo buildDataInfo(String[] fileNames,InputStream[] ins,
										String reportName,String chipName,Integer mode) throws IOException{
		//todo
		//1.非空验证
		if(ins==null ||ins.length ==0){
			throw new AnalysisException("没有提供数据文件~");
		}
		if(StringUtils.isBlank(reportName)){
			throw new AnalysisException("报告名称未指定~");
		}
		if(StringUtils.isBlank(chipName)){
			chipName="undefined";
		}
		if(mode==null){
			mode=Constants.PROCESS_MODE_NORMAL;
		}
		if(fileNames.length != ins.length){
			throw new AnalysisException("文件数量与InputStream数量不一致~");
		}
		
		//2.填充 dataInfo
		DataInfo dataInfo= new DataInfo();
		dataInfo.setReportName(reportName);
		dataInfo.setMode(mode);
		dataInfo.setChipName(chipName);
		this.dataInfo=dataInfo;
		
		//填充
		this.doBuildDataInfo(fileNames, ins);
		
		System.out.println(new Gson().toJson(dataInfo));
		return dataInfo;
		
	}
	
	private DataInfo doBuildDataInfo(String[] fileNames,InputStream[] ins) throws IOException{
		if(dataInfo==null){
			throw new AnalysisException("DataInfo not set");
		}
		if(dataConfig==null){
			throw new AnalysisException("DataConfig not set");
		}
		
		String dir="upload";
		File dirFile=new File(dir);
		if(!dirFile.exists() && !dirFile.isDirectory()){
			dirFile.mkdir();
		}
		
		//各种判断的正则表达式
		Pattern patternDutNoColumn = Pattern.compile(dataConfig.getDutNoColumnFlag());
		Pattern patternSiteNoColumn = Pattern.compile(dataConfig.getSiteNoColumnFlag());
		Pattern patternDutPassColumn = Pattern.compile(dataConfig.getDutPassColumnFlag());
		Pattern patternTestItemColumnFlag = Pattern.compile(dataConfig.getTestItemColumnFlag());
		Pattern patternDutPassTrue = Pattern.compile(dataConfig.getDutPassTrueString());
		Pattern patternDutPassFalse = Pattern.compile(dataConfig.getDutPassFalseString());
		Pattern patternLimitMaxLine = Pattern.compile(dataConfig.getLimitMaxLineFlag());
		Pattern patternLimitMinLine = Pattern.compile(dataConfig.getLimitMinLineFlag());
		Pattern patternLimitLine=Pattern.compile(dataConfig.getLimitMinLineFlag()+"|"+dataConfig.getLimitMaxLineFlag());
		Pattern patternLimitUnitLine=Pattern.compile("^\\D");
		Pattern patternDataLine=Pattern.compile("^\\d");
		
		List<FileInfo> fileInfoList=new ArrayList<FileInfo>();
		List<ColumnInfo> columnInfoList=null;
		
		for(int i=0;i<ins.length;i++){
			//2.1填充FileInfo
			FileInfo fileInfo=new FileInfo();
			fileInfo.setFileName(fileNames[i]);
			
			if(!fileNames[i].endsWith(".csv")){
				//logger.info("{} skipped in createReportSnaps..",fileNames[i]);
				fileInfo.setStatus(Constants.PROCESS_STATUS_ERROR_FORMAT);
				fileInfo.setMessage("不是csv文件");
				fileInfoList.add(fileInfo);
				continue;
			}
			
			long lineNumber=-1;//当前读取的行号
			String curLine=null;//当前行字符串
			BufferedReader br= new BufferedReader(new InputStreamReader(ins[i]));
			String localFileName=dir+"\\"+UUID.randomUUID().toString()+".csv";
			PrintWriter pw=null;
			fileInfo.setStatus(Constants.PROCESS_STATUS_INITIAL_STATE);
			try {
				pw=new PrintWriter( new BufferedWriter(new FileWriter(localFileName)));
				while((curLine = br.readLine() )!= null ){
					pw.println(curLine);
					lineNumber++;
					if(lineNumber >10){
						break;
					}
					System.out.println("line"+(lineNumber)+": "+curLine);
					//匹配测试项所在行成功
					if(patternDutNoColumn.matcher(curLine).find()
							&& patternDutPassColumn.matcher(curLine).find()
							&& patternSiteNoColumn.matcher(curLine).find()
							&& patternTestItemColumnFlag.matcher(curLine).find()){
						//logger.info("测试项所在行："+(lineNumber-1));
						
						//record
						recordTestItemStr(curLine);					
						//开始查找limit
						String limitMinStr=null;
						String limitMaxStr=null;
						while((curLine = br.readLine() )!= null){
							pw.println(curLine);
							lineNumber++;
							if(limitMinStr==null || limitMaxStr==null){
								//匹配limit成功
								if(patternLimitLine.matcher(curLine).find()){
									if(limitMinStr==null 
											&& patternLimitMinLine.matcher(curLine).find()){
										limitMinStr=curLine;
										recordLimitMinStr(curLine);
									}
									if(limitMaxStr== null 
											&& patternLimitMaxLine.matcher(curLine).find()){
										limitMaxStr=curLine;
										recordLimitMaxStr(curLine);
									}
								}
								if(limitMinStr!=null && limitMaxStr !=null){
									
									//看看是否有单位行  此处限定unitLine为Min and Max的下一行
									curLine = br.readLine();
									lineNumber++;
									if(curLine !=null && patternLimitUnitLine.matcher(curLine).find()){
										recordLimitUnitStr(curLine);
										fileInfo.setStatus(Constants.PROCESS_STATUS_HEAD_DONE_WITH_UNIT);
									}else{
										fileInfo.setStatus(Constants.PROCESS_STATUS_HEAD_DONE_WITHOUT_UNIT);
									}
									
									break;//跳出判限查找
								}
							}
						}
						if(curLine==null){
							throw new DataNotFoundException("判限未找到",Constants.PROCESS_STATUS_CANT_FIND_LIMIT);
						}
						if(fileInfo.getStatus()!=Constants.PROCESS_STATUS_INITIAL_STATE){
							break;//跳出测试项查找
						}
					}
				}//循环结束
				if(curLine==null){
					throw new DataNotFoundException("测试项未找到",Constants.PROCESS_STATUS_CANT_FIND_TESTITEM);
				}
				
				//2.2填充ColumnInfo
				columnInfoList = getColumnInfoList(dataConfig);
				//copy剩余部分
				//正常到这的话是刚刚判断了单位行 未保存该行 且lineNumber++了
				if(fileInfo.getStatus() == Constants.PROCESS_STATUS_HEAD_DONE_WITH_UNIT){
					//do nothing
				}else if (fileInfo.getStatus() == Constants.PROCESS_STATUS_HEAD_DONE_WITHOUT_UNIT) {
					//todo
				}else {
					throw new AnalysisException("未知异常");
				}
				lineNumber--;
				//找到数据起始行
				do{
					lineNumber++;
					if(patternDataLine.matcher(curLine).find()){
						fileInfo.setDataStartLine(lineNumber);
						break;
					}
					pw.println(curLine);
					
					
				}while((curLine = br.readLine())!= null);
				
				lineNumber--;
				do{
					lineNumber++;
					//2.3数据预处理   包括尾部冗余数据处理，realMin，realMax，realAverage计算
					//如果是数据 就预处理
					curLine=preprocessData(columnInfoList,patternDutPassTrue,patternDutPassFalse,curLine);
					
					
					pw.println(curLine);
				}while((curLine = br.readLine())!= null);
				//到这说明 测试项判限都匹配上了
				fileInfo.setLocalFileName(localFileName);
				fileInfo.setStatus(Constants.PROCESS_STATUS_DONE);
				fileInfoList.add(fileInfo);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}catch(TestItemLineNotMatchException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_TESTITEM_NOT_MATCH);
				fileInfo.setMessage("测试项未匹配成功");
			}catch(LimitLineNotMatchException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_LIMIT_NOT_MATCH);
				fileInfo.setMessage("判限未匹配成功");
			}catch(DataNotFoundException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_LIMIT_NOT_MATCH);
				fileInfo.setMessage("未发现测试数据，错误代码："+e.getCode());
			}catch(AnalysisException e){
				fileInfo.setMessage(e.getMessage());
			}
			finally{
				if(pw !=null){
					pw.close();
				}
				if(br!=null){
					br.close();
				}
			}
		}//循环结束
		dataInfo.setFiles(fileInfoList);
		dataInfo.setColumns(columnInfoList);
		return dataInfo;
		
	}
	/**
	 * 数据预处理  按照测试项要求处理当前行
	 * @param columnInfoList 测试项列表
	 * @param curLine 当前行
	 * @return String 处理后的当前行
	 */
	private String preprocessData(List<ColumnInfo> columnInfoList,Pattern passPattern,Pattern failPattern,String curLine) {
		if(columnInfoList==null){
			throw new DataNotFoundException("没有提供测试项信息");
		}
		String[] datas=curLine.split(",");
		int dutPass=dataInfo.getDutPassCol();
		
		if(dutPass >=datas.length){
			return curLine;
		}
		int length=columnInfoList.size();
		
		
		if(passPattern.matcher(curLine).find()){
			//如果是pass的
			for(int i=0;i<length;i++){
				ColumnInfo columnInfo = columnInfoList.get(i);
				String colDataStr=datas[columnInfo.getId()];
				double colData=0.0;
				if(StringUtils.isNotEmpty(colDataStr)){
					colData=Double.parseDouble(colDataStr) ;
				}
				
				long totalCountInLimit=columnInfo.getTotalCountInLimit()+1;
				double totalValue=columnInfo.getTotalValue()+colData;
				double realMin=columnInfo.getRealMinInLimit();
				double realMax=columnInfo.getRealMaxInLimit();
				realMin=colData < realMin ? colData : realMin;
				realMax=colData > realMax ? colData : realMax;
				
				
				columnInfo.setTotalCountInLimit(totalCountInLimit);
				columnInfo.setTotalValue(totalValue);
				columnInfo.setRealMinInLimit(realMin);
				columnInfo.setRealMaxInLimit(realMax);
			}
		}else if(failPattern.matcher(curLine).find()){
			//如果是fail的double limitMin=
			for(int i=0;i<length;i++){
				ColumnInfo columnInfo = columnInfoList.get(i);
				if(datas.length <= columnInfo.getId()){
					break;
				}
				System.out.println("ccccc:"+datas.length+curLine);
				String colDataStr=datas[columnInfo.getId()];
				double colData=0.0;
				
				if(StringUtils.isNotEmpty(colDataStr)){
					colData=Double.parseDouble(colDataStr) ;
				}
				
				double limitMin=columnInfo.getLimitMin();
				double limitMax=columnInfo.getLimitMax();
				//如果 数据在判限内且xia'yi'l<commit_msg>2016-09-20 19:22:54<commit_after>package com.funtest.analysis.dao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import com.funtest.analysis.bean.ColumnInfo;
import com.funtest.analysis.bean.DataConfig;
import com.funtest.analysis.bean.DataInfo;
import com.funtest.analysis.bean.FileInfo;
import com.funtest.analysis.bean.Report;
import com.funtest.analysis.exception.AnalysisException;
import com.funtest.analysis.exception.DataNotFoundException;
import com.funtest.analysis.exception.LimitLineNotMatchException;
import com.funtest.analysis.exception.TestItemLineNotMatchException;
import com.funtest.core.bean.constant.Constants;
import com.google.gson.Gson;

public class ReportBuilder {
	DataInfo dataInfo;
	DataConfig dataConfig;

	/**
	 * 根据ins解析出DataInfo  并删除false数据的多余部分将数据文件保存到本地
	 * @param fileNames 文件名  多个
	 * @param ins		InputStream 多个 与文件名个数相等
	 * @param chipName  芯片名 （可选）
	 * @param mode 		数据处理模式     FT  or  FT&RT
	 * @return DataInfo 包含了生成报告所需的所有信息，如 测试项名称，判限等
	 * @throws IOException 
	 */
	public DataInfo buildDataInfo(String[] fileNames,InputStream[] ins,
										String reportName,String chipName,Integer mode) throws IOException{
		//todo
		//1.非空验证
		if(ins==null ||ins.length ==0){
			throw new AnalysisException("没有提供数据文件~");
		}
		if(StringUtils.isBlank(reportName)){
			throw new AnalysisException("报告名称未指定~");
		}
		if(StringUtils.isBlank(chipName)){
			chipName="undefined";
		}
		if(mode==null){
			mode=Constants.PROCESS_MODE_NORMAL;
		}
		if(fileNames.length != ins.length){
			throw new AnalysisException("文件数量与InputStream数量不一致~");
		}
		
		//2.填充 dataInfo
		DataInfo dataInfo= new DataInfo();
		dataInfo.setReportName(reportName);
		dataInfo.setMode(mode);
		dataInfo.setChipName(chipName);
		this.dataInfo=dataInfo;
		
		//填充
		this.doBuildDataInfo(fileNames, ins);
		
		System.out.println(new Gson().toJson(dataInfo));
		return dataInfo;
		
	}
	
	private DataInfo doBuildDataInfo(String[] fileNames,InputStream[] ins) throws IOException{
		if(dataInfo==null){
			throw new AnalysisException("DataInfo not set");
		}
		if(dataConfig==null){
			throw new AnalysisException("DataConfig not set");
		}
		
		String dir="upload";
		File dirFile=new File(dir);
		if(!dirFile.exists() && !dirFile.isDirectory()){
			dirFile.mkdir();
		}
		
		//各种判断的正则表达式
		Pattern patternDutNoColumn = Pattern.compile(dataConfig.getDutNoColumnFlag());
		Pattern patternSiteNoColumn = Pattern.compile(dataConfig.getSiteNoColumnFlag());
		Pattern patternDutPassColumn = Pattern.compile(dataConfig.getDutPassColumnFlag());
		Pattern patternTestItemColumnFlag = Pattern.compile(dataConfig.getTestItemColumnFlag());
		Pattern patternDutPassTrue = Pattern.compile(dataConfig.getDutPassTrueString());
		Pattern patternDutPassFalse = Pattern.compile(dataConfig.getDutPassFalseString());
		Pattern patternLimitMaxLine = Pattern.compile(dataConfig.getLimitMaxLineFlag());
		Pattern patternLimitMinLine = Pattern.compile(dataConfig.getLimitMinLineFlag());
		Pattern patternLimitLine=Pattern.compile(dataConfig.getLimitMinLineFlag()+"|"+dataConfig.getLimitMaxLineFlag());
		Pattern patternLimitUnitLine=Pattern.compile("^\\D");
		Pattern patternDataLine=Pattern.compile("^\\d");
		
		List<FileInfo> fileInfoList=new ArrayList<FileInfo>();
		List<ColumnInfo> columnInfoList=null;
		
		for(int i=0;i<ins.length;i++){
			//2.1填充FileInfo
			FileInfo fileInfo=new FileInfo();
			fileInfo.setFileName(fileNames[i]);
			
			if(!fileNames[i].endsWith(".csv")){
				//logger.info("{} skipped in createReportSnaps..",fileNames[i]);
				fileInfo.setStatus(Constants.PROCESS_STATUS_ERROR_FORMAT);
				fileInfo.setMessage("不是csv文件");
				fileInfoList.add(fileInfo);
				continue;
			}
			
			long lineNumber=-1;//当前读取的行号
			String curLine=null;//当前行字符串
			BufferedReader br= new BufferedReader(new InputStreamReader(ins[i]));
			String localFileName=dir+"\\"+UUID.randomUUID().toString()+".csv";
			PrintWriter pw=null;
			fileInfo.setStatus(Constants.PROCESS_STATUS_INITIAL_STATE);
			try {
				pw=new PrintWriter( new BufferedWriter(new FileWriter(localFileName)));
				while((curLine = br.readLine() )!= null ){
					pw.println(curLine);
					lineNumber++;
					if(lineNumber >10){
						break;
					}
					System.out.println("line"+(lineNumber)+": "+curLine);
					//匹配测试项所在行成功
					if(patternDutNoColumn.matcher(curLine).find()
							&& patternDutPassColumn.matcher(curLine).find()
							&& patternSiteNoColumn.matcher(curLine).find()
							&& patternTestItemColumnFlag.matcher(curLine).find()){
						//logger.info("测试项所在行："+(lineNumber-1));
						
						//record
						recordTestItemStr(curLine);					
						//开始查找limit
						String limitMinStr=null;
						String limitMaxStr=null;
						while((curLine = br.readLine() )!= null){
							pw.println(curLine);
							lineNumber++;
							if(limitMinStr==null || limitMaxStr==null){
								//匹配limit成功
								if(patternLimitLine.matcher(curLine).find()){
									if(limitMinStr==null 
											&& patternLimitMinLine.matcher(curLine).find()){
										limitMinStr=curLine;
										recordLimitMinStr(curLine);
									}
									if(limitMaxStr== null 
											&& patternLimitMaxLine.matcher(curLine).find()){
										limitMaxStr=curLine;
										recordLimitMaxStr(curLine);
									}
								}
								if(limitMinStr!=null && limitMaxStr !=null){
									
									//看看是否有单位行  此处限定unitLine为Min and Max的下一行
									curLine = br.readLine();
									lineNumber++;
									if(curLine !=null && patternLimitUnitLine.matcher(curLine).find()){
										recordLimitUnitStr(curLine);
										fileInfo.setStatus(Constants.PROCESS_STATUS_HEAD_DONE_WITH_UNIT);
									}else{
										fileInfo.setStatus(Constants.PROCESS_STATUS_HEAD_DONE_WITHOUT_UNIT);
									}
									
									break;//跳出判限查找
								}
							}
						}
						if(curLine==null){
							throw new DataNotFoundException("判限未找到",Constants.PROCESS_STATUS_CANT_FIND_LIMIT);
						}
						if(fileInfo.getStatus()!=Constants.PROCESS_STATUS_INITIAL_STATE){
							break;//跳出测试项查找
						}
					}
				}//循环结束
				if(curLine==null){
					throw new DataNotFoundException("测试项未找到",Constants.PROCESS_STATUS_CANT_FIND_TESTITEM);
				}
				
				//2.2填充ColumnInfo
				columnInfoList = getColumnInfoList(dataConfig);
				//copy剩余部分
				//正常到这的话是刚刚判断了单位行 未保存该行 且lineNumber++了
				if(fileInfo.getStatus() == Constants.PROCESS_STATUS_HEAD_DONE_WITH_UNIT){
					//do nothing
				}else if (fileInfo.getStatus() == Constants.PROCESS_STATUS_HEAD_DONE_WITHOUT_UNIT) {
					//todo
				}else {
					throw new AnalysisException("未知异常");
				}
				lineNumber--;
				//找到数据起始行
				do{
					lineNumber++;
					if(patternDataLine.matcher(curLine).find()){
						fileInfo.setDataStartLine(lineNumber);
						break;
					}
					pw.println(curLine);
					
					
				}while((curLine = br.readLine())!= null);
				
				lineNumber--;
				do{
					lineNumber++;
					//2.3数据预处理   包括尾部冗余数据处理，realMin，realMax，realAverage计算
					//如果是数据 就预处理
					curLine=preprocessData(columnInfoList,patternDutPassTrue,patternDutPassFalse,curLine);
					
					
					pw.println(curLine);
				}while((curLine = br.readLine())!= null);
				//到这说明 测试项判限都匹配上了
				fileInfo.setLocalFileName(localFileName);
				fileInfo.setStatus(Constants.PROCESS_STATUS_DONE);
				fileInfoList.add(fileInfo);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}catch(TestItemLineNotMatchException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_TESTITEM_NOT_MATCH);
				fileInfo.setMessage("测试项未匹配成功");
			}catch(LimitLineNotMatchException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_LIMIT_NOT_MATCH);
				fileInfo.setMessage("判限未匹配成功");
			}catch(DataNotFoundException e){
				fileInfo.setStatus(Constants.PROCESS_STATUS_LIMIT_NOT_MATCH);
				fileInfo.setMessage("未发现测试数据，错误代码："+e.getCode());
			}catch(AnalysisException e){
				fileInfo.setMessage(e.getMessage());
			}
			finally{
				if(pw !=null){
					pw.close();
				}
				if(br!=null){
					br.close();
				}
			}
		}//循环结束
		dataInfo.setFiles(fileInfoList);
		dataInfo.setColumns(columnInfoList);
		return dataInfo;
		
	}
	/**
	 * 数据预处理  按照测试项要求处理当前行
	 * @param columnInfoList 测试项列表
	 * @param curLine 当前行
	 * @return String 处理后的当前行
	 */
	private String preprocessData(List<ColumnInfo> columnInfoList,Pattern passPattern,Pattern failPattern,String curLine) {
		if(columnInfoList==null){
			throw new DataNotFoundException("没有提供测试项信息");
		}
		String[] datas=curLine.split(",");
		int dutPass=dataInfo.getDutPassCol();
		
		if(dutPass >=datas.length){
			return curLine;
		}
		int length=columnInfoList.size();
		
		
		if(passPattern.matcher(curLine).find()){
			//如果是pass的
			for(int i=0;i<length;i++){
				ColumnInfo columnInfo = columnInfoList.get(i);
				String colDataStr=datas[columnInfo.getId()];
				double colData=0.0;
				if(StringUtils.isNotEmpty(colDataStr)){
					colData=Double.parseDouble(colDataStr) ;
				}
				
				long totalCountInLimit=columnInfo.getTotalCountInLimit()+1;
				double totalValue=columnInfo.getTotalValue()+colData;
				double realMin=columnInfo.getRealMinInLimit();
				double realMax=columnInfo.getRealMaxInLimit();
				realMin=colData < realMin ? colData : realMin;
				realMax=colData > realMax ? colData : realMax;
				
				
				columnInfo.setTotalCountInLimit(totalCountInLimit);
				columnInfo.setTotalValue(totalValue);
				columnInfo.setRealMinInLimit(realMin);
				columnInfo.setRealMaxInLimit(realMax);
			}
		}else if(failPattern.matcher(curLine).find()){
			//如果是fail的double limitMin=
			boolean isFailFind=false;
			for(int i=0;i<length;i++){
				ColumnInfo columnInfo = columnInfoList.get(i);
				if(datas.length <= columnInfo.getId()){
					break;
				}
				if(isFailFind){
					datas[columnInfo.getId()]="";
					
				}
				String colDataStr=datas[columnInfo.getId()];
				double colData=0.0;
				
				if(StringUtils.isNotEmpty(colDataStr)){
					colData=Double.parseDouble(colDataStr) ;
				}
				
				double limitMin=columnInfo.getLimitMin();
				double limitMax=columnInfo.getLimitMax();
				//如果 数据在判限内且xia'yi'l
{'fraction_non_alphanumeric': 0.12574300488087758, 'fraction_numerical': 0.0027062291596191947, 'mean_word_length': 3.9061166429587484, 'pattern_counts': {'":': 2, '<': 21, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2400872', 'n_tokens_mistral': 8880, 'n_tokens_neox': 7300, 'n_words': 951}