/// <summary>Allocate a new page for a specific bucket</summary> /// <param name="bucket">Bucet index</param> protected TPage CreateNewPage(int bucket) { uint size = m_buckets[bucket].PageSize; UnmanagedHelpers.SafeLocalAllocHandle handle = null; try { handle = UnmanagedHelpers.AllocMemory(size); return(m_allocator(handle, size)); } catch (Exception e) { if (handle != null) { if (!handle.IsClosed) { handle.Dispose(); } handle = null; } if (e is OutOfMemoryException) { throw new OutOfMemoryException(String.Format("Failed to allocate new memory for new page of size {0}", size), e); } throw; } finally { if (handle != null) { GC.AddMemoryPressure(size); } } }
private unsafe USlice Store(Slice data) { uint size = checked ((uint)data.Count); var buffer = m_keys.AllocateAligned(size); UnmanagedHelpers.CopyUnsafe(buffer, data); return(new USlice(buffer, size)); }
private IEnumerable <Window> GetTrayWindows() { var trayWindows = UnmanagedHelpers.FilterWindows((hWnd) => { var window = new Window(hWnd); var isTrayWindow = window.ClassName == "Shell_TrayWnd" || window.ClassName == "Shell_SecondaryTrayWnd"; return(isTrayWindow && Screen.FromHandle(hWnd).Bounds == _screen.Bounds); }); return(trayWindows.Select(hWnd => new Window(hWnd))); }
/// <summary>Copy an existing value to this page, and return the pointer to the copy</summary> /// <param name="value">Value that must be copied to this page</param> /// <returns>Pointer to the copy in this page</returns> public Value *TryAppend(Value *value) { Contract.Requires(value != null && Entry.GetObjectType(value) == EntryType.Value); uint rawSize = Value.SizeOf + value->Size; Value *entry = (Value *)TryAllocate(rawSize); if (entry == null) { return(null); // the page is full } UnmanagedHelpers.CopyUnsafe((byte *)entry, (byte *)value, rawSize); return(entry); }
public Value *TryAppend(USlice buffer) { Contract.Requires(buffer.Data != null && buffer.Count >= Value.SizeOf && ((Key *)buffer.Data)->Size == buffer.Count - Value.SizeOf); var entry = (Value *)TryAllocate(buffer.Count); if (entry == null) { return(null); // the page is full } UnmanagedHelpers.CopyUnsafe((byte *)entry, buffer.Data, buffer.Count); return(entry); }
public Key *TryAppend(USlice buffer) { Contract.Requires(buffer.Data != null && buffer.Count >= Key.SizeOf && ((Key *)buffer.Data)->Size == buffer.Count - Key.SizeOf); var entry = (Key *)TryAllocate(buffer.Count); if (entry == null) { return(null); // this page is full } UnmanagedHelpers.CopyUnsafe((byte *)entry, buffer.Data, buffer.Count); entry->Header = ((ushort)EntryType.Key) << Entry.TYPE_SHIFT; return(entry); }
public unsafe void Add(ulong sequence, USlice userKey, USlice userValue) { // allocate the key var tmp = MemoryDatabaseHandler.PackUserKey(m_scratch, userKey); Key *key = m_keys.Append(tmp); Contract.Assert(key != null, "key == null"); // allocate the value uint size = userValue.Count; Value *value = m_values.Allocate(size, sequence, null, key); Contract.Assert(value != null, "value == null"); UnmanagedHelpers.CopyUnsafe(&(value->Data), userValue); key->Values = value; m_list.Add(new IntPtr(key)); }
public void ReadHeader(CancellationToken ct) { ct.ThrowIfCancellationRequested(); // minimum header prolog size is 64 but most will only a single page // we can preallocate a full page, and we will resize it later if needed var reader = m_file.CreateReader(0, SnapshotFormat.HEADER_METADATA_BYTES); // "PNDB" var signature = reader.ReadFixed32(); // v1.0 uint major = reader.ReadFixed16(); uint minor = reader.ReadFixed16(); m_version = new Version((int)major, (int)minor); // FLAGS m_dbFlags = (SnapshotFormat.Flags)reader.ReadFixed64(); // Database ID m_uid = new Uuid128(reader.ReadBytes(16).GetBytes()); // Database Version m_sequence = reader.ReadFixed64(); // Number of items in the database m_itemCount = checked ((long)reader.ReadFixed64()); // Database Timestamp m_timestamp = reader.ReadFixed64(); // Page Size m_pageSize = reader.ReadFixed32(); // Header Size m_headerSize = reader.ReadFixed32(); Contract.Assert(!reader.HasMore); #region Sanity checks // Signature if (signature != SnapshotFormat.HEADER_MAGIC_NUMBER) { throw ParseError("Invalid magic number"); } // Version if (m_version.Major != 1) { throw ParseError("Unsupported file version (major)"); } if (m_version.Minor > 0) { throw ParseError("Unsupported file version (minor)"); } // Flags // Page Size if (m_pageSize != UnmanagedHelpers.NextPowerOfTwo(m_pageSize)) { throw ParseError("Page size ({0}) is not a power of two", m_pageSize); } if (m_pageSize < SnapshotFormat.HEADER_METADATA_BYTES) { throw ParseError("Page size ({0}) is too small", m_pageSize); } if (m_pageSize > 1 << 20) { throw ParseError("Page size ({0}) is too big", m_pageSize); } // Header Size if (m_headerSize < 64 + 4 + 4) { throw ParseError("Header size ({0}) is too small", m_headerSize); } if (m_headerSize > m_file.Length) { throw ParseError("Header size is bigger than the file itself ({0} < {1})", m_headerSize, m_file.Length); } if (m_headerSize > 1 << 10) { throw ParseError("Header size ({0}) exceeds the maximum allowed size", m_headerSize); } #endregion // we know the page size and header size, read the rest... // read the rest reader = m_file.CreateReader(0, m_headerSize); reader.Skip(SnapshotFormat.HEADER_METADATA_BYTES); // parse the attributes Contract.Assert(reader.Offset == SnapshotFormat.HEADER_METADATA_BYTES); var attributeCount = checked ((int)reader.ReadFixed32()); if (attributeCount < 0 || attributeCount > 1024) { throw ParseError("Attributes count is invalid"); } var attributes = new Dictionary <string, IFdbTuple>(attributeCount); for (int i = 0; i < attributeCount; i++) { var name = reader.ReadVarbytes().ToSlice(); //TODO: max size ? if (name.IsNullOrEmpty) { throw ParseError("Header attribute name is empty"); } var data = reader.ReadVarbytes().ToSlice(); //TODO: max size + have a small scratch pad buffer for these ? var value = FdbTuple.Unpack(data); attributes.Add(name.ToUnicode(), value); } m_attributes = attributes; // read the header en marker var marker = reader.ReadFixed32(); if (marker != uint.MaxValue) { throw ParseError("Header end marker is invalid"); } // verify the header checksum uint actualHeaderChecksum = SnapshotFormat.ComputeChecksum(reader.Base, reader.Offset); uint headerChecksum = reader.ReadFixed32(); m_headerChecksum = headerChecksum; if (headerChecksum != actualHeaderChecksum) { throw ParseError("The header checksum does not match ({0} != {1}). This may be an indication of data corruption", headerChecksum, actualHeaderChecksum); } m_dataStart = RoundUp(m_headerSize, m_pageSize); m_hasHeader = true; }
private static IEnumerable <Window> GetTaskbarWindows() { var trayWindows = UnmanagedHelpers.FilterWindows(IsAltTabWindow); return(trayWindows.Select(hWnd => new Window(hWnd))); }