/// <summary> /// Create instance of PMM /// </summary> /// <param name="settings"></param> /// <param name="startAddress"></param> /// <param name="pageHandlers"></param> internal PersistentMemoryMalloc(LogSettings settings, long startAddress, IPageHandlers pageHandlers) { // Segment size LogSegmentSizeBits = settings.SegmentSizeBits; SegmentSize = 1 << LogSegmentSizeBits; SegmentSizeMask = SegmentSize - 1; SegmentBufferSize = 1 + (LogTotalSizeBytes / SegmentSize < 1 ? 1 : (int)(LogTotalSizeBytes / SegmentSize)); // Total HLOG size LogTotalSizeBits = settings.MemorySizeBits; LogTotalSizeBytes = 1L << LogTotalSizeBits; BufferSize = (int)(LogTotalSizeBytes / (1L << LogPageSizeBits)); // HeadOffset lag (from tail) HeadOffsetLagSize = BufferSize - HeadOffsetLagNumPages; HeadOffsetLagAddress = (long)HeadOffsetLagSize << LogPageSizeBits; // ReadOnlyOffset lag (from tail) LogMutableFraction = settings.MutableFraction; ReadOnlyLagAddress = (long)(LogMutableFraction * BufferSize) << LogPageSizeBits; values = new byte[BufferSize][]; handles = new GCHandle[BufferSize]; pointers = new long[BufferSize]; PageStatusIndicator = new FullPageStatus[BufferSize]; segmentOffsets = new long[SegmentBufferSize]; if (BufferSize < 16) { throw new Exception("HLOG buffer must be at least 16 pages"); } device = settings.LogDevice; objectLogDevice = settings.ObjectLogDevice; if (pageHandlers.HasObjects()) { if (objectLogDevice == null) { throw new Exception("Objects in key/value, but object log not provided during creation of FASTER instance"); } } sectorSize = (int)device.SectorSize; epoch = LightEpoch.Instance; ioBufferPool = NativeSectorAlignedBufferPool.GetPool(1, sectorSize); AlignedPageSizeBytes = ((PageSize + (sectorSize - 1)) & ~(sectorSize - 1)); ptrHandle = GCHandle.Alloc(pointers, GCHandleType.Pinned); nativePointers = (long *)ptrHandle.AddrOfPinnedObject(); Initialize(startAddress); }
private void ClearPage(int page, bool pageZero) { if (pageHandlers.HasObjects()) { long ptr = pointers[page]; int numBytes = PageSize; long endptr = ptr + numBytes; if (pageZero) { ptr += Constants.kFirstValidAddress; } pageHandlers.ClearPage(ptr, endptr); } Array.Clear(values[page], 0, values[page].Length); }