public Task <BufferEntry> Handle(BufferEntry entry) { return(Task.Run(() => { callback(entry); return entry; })); }
public async Task Process(BufferHandler handler) { int started = 0; int registered = 0; Queue <byte[]> memory = new Queue <byte[]>(blockCount + 1); Queue <Task <BufferEntry> > tasks = new Queue <Task <BufferEntry> >(blockCount); BufferBlock[] blocks = new BufferBlock[(source.Length - 1) / blockSize + 1]; void newBlockIfNotExists(int id) { if (blocks.Length > id && blocks[id] == null) { blocks[id] = new BufferBlock { Request = new SemaphoreSlim(0, blocks.Length - id), Ready = new ManualResetEventSlim(false) }; } } void enableBlock(int id, byte[] data, int size) { blocks[id].Data = data; blocks[id].Size = size; blocks[id].Ready.Set(); } async Task <bool> readNextBlock(int id) { byte[] data; if (memory.Count == 0) { data = new byte[blockSize]; } else { data = memory.Dequeue(); } int read = await ReadNext(data).ConfigureAwait(false); if (read == 0) { return(false); } for (int i = 0; i <= 1; i++) { newBlockIfNotExists(id + i); } enableBlock(id, data, read); return(true); } while (true) { if (await readNextBlock(registered++).ConfigureAwait(false) == false) { break; } while (tasks.Count == blockCount) { List <Task> wait = new List <Task> { tasks.Peek() }; if (blocks.Length > registered) { wait.Add(blocks[registered].Request.WaitAsync()); } int index = Task.WaitAny(wait.ToArray()); if (index == 0) { BufferEntry entry = tasks.Dequeue().Result; BufferBlock block = blocks[entry.Id]; //Console.WriteLine($"awaited block {entry.Id}"); blocks[entry.Id] = null; memory.Enqueue(block.Data); block.Request.Dispose(); block.Ready.Dispose(); block.Data = null; } else { //Console.WriteLine($"awaited request"); if (await readNextBlock(registered++).ConfigureAwait(false) == false) { break; } } } //Console.WriteLine($"started block {started}"); tasks.Enqueue(handler.Handle(new BufferEntry(started++, blocks))); } while (started < blocks.Length) { tasks.Enqueue(handler.Handle(new BufferEntry(started++, blocks))); } while (tasks.Count > 0) { await tasks.Dequeue(); } }
private int Handle(BufferEntry entry, XenonHierarchy hierarchy, ref int position) { //Console.WriteLine($"el {position}"); byte value; bool self = false; if (entry.GetByteAt(position++) != '<') { return(-1); } int starting = position; if ((position = XenonScanner.NextElementName(entry, starting)) == -1) { return(-1); } // handle element start int previousId = 0; int owner = hierarchy.Add(starting, position - starting); if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if ((value = entry.GetByteAt(position)) == 0) { return(-1); } int append(int id) { if (previousId == 0) { hierarchy.SetFirst(owner, id); previousId = id; } else { hierarchy.SetNext(previousId, id); previousId = id; } return(id); } int addToHierarchy(int index, int length) { return(append(hierarchy.Add(index, length))); } int contentId = append(hierarchy.Add()); void setContent(int index, int length) { if (contentId != 0) { hierarchy.SetPosition(contentId, index); hierarchy.SetLength(contentId, length); contentId = 0; } else { addToHierarchy(index, length); } } while (value != '/' && value != '>') { starting = position; if ((position = XenonScanner.NextAttributeName(entry, starting)) == -1) { return(-1); } // handle attribute name int nameId = addToHierarchy(starting, position - starting); if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (entry.GetByteAt(position++) != '=') { return(-1); } if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (entry.GetByteAt(position++) != '"') { return(-1); } starting = position; if ((position = XenonScanner.NextAttributeValue(entry, starting)) == -1) { return(-1); } // handle attribute value int valueId = hierarchy.Add(starting, position - starting); hierarchy.SetFirst(nameId, valueId); if (entry.GetByteAt(position++) != '"') { return(-1); } if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if ((value = entry.GetByteAt(position)) == 0) { return(-1); } } if (value == '/') { if ((value = entry.GetByteAt(++position)) == 0) { return(-1); } self = true; } if (value != '>') { return(-1); } if (self == false) { position = position + 1; while (true) { starting = position; if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1) { return(-1); } if (starting == position) { if ((value = entry.GetByteAt(position)) == 0) { return(-1); } if (value == '<') { if ((value = entry.GetByteAt(position + 1)) == 0) { return(-1); } if (value == '/') { starting = position + 2; if ((position = XenonScanner.NextElementName(entry, starting + 2)) == -1) { return(-1); } // handle element end if ((value = entry.GetByteAt(position)) != '>') { return(-1); } //Console.WriteLine($"cl {position}"); return(owner); } if ((starting = Handle(entry, hierarchy, ref position)) == -1) { return(-1); } append(starting); position++; continue; } } if ((position = XenonScanner.NextContent(entry, position)) == -1) { return(-1); } setContent(starting, position - starting); } } return(owner); }
protected XenonNode(int id, BufferEntry entry, XenonHierarchy hierarchy) { this.id = id; this.entry = entry; this.hierarchy = hierarchy; }
public XenonDocument(BufferEntry entry, XenonHierarchy hierarchy) : base(hierarchy.GetFirst(0), entry, hierarchy) { }