Skip to content

Commit

Permalink
Sample to show use of FASTER with fixed-length structs (#160)
Browse files Browse the repository at this point in the history
* Sample to show use of FASTER with fixed-length struct keys and values, of size known at compile time
  • Loading branch information
badrishc committed Jul 23, 2019
1 parent 1205739 commit 3f1e1bc
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 2 deletions.
15 changes: 13 additions & 2 deletions cs/FASTER.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2008
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FASTER.benchmark", "benchmark\FASTER.benchmark.csproj", "{33A732D1-2B58-4FEE-9696-B9483496229F}"
EndProject
Expand Down Expand Up @@ -35,6 +35,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassCacheMT", "playground\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VarLenStructSample", "playground\VarLenStructSample\VarLenStructSample.csproj", "{37B3C501-A7A1-4E86-B766-22F9BEF31DFE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FixedLenStructSample", "playground\FixedLenStructSample\FixedLenStructSample.csproj", "{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -131,6 +133,14 @@ Global
{37B3C501-A7A1-4E86-B766-22F9BEF31DFE}.Release|Any CPU.Build.0 = Release|x64
{37B3C501-A7A1-4E86-B766-22F9BEF31DFE}.Release|x64.ActiveCfg = Release|x64
{37B3C501-A7A1-4E86-B766-22F9BEF31DFE}.Release|x64.Build.0 = Release|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Debug|Any CPU.ActiveCfg = Debug|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Debug|Any CPU.Build.0 = Debug|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Debug|x64.ActiveCfg = Debug|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Debug|x64.Build.0 = Debug|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Release|Any CPU.ActiveCfg = Release|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Release|Any CPU.Build.0 = Release|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Release|x64.ActiveCfg = Release|x64
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -148,6 +158,7 @@ Global
{079F8DF4-96D4-41AC-AD04-308FDF70E371} = {E6026D6A-01C5-4582-B2C1-64751490DABE}
{F989FF23-5DD7-4D8F-9458-BDA22EFC038D} = {E6026D6A-01C5-4582-B2C1-64751490DABE}
{37B3C501-A7A1-4E86-B766-22F9BEF31DFE} = {E6026D6A-01C5-4582-B2C1-64751490DABE}
{7EBB5ADF-D9EA-4B8B-AAE7-C48A98EBF780} = {E6026D6A-01C5-4582-B2C1-64751490DABE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A0750637-2CCB-4139-B25E-F2CE740DCFAC}
Expand Down
6 changes: 6 additions & 0 deletions cs/playground/FixedLenStructSample/App.config
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
</configuration>
38 changes: 38 additions & 0 deletions cs/playground/FixedLenStructSample/FixedLenStructSample.csproj
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<Platforms>x64</Platforms>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>StructSample</RootNamespace>
<ErrorReport>prompt</ErrorReport>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DefineConstants>TRACE</DefineConstants>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\x64\Release\</OutputPath>
</PropertyGroup>

<ItemGroup>
<None Include="App.config" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\core\FASTER.core.csproj" />
</ItemGroup>
</Project>
66 changes: 66 additions & 0 deletions cs/playground/FixedLenStructSample/Functions.cs
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using FASTER.core;
using System;

namespace FixedLenStructSample
{
/// <summary>
/// Callback functions for FASTER operations
/// </summary>
public class FixedLenFunctions : IFunctions<FixedLenKey, FixedLenValue, string, string, Empty>
{
public void CheckpointCompletionCallback(Guid sessionId, long serialNum)
{
}

public void ConcurrentReader(ref FixedLenKey key, ref string input, ref FixedLenValue value, ref string dst)
{
dst = value.ToString();
}

public void ConcurrentWriter(ref FixedLenKey key, ref FixedLenValue src, ref FixedLenValue dst)
{
src.CopyTo(ref dst);
}

public void CopyUpdater(ref FixedLenKey key, ref string input, ref FixedLenValue oldValue, ref FixedLenValue newValue)
{
}

public void DeleteCompletionCallback(ref FixedLenKey key, Empty ctx)
{
}

public void InitialUpdater(ref FixedLenKey key, ref string input, ref FixedLenValue value)
{
}

public void InPlaceUpdater(ref FixedLenKey key, ref string input, ref FixedLenValue value)
{
}

public void ReadCompletionCallback(ref FixedLenKey key, ref string input, ref string output, Empty ctx, Status status)
{
}

public void RMWCompletionCallback(ref FixedLenKey key, ref string input, Empty ctx, Status status)
{
}

public void SingleReader(ref FixedLenKey key, ref string input, ref FixedLenValue value, ref string dst)
{
dst = value.ToString();
}

public void SingleWriter(ref FixedLenKey key, ref FixedLenValue src, ref FixedLenValue dst)
{
src.CopyTo(ref dst);
}

public void UpsertCompletionCallback(ref FixedLenKey key, ref FixedLenValue value, Empty ctx)
{
}
}
}
57 changes: 57 additions & 0 deletions cs/playground/FixedLenStructSample/Program.cs
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using FASTER.core;
using System;

namespace FixedLenStructSample
{
public class Program
{
// This sample uses fixed length structs for keys and values
static void Main()
{
var log = Devices.CreateLogDevice("hlog.log", deleteOnClose: true);
var fht = new FasterKV<FixedLenKey, FixedLenValue, string, string, Empty, FixedLenFunctions>
(128, new FixedLenFunctions(),
new LogSettings { LogDevice = log, MemorySizeBits = 17, PageSizeBits = 12 }
);
fht.StartSession();

var key = new FixedLenKey("foo");
var value = new FixedLenValue("bar");

var status = fht.Upsert(ref key, ref value, Empty.Default, 0);

if (status != Status.OK)
Console.WriteLine("FixedLenStructSample: Error!");

var input = default(string); // unused
var output = default(string);

key = new FixedLenKey("xyz");
status = fht.Read(ref key, ref input, ref output, Empty.Default, 0);

if (status != Status.NOTFOUND)
Console.WriteLine("FixedLenStructSample: Error!");

key = new FixedLenKey("foo");
status = fht.Read(ref key, ref input, ref output, Empty.Default, 0);

if (status != Status.OK)
Console.WriteLine("FixedLenStructSample: Error!");

if (output.Equals(value.ToString()))
Console.WriteLine("FixedLenStructSample: Success!");
else
Console.WriteLine("FixedLenStructSample: Error!");

fht.StopSession();
fht.Dispose();
log.Close();

Console.WriteLine("Press <ENTER> to end");
Console.ReadLine();
}
}
}
21 changes: 21 additions & 0 deletions cs/playground/FixedLenStructSample/Properties/AssemblyInfo.cs
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyDescription("")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("17bdd0a5-98e5-464a-8a00-050d9ff4c562")]
137 changes: 137 additions & 0 deletions cs/playground/FixedLenStructSample/Types.cs
@@ -0,0 +1,137 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using FASTER.core;
using System;
using System.Runtime.InteropServices;

namespace FixedLenStructSample
{
/// <summary>
/// Represents a fixed length struct type (Length = 32)
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = Length)]
public unsafe struct FixedLenKey : IFasterEqualityComparer<FixedLenKey>
{
private const int Length = 32;

[FieldOffset(0)]
private byte data;

public FixedLenKey(string v)
{
if (Length < 2 * (v.Length + 1))
throw new Exception("Insufficient space to store string");

fixed (byte* ptr = &data)
{
var data = (char*)ptr;
for (var i = 0; i < Length / sizeof(char); i++)
{
if (i < v.Length)
*(data + i) = v[i];
else
*(data + i) = '\0';
}
}
}

public void CopyTo(ref FixedLenKey dst)
{
fixed (byte* source = &data, destination = &dst.data)
Buffer.MemoryCopy(source, destination, Length, Length);
}

public bool Equals(ref FixedLenKey k1, ref FixedLenKey k2)
{
fixed (byte* pk1 = &k1.data, pk2 = &k2.data)
{
for (var i = 0; i < Length; i++)
{
var left = *(pk1 + i);
var right = *(pk2 + i);
if (left != right)
return false;
}
}

return true;
}

public long GetHashCode64(ref FixedLenKey k)
{
fixed (byte* data = &k.data)
return Utility.HashBytes(data, Length);
}

public override string ToString()
{
fixed (byte* ptr = &data)
return new string((char*)ptr);
}
}

/// <summary>
/// Represents a fixed length struct type (Length = 64)
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = Length)]
public unsafe struct FixedLenValue : IFasterEqualityComparer<FixedLenValue>
{
private const int Length = 64;

[FieldOffset(0)]
private byte data;

public FixedLenValue(string v)
{
if (Length < 2 * (v.Length + 1))
throw new Exception("Insufficient space to store string");

fixed (byte* ptr = &data)
{
var data = (char*)ptr;
for (var i = 0; i < Length / sizeof(char); i++)
{
if (i < v.Length)
*(data + i) = v[i];
else
*(data + i) = '\0';
}
}
}

public void CopyTo(ref FixedLenValue dst)
{
fixed (byte* source = &data, destination = &dst.data)
Buffer.MemoryCopy(source, destination, Length, Length);
}

public bool Equals(ref FixedLenValue k1, ref FixedLenValue k2)
{
fixed (byte* pk1 = &k1.data, pk2 = &k2.data)
{
for (var i = 0; i < Length; i++)
{
var left = *(pk1 + i);
var right = *(pk2 + i);
if (left != right)
return false;
}
}

return true;
}

public long GetHashCode64(ref FixedLenValue k)
{
fixed (byte* data = &k.data)
return Utility.HashBytes(data, Length);
}

public override string ToString()
{
fixed (byte* ptr = &data)
return new string((char*)ptr);
}
}
}

0 comments on commit 3f1e1bc

Please sign in to comment.