/// <summary> /// append data /// </summary> /// <typeparam name="T"></typeparam> /// <param name="signalId"></param> /// <param name="dim"></param> /// <param name="samples"></param> /// <param name="createNewSEPayload"></param> /// <returns></returns> public async Task AppendSampleAsync <T>(Guid signalId, List <long> dim, List <T> samples, bool createNewSEPayload = false) { //review cassandra的se是不是不管怎样都create new payload? 是的 //存在Signal,找到子节点满足 父节点Id=signal,dimension=dim string dimension = DimensionsToText(dim); var ms = new MemoryStream(); Serializer.Serialize(ms, samples); byte[] result = ms.ToArray(); SEPayload lastPayload = (await mapper.FetchAsync <SEPayload>("SELECT * FROM sepayload where parentid=? and dimensions=?", signalId, dimension)).LastOrDefault(); long start = 0, end = -1; //review todo 这里还是有读取 if (lastPayload != null) { start = lastPayload.start; end = lastPayload.end; } SEPayload newPayload = new SEPayload(); newPayload.parentid = signalId; newPayload.start = end + 1; newPayload.end = end + samples.Count(); newPayload.samples = result; newPayload.dimensions = dimension; await mapper.InsertAsync <SEPayload>(newPayload); }
/// <summary> /// return the dimensions of the signal /// </summary> /// <param name="signalId">signal id, only applis to signal</param> /// <returns>the dimension of the signal, hi rank dimension comes in first in the list</returns> public async Task <List <long> > GetDimentionsAsync(Guid signalId) { //var filter = Builders<SEPayload>.Filter.Eq("ParentId", signalId); //var cursor = await collectionSEPayload.FindAsync(filter); //await cursor.MoveNextAsync(); //var tm = (SEPayload)cursor.Current.FirstOrDefault(); //return tm.Dimensions; var builder = Builders <SEPayload> .Filter; var filter = new List <FilterDefinition <SEPayload> >(); filter.Add(builder.Eq("ParentId", signalId)); filter.Add(builder.Eq("Dimensions", "")); var sot = Builders <SEPayload> .Sort.Descending("End"); var options = new FindOptions <SEPayload, SEPayload> { Sort = sot, Limit = 1 }; using (var cursor = await collectionSEPayload.FindAsync(builder.And(filter), options)) { await cursor.MoveNextAsync(); SEPayload endSEPayload = (SEPayload)cursor.Current.FirstOrDefault(); } return(null); }
/* * public async Task<List<MatrixStorageEngine.Models.SESampleAppendResult>> AppendSampleAsync<T>(Guid signalId, List<long> dim, List<T> samples, bool createNewSEPayload = false) * { * List<SESampleAppendResult> listResult = new List<SESampleAppendResult>(); * //存在Signal,找到子节点满足 父节点Id=signal,dimension=dim * var builder = Builders<SEPayload>.Filter; * var filter = new List<FilterDefinition<SEPayload>>(); * filter.Add(builder.Eq("ParentId", signalId)); * filter.Add(builder.Eq("Dimensions", dim)); * var sot = Builders<SEPayload>.Sort.Descending("End"); * var options = new FindOptions<SEPayload, SEPayload<T>> { Sort = sot, Limit = 1 }; * using (var cursor = await collectionSEPayload.FindAsync(builder.And(filter), options)) * { * await cursor.MoveNextAsync(); * if (cursor.Current.Count() == 0) * { * //没有这样的SEPayload,不管createNewSEPayload是不是真,都要创建一个新的SEPayload, * //创建新的SEPayload时,是否会超出范围 * await CreateNewPayloadAsync<T>(signalId, dim, samples, listResult); * } * else * { * // 有这样的SEPayload,createNewSEPayload为真时,直接创建;为假时,先接上再创建 * SEPayload<T> endSEPayload = (SEPayload<T>)cursor.Current.FirstOrDefault(); * if (createNewSEPayload == true) * { * await CreateNewPayloadAsync<T>(signalId, dim, samples, listResult, endSEPayload.End + 1); * } * else * { * bool flag = false; * try * { * var end = endSEPayload.End + samples.Count(); * var up = Builders<SEPayload>.Update.PushEach("Samples", samples).Set("End", end); * var endfilter = Builders<SEPayload>.Filter.Eq("Id", endSEPayload.Id); * await collectionSEPayload.UpdateOneAsync(endfilter, up); * SESampleAppendResult res = new SESampleAppendResult(endSEPayload.Id, samples.Count()); * listResult.Add(res); * flag = false; * } * catch (MongoWriteException) * { * flag = true; * } * if (flag) * { * await CreateNewPayloadAsync<T>(signalId, dim, samples, listResult, endSEPayload.End + 1); * } * } * } * } * return listResult; * } */ private async Task CreateNewPayloadAsync <T>(Guid signalId, List <long> dim, List <T> samples, List <SESampleAppendResult> listResult, long start = 0) { Stack <List <T> > stack = new Stack <List <T> >(); stack.Push(samples); long startIndex = start; while (stack.Count() > 0) { List <T> write = stack.Pop(); var SEPayload1 = new SEPayload <T>(); SEPayload1.ParentId = signalId; SEPayload1.Dimensions = dim; SEPayload1.Start = startIndex; long end = startIndex + write.Count() - 1; SEPayload1.End = end; SEPayload1.Samples.AddRange(write); try { await collectionSEPayload.InsertOneAsync(SEPayload1); startIndex = end; SESampleAppendResult res = new SESampleAppendResult(SEPayload1.Id, write.Count()); listResult.Add(res); } catch (MongoWriteException) { Int32 indexcount = write.Count() / 2; var later = write.GetRange(0, indexcount); write.RemoveRange(0, indexcount); stack.Push(write); stack.Push(later); } } }
/// <summary> /// get a SEPayload entity by its id /// </summary> /// <param name="id">SEPayload id</param> /// <returns></returns> public async Task <SEPayload <T> > GetPayloadByIdAsync <T>(Guid id) { IFindFluent <SEPayload, SEPayload> findFluent = (collectionSEPayload.Find <SEPayload>(x => x.Id == id)); SEPayload <T> entity = (SEPayload <T>)(await findFluent.FirstOrDefaultAsync()); return(entity); }
//review 这个这么重要,也没注释,payload, dim这些关系我忘的差不多了也没个文档。我相信有一天你也会忘得差不多的。。到时候没法再改了 public async Task AppendSampleAsync <T>(Guid signalId, List <long> dim, List <T> samples, bool createNewSEPayload = false) { //存在Signal,找到子节点满足 父节点Id=signal,dimension=dim var builder = Builders <SEPayload> .Filter; var filter = new List <FilterDefinition <SEPayload> >(); filter.Add(builder.Eq("ParentId", signalId)); filter.Add(builder.Eq("Dimensions", dim)); var sot = Builders <SEPayload> .Sort.Descending("End"); var options = new FindOptions <SEPayload, SEPayload <T> > { Sort = sot, Limit = 1 }; //review todo 每次append的时候还要读取,是这样的,append时读取时非常影响吸能的,如果可以避免一定要避免 using (var cursor = await collectionSEPayload.FindAsync(builder.And(filter), options)) { await cursor.MoveNextAsync(); if (cursor.Current.Count() == 0) { //没有这样的SEPayload,不管createNewSEPayload是不是真,都要创建一个新的SEPayload, //创建新的SEPayload时,是否会超出范围 await CreateNewPayloadAsync <T>(signalId, dim, samples, null); } else { // 有这样的SEPayload,createNewSEPayload为真时,直接创建;为假时,先接上再创建 SEPayload <T> endSEPayload = (SEPayload <T>)cursor.Current.FirstOrDefault(); if (createNewSEPayload == true) { await CreateNewPayloadAsync <T>(signalId, dim, samples, null, endSEPayload.End + 1); } else { bool flag = false; try { var end = endSEPayload.End + samples.Count(); var up = Builders <SEPayload> .Update.PushEach("Samples", samples).Set("End", end); var endfilter = Builders <SEPayload> .Filter.Eq("Id", endSEPayload.Id); await collectionSEPayload.UpdateOneAsync(endfilter, up); flag = false; } catch (MongoWriteException) { flag = true; } if (flag) { await CreateNewPayloadAsync <T>(signalId, dim, samples, null, endSEPayload.End + 1); } } } } }
/// <summary> /// 自定义Start和End写入数据 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="signalId"></param> /// <param name="dim"></param> /// <param name="samples"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="createNewSEPayload"></param> /// <returns></returns> public async Task AppendSampleAsync <T>(Guid signalId, List <long> dim, List <T> samples, long start, long end, bool createNewSEPayload = false) { //存在Signal,找到子节点满足 父节点Id=signal,dimension=dim string dimension = DimensionsToText(dim); var ms = new MemoryStream(); List <Byte> by = new List <byte>(); Serializer.Serialize(ms, samples); byte[] result = ms.ToArray(); SEPayload newPayload = new SEPayload(); newPayload.parentid = signalId; newPayload.start = start; newPayload.end = end; newPayload.samples = result; newPayload.dimensions = dimension; await mapper.InsertAsync <SEPayload>(newPayload); }