/// <summary> /// 状态数据创建器 /// </summary> /// <param name="values">状态集合</param> public TmphByteArrayBuilder(TmphKeyValue<byte[], int>[] values) { this.values = values; prefixSize = tableCount = stateCount = tableType = charCount = 0; state = charsAscii = prefix = table = null; if (values.Length > 1) { byte* chars = stackalloc byte[128 >> 3]; this.chars = new TmphFixedMap(chars, 128 >> 3, 0); Data = new TmphPointer(); count(0, values.Length, 0); for (byte* start = chars, end = chars + (128 >> 3); start != end; start += sizeof(int)) { charCount += (*(uint*)start).bitCount(); } var size = (1 + (stateCount += tableCount) * 3) * sizeof(int) + 128 + 4 + (prefixSize & (int.MaxValue - 3)); if (stateCount < 256) size += tableCount * (charCount + 1); else if (stateCount < 65536) { size += tableCount * (charCount + 1) * sizeof(ushort); tableType = 1; } else { size += tableCount * (charCount + 1) * sizeof(int); tableType = 2; } Data = TmphUnmanaged.Get(size, true); *Data.Int = stateCount; //状态数量[int] state = Data.Byte + sizeof(int); //状态集合[stateCount*(前缀位置[int]+状态位置[int]+名称索引[int])] charsAscii = state + (stateCount * 3) * sizeof(int); //ascii字符查找表[128*byte] byte charIndex = 0; for (byte index = 1; index != 128; ++index) { if (this.chars.Get(index)) *(charsAscii + index) = ++charIndex; } prefix = charsAscii + 128; //前缀集合 table = prefix + ((prefixSize & (int.MaxValue - 3)) + 4); //状态矩阵[tableCount*(charCount+1)*[byte/ushort/int]] *prefix++ = (byte)charCount; //字符数量 stateCount = 0; create(0, values.Length, 0); } else { chars = new TmphFixedMap(); var value = values[0].Key; fixed (byte* valueFixed = value) { if (values[0].Key.Length <= 128) { Data = TmphUnmanaged.Get(sizeof(int) + sizeof(int) * 3 + 128 + 1, false); *Data.Int = 1; //状态数量 state = Data.Byte + sizeof(int); *(int*)state = sizeof(int) * 3; //前缀位置 *(int*)(state + sizeof(int)) = 0; //状态位置 *(int*)(state + sizeof(int) * 2) = values[0].Value; //名称索引 prefix = Data.Byte + sizeof(int) * 4; Unsafe.TmphMemory.Copy(valueFixed, prefix, value.Length); *(prefix + value.Length) = *(prefix + 128) = 0; } else { Data = TmphUnmanaged.Get(sizeof(int) + sizeof(int) * 3 + 128 + 1 + value.Length + 1, true); *Data.Int = 1; //状态数量 state = Data.Byte + sizeof(int); *(int*)state = sizeof(int) * 3 + 128 + 1; //前缀位置 *(int*)(state + sizeof(int)) = 0; //状态位置 *(int*)(state + sizeof(int) * 2) = values[0].Value; //名称索引 Unsafe.TmphMemory.Copy(valueFixed, Data.Byte + sizeof(int) * 3 + 128 + 1, value.Length); } } } }
public unsafe static string toRegex(this string value) { if (value == null || value.Length == 0) { fixed (char* valueFixed = value) { char* end = valueFixed + value.Length; int count = Unsafe.TmphString.AsciiCount(valueFixed, end, regexEscapeMap.Byte, RegexEscape[0]); if (count != 0) { TmphFixedMap map = new TmphFixedMap(regexEscapeMap); value = Laurent.Lee.CLB.TmphString.FastAllocateString(count += value.Length); fixed (char* writeFixed = value) { for (char* start = valueFixed, write = writeFixed; start != end; *write++ = *start++) { if ((*start & 0xff80) == 0 && map.Get(*start)) *write++ = '\\'; } } } } } return value; }
/// <summary> /// 状态数据创建器 /// </summary> /// <param name="values">状态集合</param> public TmphBuilder(TmphKeyValue<byte[], int>[] values) { this.values = values; prefixSize = tableCount = stateCount = tableType = charCount = 0; state = bytes = nullPrefix = prefix = table = null; if (values.Length > 1) { byte* chars = stackalloc byte[256 >> 3]; this.chars = new TmphFixedMap(chars, 256 >> 3, 0); Data = new TmphPointer(); count(0, values.Length, 0); for (byte* start = chars, end = chars + (256 >> 3); start != end; start += sizeof(int)) { charCount += (*(uint*)start).bitCount(); } var size = (1 + (stateCount += tableCount) * 3) * sizeof(int) + 256 + 4 + ((prefixSize + 3) & (int.MaxValue - 3)); if (stateCount < 256) size += tableCount * charCount; else if (stateCount < 65536) { size += tableCount * charCount * sizeof(ushort); tableType = 1; } else { size += tableCount * charCount * sizeof(int); tableType = 2; } Data = TmphUnmanaged.Get(size, true); *Data.Int = stateCount; //状态数量[int] state = Data.Byte + sizeof(int); //状态集合[stateCount*(前缀位置[int]+状态位置[int]+名称索引[int])] bytes = state + (stateCount * 3) * sizeof(int); //字节查找表[256*byte] byte charIndex = 0; for (var index = 0; index != 256; ++index) { if (this.chars.Get(index)) *(bytes + index) = charIndex++; } nullPrefix = bytes + 256; //空前缀 table = nullPrefix + (((prefixSize + 3) & (int.MaxValue - 3)) + 4); //状态矩阵[tableCount*charCount*[byte/ushort/int]] *(ushort*)nullPrefix = (ushort)charCount; //字符数量 prefix = nullPrefix + sizeof(int) + sizeof(ushort); //前缀集合 nullPrefix += sizeof(int); stateCount = 0; create(0, values.Length, 0); } else { chars = new TmphFixedMap(); var value = values[0].Key; fixed (byte* valueFixed = value) { if (values[0].Key.Length <= 254) { Data = TmphUnmanaged.Get(sizeof(int) + sizeof(int) * 3 + 256 + 2, false); *Data.Int = 1; //状态数量 state = Data.Byte + sizeof(int); *(int*)state = sizeof(int) * 3 + sizeof(ushort); //前缀位置 *(int*)(state + sizeof(int)) = 0; //状态位置 *(int*)(state + sizeof(int) * 2) = values[0].Value; //名称索引 prefix = Data.Byte + sizeof(int) * 4; *(ushort*)prefix = (ushort)value.Length; Unsafe.TmphMemory.Copy(valueFixed, prefix + sizeof(ushort), value.Length); *(ushort*)(prefix + 256) = 0; } else { Data = TmphUnmanaged.Get(sizeof(int) + sizeof(int) * 3 + 256 + 4 + 2 + value.Length, true); *Data.Int = 1; //状态数量 state = Data.Byte + sizeof(int); *(int*)state = sizeof(int) * 3 + 256 + 4 + sizeof(ushort); //前缀位置 *(int*)(state + sizeof(int)) = 0; //状态位置 *(int*)(state + sizeof(int) * 2) = values[0].Value; //名称索引 prefix = Data.Byte + sizeof(int) * 4 + 256 + 4; *(ushort*)prefix = (ushort)value.Length; Unsafe.TmphMemory.Copy(valueFixed, prefix + sizeof(ushort), value.Length); } } } }