/// <summary> /// /// </summary> /// <param name="tid"></param> /// <returns></returns> private static long ReadTagIndex(this DataFileSeriserbase datafile, int tid, out long offset, out short len) { len = datafile.ReadShort(0); var vsize = datafile.ReadInt(2); offset = vsize; lock (TagHeadOffsetManager.manager.LogHeadOffsets) { if (!TagHeadOffsetManager.manager.Contains(datafile.FileName)) { var data = datafile.Read(6, vsize); MarshalVarintCodeMemory vcm = new MarshalVarintCodeMemory(data.StartMemory, vsize); var ltmp = vcm.ToLongList(); int addroffset = (ltmp.Count - 1) / 2; List <int> ids = new List <int>(); List <long> addrs = new List <long>(); long lp = ltmp[1]; for (int i = 1; i < ltmp[0]; i++) { var lp2 = ltmp[i + 1] + lp; ids.Add((int)lp2); lp = lp2; } lp = ltmp[1 + addroffset]; for (int i = 1; i < ltmp[0]; i++) { var lp2 = ltmp[i + 1 + addroffset] + lp; addrs.Add(lp2); lp = lp2; } Dictionary <int, long> idaddrs = new Dictionary <int, long>(); for (int i = 0; i < ids.Count; i++) { idaddrs.Add(ids[i], addrs[i]); } TagHeadOffsetManager.manager.AddLogHead(datafile.FileName, idaddrs); if (idaddrs.ContainsKey(tid)) { return(idaddrs[tid]); } } else { var idaddrs = TagHeadOffsetManager.manager.Get(datafile.FileName); if (idaddrs.ContainsKey(tid)) { return(idaddrs[tid]); } } } return(-1); }
/// <summary> /// /// </summary> /// <param name="memory"></param> /// <returns></returns> public static List <long> ToLongList(this MarshalVarintCodeMemory memory) { List <long> re = new List <long>(); memory.Position = 0; while (memory.Position < memory.Length) { re.Add(memory.ReadInt64()); } return(re); }
/// <summary> /// /// </summary> /// <param name="memory"></param> /// <returns></returns> public static List <int> ToIntList(this MarshalVarintCodeMemory memory) { List <int> re = new List <int>(); memory.Position = 0; while (memory.Position < memory.Length) { re.Add(memory.ReadInt32()); } return(re); }
/// <summary> /// 检测数据头部指针区域数据是否被缓存 /// </summary> /// <param name="datafile"></param> /// <param name="offset"></param> /// <param name="fileDuration"></param> /// <param name="blockDuration"></param> /// <param name="timetick"></param> /// <returns></returns> public static Dictionary <int, int> CheckBlockHeadCach(this DataFileSeriserbase datafile, long offset, out int tagCount, out int fileDuration, out int blockDuration, out int timetick, out long blockPointer, out DateTime time) { //文件头部结构:Pre DataRegion(8) + Next DataRegion(8) + Datatime(8)+tagcount(4)+ tagid sum(8) +file duration(4)+ block duration(4)+Time tick duration(4)+ { + tagid1+tagid2+...+tagidn }+ {[tag1 block point1(8) + tag2 block point1+ tag3 block point1+...] + [tag1 block point2(8) + tag2 block point2+ tag3 block point2+...]....} var dataoffset = offset + 16; //读取时间 time = datafile.ReadDateTime(dataoffset); dataoffset += 8; //读取变量个数 int count = datafile.ReadInt(dataoffset); dataoffset += 4; tagCount = count; //读取校验和 long idsum = datafile.ReadLong(dataoffset); dataoffset += 8; //读取单个文件的时长 fileDuration = datafile.ReadInt(dataoffset); dataoffset += 4; //读取数据块时长 blockDuration = datafile.ReadInt(dataoffset); dataoffset += 4; //读取时钟周期 timetick = datafile.ReadInt(dataoffset); dataoffset += 4; lock (TagHeadOffsetManager.manager) { if (!TagHeadOffsetManager.manager.Contains(idsum, count)) { //Tag id 列表经过压缩,内容格式为:DataSize + Data var dsize = datafile.ReadInt(dataoffset); if (dsize <= 0) { tagCount = 0; fileDuration = 0; blockDuration = 0; timetick = 0; blockPointer = 0; return(new Dictionary <int, int>()); } dataoffset += 4; blockPointer = dataoffset + dsize - offset; var dtmp = new Dictionary <int, int>(); using (var dd = datafile.Read(dataoffset, dsize)) { MarshalVarintCodeMemory vcm = new MarshalVarintCodeMemory(dd.StartMemory, dsize); var ltmp = vcm.ToIntList(); //vcm.Dispose(); if (ltmp.Count > 0) { int preid = ltmp[0]; dtmp.Add(preid, 0); for (int i = 1; i < ltmp.Count; i++) { var id = ltmp[i] + preid; dtmp.Add(id, i); preid = id; } } TagHeadOffsetManager.manager.Add(idsum, count, dtmp, blockPointer); dd.Dispose(); } return(dtmp); } else { var re = TagHeadOffsetManager.manager.Get(idsum, count); blockPointer = re.Item2; return(re.Item1); } } }