//-----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation.
//
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Windows10
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
///
/// Contains cumulative statistics on the work performed by the database
/// engine on the current thread. This information is returned via
/// JetGetThreadStats.
///
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1300:ElementMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[Serializable]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
public struct JET_THREADSTATS2 : IEquatable
{
///
/// The size of a JET_THREADSTATS2 structure.
///
internal static readonly int Size = Marshal.SizeOf(typeof(JET_THREADSTATS2));
///
/// Size of the structure. This is used for interop.
///
private readonly int cbStruct;
///
/// Number of pages visited.
///
private int pagesReferenced;
///
/// Number of pages read from disk.
///
private int pagesRead;
///
/// Number of pages preread.
///
private int pagesPreread;
///
/// Number of pages dirtied.
///
private int pagesDirtied;
///
/// Pages redirtied.
///
private int pagesRedirtied;
///
/// Number of log records generated.
///
private int numLogRecords;
///
/// Number of bytes logged.
///
private int loggedBytes;
///
/// Elapsed time for pages cache missed in microseconds.
///
private long usecsCacheMisses;
///
/// Number of pages cache missed.
///
private int pagesCacheMisses;
///
/// Gets the total number of database pages visited by the database
/// engine on the current thread.
///
public int cPageReferenced
{
[DebuggerStepThrough]
get { return this.pagesReferenced; }
internal set { this.pagesReferenced = value; }
}
///
/// Gets the total number of database pages fetched from disk by the
/// database engine on the current thread.
///
public int cPageRead
{
[DebuggerStepThrough]
get { return this.pagesRead; }
internal set { this.pagesRead = value; }
}
///
/// Gets the total number of database pages prefetched from disk by
/// the database engine on the current thread.
///
public int cPagePreread
{
[DebuggerStepThrough]
get { return this.pagesPreread; }
internal set { this.pagesPreread = value; }
}
///
/// Gets the total number of database pages, with no unwritten changes,
/// that have been modified by the database engine on the current thread.
///
public int cPageDirtied
{
[DebuggerStepThrough]
get { return this.pagesDirtied; }
internal set { this.pagesDirtied = value; }
}
///
/// Gets the total number of database pages, with unwritten changes, that
/// have been modified by the database engine on the current thread.
///
public int cPageRedirtied
{
[DebuggerStepThrough]
get { return this.pagesRedirtied; }
internal set { this.pagesRedirtied = value; }
}
///
/// Gets the total number of transaction log records that have been
/// generated by the database engine on the current thread.
///
public int cLogRecord
{
[DebuggerStepThrough]
get { return this.numLogRecords; }
internal set { this.numLogRecords = value; }
}
///
/// Gets the total size, in bytes, of transaction log records that
/// have been generated by the database engine on the current thread.
///
public int cbLogRecord
{
[DebuggerStepThrough]
get { return this.loggedBytes; }
internal set { this.loggedBytes = value; }
}
///
/// Gets the cumulative latency, in microseconds, of cache misses experienced by
/// this thread.
///
public long cusecPageCacheMiss
{
[DebuggerStepThrough]
get { return this.usecsCacheMisses; }
internal set { this.usecsCacheMisses = value; }
}
///
/// Gets the cumulative count of cache misses experienced by the thread.
///
public int cPageCacheMiss
{
[DebuggerStepThrough]
get { return this.pagesCacheMisses; }
internal set { this.pagesCacheMisses = value; }
}
///
/// Create a new struct with the specified
/// valued.
///
///
/// Number of pages visited.
///
///
/// Number of pages read.
///
///
/// Number of pages preread.
///
///
/// TNumber of pages dirtied.
///
///
/// Number of pages redirtied.
///
///
/// Number of log records generated.
///
///
/// Bytes of log records written.
///
///
/// Elapsed time for pages cache missed in microseconds.
///
///
/// Number of pages cache missed.
///
///
/// A new struct with the specified values.
///
public static JET_THREADSTATS2 Create(
int cPageReferenced,
int cPageRead,
int cPagePreread,
int cPageDirtied,
int cPageRedirtied,
int cLogRecord,
int cbLogRecord,
long cusecPageCacheMiss,
int cPageCacheMiss)
{
return new JET_THREADSTATS2
{
cPageReferenced = cPageReferenced,
cPageRead = cPageRead,
cPagePreread = cPagePreread,
cPageDirtied = cPageDirtied,
cPageRedirtied = cPageRedirtied,
cLogRecord = cLogRecord,
cbLogRecord = cbLogRecord,
cusecPageCacheMiss = cusecPageCacheMiss,
cPageCacheMiss = cPageCacheMiss,
};
}
///
/// Add the stats in two JET_THREADSTATS2 structures.
///
/// The first JET_THREADSTATS2.
/// The second JET_THREADSTATS2.
/// A JET_THREADSTATS2 containing the result of adding the stats in t1 and t2.
public static JET_THREADSTATS2 Add(JET_THREADSTATS2 t1, JET_THREADSTATS2 t2)
{
unchecked
{
return new JET_THREADSTATS2
{
cPageReferenced = t1.cPageReferenced + t2.cPageReferenced,
cPageRead = t1.cPageRead + t2.cPageRead,
cPagePreread = t1.cPagePreread + t2.cPagePreread,
cPageDirtied = t1.cPageDirtied + t2.cPageDirtied,
cPageRedirtied = t1.cPageRedirtied + t2.cPageRedirtied,
cLogRecord = t1.cLogRecord + t2.cLogRecord,
cbLogRecord = t1.cbLogRecord + t2.cbLogRecord,
cusecPageCacheMiss = t1.cusecPageCacheMiss + t2.cusecPageCacheMiss,
cPageCacheMiss = t1.cPageCacheMiss + t2.cPageCacheMiss,
};
}
}
///
/// Add the stats in two JET_THREADSTATS2 structures.
///
/// The first JET_THREADSTATS2.
/// The second JET_THREADSTATS2.
/// A JET_THREADSTATS2 containing the result of adding the stats in t1 and t2.
public static JET_THREADSTATS2 operator +(JET_THREADSTATS2 t1, JET_THREADSTATS2 t2)
{
return Add(t1, t2);
}
///
/// Calculate the difference in stats between two JET_THREADSTATS2 structures.
///
/// The first JET_THREADSTATS2.
/// The second JET_THREADSTATS2.
/// A JET_THREADSTATS2 containing the difference in stats between t1 and t2.
public static JET_THREADSTATS2 Subtract(JET_THREADSTATS2 t1, JET_THREADSTATS2 t2)
{
unchecked
{
return new JET_THREADSTATS2
{
cPageReferenced = t1.cPageReferenced - t2.cPageReferenced,
cPageRead = t1.cPageRead - t2.cPageRead,
cPagePreread = t1.cPagePreread - t2.cPagePreread,
cPageDirtied = t1.cPageDirtied - t2.cPageDirtied,
cPageRedirtied = t1.cPageRedirtied - t2.cPageRedirtied,
cLogRecord = t1.cLogRecord - t2.cLogRecord,
cbLogRecord = t1.cbLogRecord - t2.cbLogRecord,
cusecPageCacheMiss = t1.cusecPageCacheMiss - t2.cusecPageCacheMiss,
cPageCacheMiss = t1.cPageCacheMiss - t2.cPageCacheMiss,
};
}
}
///
/// Calculate the difference in stats between two JET_THREADSTATS2 structures.
///
/// The first JET_THREADSTATS2.
/// The second JET_THREADSTATS2.
/// A JET_THREADSTATS2 containing the difference in stats between t1 and t2.
public static JET_THREADSTATS2 operator -(JET_THREADSTATS2 t1, JET_THREADSTATS2 t2)
{
return Subtract(t1, t2);
}
///
/// Determines whether two specified instances of JET_THREADSTATS2
/// are equal.
///
/// The first instance to compare.
/// The second instance to compare.
/// True if the two instances are equal.
public static bool operator ==(JET_THREADSTATS2 lhs, JET_THREADSTATS2 rhs)
{
return lhs.Equals(rhs);
}
///
/// Determines whether two specified instances of JET_THREADSTATS2
/// are not equal.
///
/// The first instance to compare.
/// The second instance to compare.
/// True if the two instances are not equal.
public static bool operator !=(JET_THREADSTATS2 lhs, JET_THREADSTATS2 rhs)
{
return !(lhs == rhs);
}
///
/// Gets a string representation of this object.
///
/// A string representation of this object.
public override string ToString()
{
// String.Concat is faster than using a StringBuilder.
// use Int32.ToString instead of passing the Int32 to
// String.Format (which requires boxing).
return string.Concat(
this.cPageReferenced.ToString("N0", CultureInfo.InvariantCulture),
" page reference",
GetPluralS(this.cPageReferenced),
", ",
this.cPageRead.ToString("N0", CultureInfo.InvariantCulture),
" page",
GetPluralS(this.cPageRead),
" read, ",
this.cPagePreread.ToString("N0", CultureInfo.InvariantCulture),
" page",
GetPluralS(this.cPagePreread),
" preread, ",
this.cPageDirtied.ToString("N0", CultureInfo.InvariantCulture),
" page",
GetPluralS(this.cPageDirtied),
" dirtied, ",
this.cPageRedirtied.ToString("N0", CultureInfo.InvariantCulture),
" page",
GetPluralS(this.cPageRedirtied),
" redirtied, ",
this.cLogRecord.ToString("N0", CultureInfo.InvariantCulture),
" log record",
GetPluralS(this.cLogRecord),
", ",
this.cbLogRecord.ToString("N0", CultureInfo.InvariantCulture),
" byte",
GetPluralS(this.cbLogRecord),
" logged",
", ",
this.cusecPageCacheMiss.ToString("N0", CultureInfo.InvariantCulture),
" page cache miss latency (us)",
", ",
this.cPageCacheMiss.ToString("N0", CultureInfo.InvariantCulture),
" page cache miss count");
}
///
/// Returns a value indicating whether this instance is equal
/// to another instance.
///
/// An object to compare with this instance.
/// True if the two instances are equal.
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return this.Equals((JET_THREADSTATS2)obj);
}
///
/// Returns the hash code for this instance.
///
/// The hash code for this instance.
public override int GetHashCode()
{
return this.cPageReferenced
^ this.cPageRead << 1
^ this.cPagePreread << 2
^ this.cPageDirtied << 3
^ this.cPageRedirtied << 4
^ this.cLogRecord << 5
^ this.cbLogRecord << 6
^ this.cusecPageCacheMiss.GetHashCode() << 7
^ this.cPageCacheMiss << 8;
}
///
/// Returns a value indicating whether this instance is equal
/// to another instance.
///
/// An instance to compare with this instance.
/// True if the two instances are equal.
public bool Equals(JET_THREADSTATS2 other)
{
return this.cPageCacheMiss == other.cPageCacheMiss
&& this.cusecPageCacheMiss == other.cusecPageCacheMiss
&& this.cbLogRecord == other.cbLogRecord
&& this.cLogRecord == other.cLogRecord
&& this.cPageDirtied == other.cPageDirtied
&& this.cPagePreread == other.cPagePreread
&& this.cPageRead == other.cPageRead
&& this.cPageRedirtied == other.cPageRedirtied
&& this.cPageReferenced == other.cPageReferenced;
}
///
/// Get the plural suffix ('s') for the given number.
///
/// The number.
/// The letter 's' if n is greater than 1.
private static string GetPluralS(int n)
{
return n == 1 ? string.Empty : "s";
}
}
}