public void InitWriteCache(int prealloc = 128) { //Debug.Assert(m_cachedChunks == null, "Error: Cache already initialized"); disabled due to shared storages if (m_cachedChunks != null) { return; } if (OperationsComponent != null) { CachedWrites = true; } else { return; } m_cachedChunks = new MyConcurrentDictionary <Vector3I, VoxelChunk>(prealloc, Vector3I.Comparer); m_pendingChunksToWrite = new MyConcurrentQueue <Vector3I>(prealloc / 10); m_chunksbyAge = new MyQueue <Vector3I>(prealloc); m_cacheMap = new MyDynamicAABBTree(Vector3.Zero); m_cacheLock = new FastResourceLock(); OperationsComponent.Add(this); }
public virtual void CloseInternal() { using (m_storageLock.AcquireExclusiveUsing()) { Closed = true; if (RangeChanged != null) { foreach (var handler in RangeChanged.GetInvocationList()) { RangeChanged -= (RangeChangedDelegate)handler; } } if (DataProvider != null) { DataProvider.Close(); } } if (CachedWrites) { OperationsComponent.Remove(this); } }
public void WriteRange(MyStorageData source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax) { MyPrecalcComponent.AssertUpdateThread(); ProfilerShort.Begin(GetType().Name + ".WriteRange"); try { m_compressedData = null; if (CachedWrites && m_pendingChunksToWrite.Count < WriteCacheCap) { bool enqueued = m_pendingChunksToWrite.Count > 0; var lodDiff = VoxelChunk.SizeBits; var chunkMin = voxelRangeMin >> lodDiff; var chunkMax = voxelRangeMax >> lodDiff; var pos = Vector3I.Zero; for (pos.Z = chunkMin.Z; pos.Z <= chunkMax.Z; ++pos.Z) { for (pos.Y = chunkMin.Y; pos.Y <= chunkMax.Y; ++pos.Y) { for (pos.X = chunkMin.X; pos.X <= chunkMax.X; ++pos.X) { var celPos = pos << lodDiff; var lodCkStart = pos << lodDiff; lodCkStart = Vector3I.Max(lodCkStart, voxelRangeMin); var lodCkEnd = ((pos + 1) << lodDiff) - 1; lodCkEnd = Vector3I.Min(lodCkEnd, voxelRangeMax); var targetOffset = lodCkStart - voxelRangeMin; VoxelChunk chunk; // Do not read the chunk if the range overlaps the whole chunk var toRead = (lodCkEnd - lodCkStart + 1).Size != VoxelChunk.Volume ? dataToWrite : 0; GetChunk(ref pos, out chunk, toRead); lodCkStart -= celPos; lodCkEnd -= celPos; using (chunk.Lock.AcquireExclusiveUsing()) { bool dirty = chunk.Dirty != 0; chunk.Write(source, dataToWrite, ref targetOffset, ref lodCkStart, ref lodCkEnd); if (!dirty) { m_pendingChunksToWrite.Enqueue(pos); } } } } } if (!enqueued) { OperationsComponent.Add(this); } } else { using (m_storageLock.AcquireExclusiveUsing()) WriteRangeInternal(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax); } ProfilerShort.BeginNextBlock(GetType().Name + ".OnRangeChanged"); OnRangeChanged(voxelRangeMin, voxelRangeMax, dataToWrite); } finally { ProfilerShort.End(); } }