protected void SaveItems(SaveMetrics metrics) { Dictionary <Serial, Item> items = World.Items; GenericWriter idx; GenericWriter tdb; GenericWriter bin; if (UseSequentialWriters) { idx = new BinaryFileWriter(World.ItemIndexPath, false); tdb = new BinaryFileWriter(World.ItemTypesPath, false); bin = new BinaryFileWriter(World.ItemDataPath, true); } else { idx = new AsyncWriter(World.ItemIndexPath, false); tdb = new AsyncWriter(World.ItemTypesPath, false); bin = new AsyncWriter(World.ItemDataPath, true); } idx.Write((int)items.Count); DateTime n = DateTime.UtcNow; foreach (Item item in items.Values) { if (item.Decays && item.Parent == null && item.Map != Map.Internal && (item.LastMoved + item.DecayTime) <= n) { _decayQueue.Enqueue(item); } long start = bin.Position; idx.Write((int)item._TypeRef); idx.Write((int)item.Serial); idx.Write((long)start); item.Serialize(bin); if (metrics != null) { metrics.OnItemSaved((int)(bin.Position - start)); } idx.Write((int)(bin.Position - start)); item.FreeCache(); } tdb.Write((int)World._ItemTypes.Count); for (int i = 0; i < World._ItemTypes.Count; ++i) { tdb.Write(World._ItemTypes[i].FullName); } idx.Close(); tdb.Close(); bin.Close(); }
private Task SaveItems() { //Start the blocking consumer; this runs in background. Task commitTask = StartCommitTask(_itemThreadWriters, _itemData, _itemIndex); IEnumerable <Item> items = World.Items.Values; //Start the producer. Parallel.ForEach(items, () => new QueuedMemoryWriter(), (Item item, ParallelLoopState state, QueuedMemoryWriter writer) => { long startPosition = writer.Position; item.Serialize(writer); int size = (int)(writer.Position - startPosition); writer.QueueForIndex(item, size); if (item.Decays && item.Parent == null && item.Map != Map.Internal && DateTime.UtcNow > (item.LastMoved + item.DecayTime)) { _decayBag.Add(item); } if (_metrics != null) { _metrics.OnItemSaved(size); } return(writer); }, (writer) => { writer.Flush(); _itemThreadWriters.Add(writer); }); _itemThreadWriters.CompleteAdding(); //We only get here after the Parallel.ForEach completes. Lets our task return(commitTask); }