Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial checkin of transactional dictionary

  • Loading branch information...
commit 34f20e415c92de1b57ca7b6b55bc43a9cb19b5f4 1 parent 3e0e78d
xoltar authored October 21, 2012
22  .gitattributes
... ...
@@ -0,0 +1,22 @@
  1
+# Auto detect text files and perform LF normalization
  2
+* text=auto
  3
+
  4
+# Custom for Visual Studio
  5
+*.cs     diff=csharp
  6
+*.sln    merge=union
  7
+*.csproj merge=union
  8
+*.vbproj merge=union
  9
+*.fsproj merge=union
  10
+*.dbproj merge=union
  11
+
  12
+# Standard to msysgit
  13
+*.doc	 diff=astextplain
  14
+*.DOC	 diff=astextplain
  15
+*.docx diff=astextplain
  16
+*.DOCX diff=astextplain
  17
+*.dot  diff=astextplain
  18
+*.DOT  diff=astextplain
  19
+*.pdf  diff=astextplain
  20
+*.PDF	 diff=astextplain
  21
+*.rtf	 diff=astextplain
  22
+*.RTF	 diff=astextplain
4  .nuget/packages.config
... ...
@@ -0,0 +1,4 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<packages>
  3
+  <package id="xunit.runners" version="1.9.1" />
  4
+</packages>
33  Xoltar-Sharp.sln
... ...
@@ -0,0 +1,33 @@
  1
+
  2
+Microsoft Visual Studio Solution File, Format Version 12.00
  3
+# Visual Studio Express 2012 for Web
  4
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Xoltar.Core", "Xoltar.Core\Xoltar.Core.fsproj", "{5E7440B3-0716-46B6-93B1-48AA3D0B1A7B}"
  5
+EndProject
  6
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{63D7A2CE-0BE8-4E3D-AF7F-91962625D125}"
  7
+	ProjectSection(SolutionItems) = preProject
  8
+		.nuget\NuGet.Config = .nuget\NuGet.Config
  9
+		.nuget\NuGet.exe = .nuget\NuGet.exe
  10
+		.nuget\NuGet.targets = .nuget\NuGet.targets
  11
+	EndProjectSection
  12
+EndProject
  13
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Xoltar.Core.Test", "Xoltar.Core.Test\Xoltar.Core.Test.fsproj", "{FAACD970-DE96-4405-A1BE-15AE84EB2C34}"
  14
+EndProject
  15
+Global
  16
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
  17
+		Debug|Any CPU = Debug|Any CPU
  18
+		Release|Any CPU = Release|Any CPU
  19
+	EndGlobalSection
  20
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
  21
+		{5E7440B3-0716-46B6-93B1-48AA3D0B1A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  22
+		{5E7440B3-0716-46B6-93B1-48AA3D0B1A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
  23
+		{5E7440B3-0716-46B6-93B1-48AA3D0B1A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
  24
+		{5E7440B3-0716-46B6-93B1-48AA3D0B1A7B}.Release|Any CPU.Build.0 = Release|Any CPU
  25
+		{FAACD970-DE96-4405-A1BE-15AE84EB2C34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  26
+		{FAACD970-DE96-4405-A1BE-15AE84EB2C34}.Debug|Any CPU.Build.0 = Debug|Any CPU
  27
+		{FAACD970-DE96-4405-A1BE-15AE84EB2C34}.Release|Any CPU.ActiveCfg = Release|Any CPU
  28
+		{FAACD970-DE96-4405-A1BE-15AE84EB2C34}.Release|Any CPU.Build.0 = Release|Any CPU
  29
+	EndGlobalSection
  30
+	GlobalSection(SolutionProperties) = preSolution
  31
+		HideSolutionNode = FALSE
  32
+	EndGlobalSection
  33
+EndGlobal
8  Xoltar.Core.Test/Script.fsx
... ...
@@ -0,0 +1,8 @@
  1
+// Learn more about F# at http://fsharp.net. See the 'F# Tutorial' project
  2
+// for more guidance on F# programming.
  3
+
  4
+#load "Library1.fs"
  5
+open Xoltar.Core.Test
  6
+
  7
+// Define your library scripting code here
  8
+
123  Xoltar.Core.Test/TransactionalDictionary.fs
... ...
@@ -0,0 +1,123 @@
  1
+namespace Xoltar.Core.Transaction.Test
  2
+open Xunit
  3
+open Xoltar.Core.Transaction
  4
+open System.Collections.Generic
  5
+
  6
+module Dictionary =
  7
+    let dict () = Dictionary()
  8
+    let trans<'k,'v when 'k:equality and 'v:equality>() = 
  9
+        let d = dict()
  10
+        TransactionalDictionary<'k,'v>(d) :> IDictionary<'k,'v>, d
  11
+    let slim set = new System.Threading.ManualResetEventSlim(set)
  12
+    [<Fact>]
  13
+    let ``a new dictionary has count = 0``() = 
  14
+        let d,back = trans()
  15
+        Assert.Equal(0, d.Count)  
  16
+
  17
+    [<Fact>]
  18
+    let ``after adding an item, the item can be retrieved``()= 
  19
+        let d,back = trans()
  20
+        d.[1] <- 2
  21
+        Assert.Equal(2, d.[1])
  22
+
  23
+    [<Fact>]
  24
+    let ``after adding an item, then clearing, the count = 0``() =
  25
+        let d,back = trans()
  26
+        d.[1] <- 2
  27
+        d.Clear()
  28
+        Assert.Equal(0, d.Count)
  29
+
  30
+    [<Fact>]
  31
+    let ``after adding an item, then removing, the count = 0``() =
  32
+        let d,back = trans()
  33
+        d.[1] <- 2
  34
+        d.Remove(1) |> ignore
  35
+        Assert.Equal(0, d.Count)
  36
+
  37
+    [<Fact>]
  38
+    let ``values in a transaction are isolated``() = 
  39
+        use valueSet = slim false 
  40
+        use valueChecked = slim false
  41
+        (
  42
+            let d,back = trans()
  43
+            d.[1] <- 2
  44
+            let t = System.Threading.Tasks.Task.Factory.StartNew (fun () -> 
  45
+                        valueSet.Wait()
  46
+                        try
  47
+                            Assert.Equal(2, d.[1])
  48
+                        finally
  49
+                            valueChecked.Set())
  50
+            use txn = new System.Transactions.TransactionScope()
  51
+            (
  52
+                d.[1] <- 5
  53
+                valueSet.Set()
  54
+                valueChecked.Wait()
  55
+            )
  56
+            t.Wait()
  57
+        )
  58
+
  59
+    [<Fact>]
  60
+    let ``values in a transaction are visible to the transaction``() = 
  61
+        let d,back = trans()
  62
+        d.[1] <- 2
  63
+        use txn = new System.Transactions.TransactionScope()
  64
+        (
  65
+            d.[1] <- 5
  66
+            Assert.Equal(5, d.[1])
  67
+        )
  68
+    
  69
+    [<Fact>]
  70
+    let ``after rollback, transaction values are not committed``()= 
  71
+        let d,back = trans()
  72
+        d.[1] <- 2
  73
+        use txn = new System.Transactions.TransactionScope()
  74
+        (
  75
+            d.[1] <- 5
  76
+        )
  77
+        Assert.Equal(2, back.[1])
  78
+
  79
+    [<Fact>]
  80
+    let ``after rollback, transaction values are gone in trans dict``()= 
  81
+        let d,back = trans()
  82
+        d.[1] <- 2
  83
+        use txn = new System.Transactions.TransactionScope()
  84
+        (
  85
+            d.[1] <- 5
  86
+        )
  87
+        Assert.Equal(2, d.[1])
  88
+
  89
+    [<Fact>]
  90
+    let ``after commit, transaction values persist``()= 
  91
+        let d,back = trans()
  92
+        d.[1] <- 2
  93
+        use txn = new System.Transactions.TransactionScope()
  94
+        (
  95
+            d.[1] <- 5
  96
+            txn.Complete()
  97
+        )
  98
+        Assert.Equal(5, back.[1])
  99
+
  100
+    [<Fact>]
  101
+    let ``last commit wins``() = 
  102
+        use valueSet = slim false 
  103
+        use valueSet2 = slim false
  104
+        use valueChecked = slim false
  105
+        (
  106
+            let d,back = trans()
  107
+            d.[1] <- 2
  108
+            let t = System.Threading.Tasks.Task.Factory.StartNew (fun () -> 
  109
+                        valueSet.Wait()
  110
+                        try
  111
+                            Assert.Equal(2, d.[1])
  112
+                        finally
  113
+                            valueChecked.Set())
  114
+            use txn = new System.Transactions.TransactionScope()
  115
+            (
  116
+                d.[1] <- 5
  117
+                valueSet.Set()
  118
+                valueChecked.Wait()
  119
+                txn.Complete()
  120
+            )
  121
+            t.Wait()
  122
+            Assert.Equal(5, back.[1])
  123
+        )
92  Xoltar.Core.Test/Xoltar.Core.Test.fsproj
... ...
@@ -0,0 +1,92 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  4
+  <PropertyGroup>
  5
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
  6
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
  7
+    <SchemaVersion>2.0</SchemaVersion>
  8
+    <ProjectGuid>faacd970-de96-4405-a1be-15ae84eb2c34</ProjectGuid>
  9
+    <OutputType>Library</OutputType>
  10
+    <RootNamespace>Xoltar.Core.Test</RootNamespace>
  11
+    <AssemblyName>Xoltar.Core.Test</AssemblyName>
  12
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  13
+    <Name>Xoltar.Core.Test</Name>
  14
+  </PropertyGroup>
  15
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  16
+    <DebugSymbols>true</DebugSymbols>
  17
+    <DebugType>full</DebugType>
  18
+    <Optimize>false</Optimize>
  19
+    <Tailcalls>false</Tailcalls>
  20
+    <OutputPath>bin\Debug\</OutputPath>
  21
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
  22
+    <WarningLevel>3</WarningLevel>
  23
+    <DocumentationFile>bin\Debug\Xoltar.Core.Test.XML</DocumentationFile>
  24
+  </PropertyGroup>
  25
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  26
+    <DebugType>pdbonly</DebugType>
  27
+    <Optimize>true</Optimize>
  28
+    <Tailcalls>true</Tailcalls>
  29
+    <OutputPath>bin\Release\</OutputPath>
  30
+    <DefineConstants>TRACE</DefineConstants>
  31
+    <WarningLevel>3</WarningLevel>
  32
+    <DocumentationFile>bin\Release\Xoltar.Core.Test.XML</DocumentationFile>
  33
+  </PropertyGroup>
  34
+  <ItemGroup>
  35
+    <Reference Include="FsCheck">
  36
+      <HintPath>..\packages\FsCheck.0.8.3.0\lib\net40-Client\FsCheck.dll</HintPath>
  37
+      <Private>True</Private>
  38
+    </Reference>
  39
+    <Reference Include="FsCheck.Xunit">
  40
+      <HintPath>..\packages\FsCheck.Xunit.0.3.0.0\lib\net40-Client\FsCheck.Xunit.dll</HintPath>
  41
+      <Private>True</Private>
  42
+    </Reference>
  43
+    <Reference Include="mscorlib" />
  44
+    <Reference Include="FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  45
+      <Private>True</Private>
  46
+    </Reference>
  47
+    <Reference Include="System" />
  48
+    <Reference Include="System.Core" />
  49
+    <Reference Include="System.Numerics" />
  50
+    <Reference Include="System.Transactions" />
  51
+    <Reference Include="xunit, Version=1.9.1.1600, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c">
  52
+      <Private>True</Private>
  53
+    </Reference>
  54
+    <Reference Include="xunit.extensions">
  55
+      <HintPath>..\packages\xunit.extensions.1.9.1\lib\net20\xunit.extensions.dll</HintPath>
  56
+      <Private>True</Private>
  57
+    </Reference>
  58
+    <Reference Include="xunit.runner.msbuild, Version=1.9.1.1600, Culture=neutral, PublicKeyToken=null">
  59
+      <Private>True</Private>
  60
+    </Reference>
  61
+    <Reference Include="xunit.runner.tdnet, Version=1.9.1.1600, Culture=neutral, PublicKeyToken=null">
  62
+      <Private>True</Private>
  63
+    </Reference>
  64
+    <Reference Include="xunit.runner.utility, Version=1.9.1.1600, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c">
  65
+      <Private>True</Private>
  66
+    </Reference>
  67
+  </ItemGroup>
  68
+  <ItemGroup>
  69
+    <Compile Include="TransactionalDictionary.fs" />
  70
+    <None Include="Script.fsx" />
  71
+    <None Include="packages.config" />
  72
+    <None Include="app.config" />
  73
+  </ItemGroup>
  74
+  <ItemGroup>
  75
+    <ProjectReference Include="..\Xoltar.Core\Xoltar.Core.fsproj">
  76
+      <Name>Xoltar.Core</Name>
  77
+      <Project>{5e7440b3-0716-46b6-93b1-48aa3d0b1a7b}</Project>
  78
+      <Private>True</Private>
  79
+    </ProjectReference>
  80
+  </ItemGroup>
  81
+  <PropertyGroup>
  82
+    <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
  83
+  </PropertyGroup>
  84
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
  85
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
  86
+       Other similar extension points exist, see Microsoft.Common.targets.
  87
+  <Target Name="BeforeBuild">
  88
+  </Target>
  89
+  <Target Name="AfterBuild">
  90
+  </Target>
  91
+  -->
  92
+</Project>
2  Xoltar.Core.Test/app.config
... ...
@@ -0,0 +1,2 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<configuration />
4  Xoltar.Core.Test/packages.config
... ...
@@ -0,0 +1,4 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<packages>
  3
+  <package id="FsCheck" version="0.8.3.0" targetFramework="net45" />
  4
+</packages>
8  Xoltar.Core/Script.fsx
... ...
@@ -0,0 +1,8 @@
  1
+// Learn more about F# at http://fsharp.net. See the 'F# Tutorial' project
  2
+// for more guidance on F# programming.
  3
+
  4
+#load "Library1.fs"
  5
+open Xoltar.Core
  6
+
  7
+// Define your library scripting code here
  8
+
187  Xoltar.Core/TransactionalDictionary.fs
... ...
@@ -0,0 +1,187 @@
  1
+namespace Xoltar.Core.Transaction
  2
+
  3
+open System.Collections.Generic
  4
+open System.Linq
  5
+open Microsoft.FSharp.Linq
  6
+open System.Transactions
  7
+
  8
+type TransactionValues<'TKey,'TValue
  9
+                        when 'TKey: equality
  10
+                         and 'TValue: equality>
  11
+                         (backingStore:IDictionary<'TKey, 'TValue>,
  12
+                          finished:System.Action) as this =     
  13
+    let transaction = 
  14
+        let txn = System.Transactions.Transaction.Current
  15
+        if txn = null then 
  16
+            let msg = "TransactionalDictionary can only be created in the context of an open transaction"
  17
+            raise (System.InvalidOperationException(msg))
  18
+        txn.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None) |> ignore
  19
+        txn
  20
+
  21
+    let transactionValues = 
  22
+        if backingStore.IsReadOnly then
  23
+            raise (System.ArgumentException("Source dictionary is ReadOnly"))
  24
+        let dict = new Dictionary<'TKey, 'TValue option>()
  25
+        for kv in backingStore do
  26
+            dict.[kv.Key] <- Some kv.Value
  27
+        dict
  28
+
  29
+    let remove key = transactionValues.[key] <- None
  30
+    let current () = seq {
  31
+                        for kv in transactionValues do
  32
+                        if Option.isSome (kv.Value) then 
  33
+                            yield new KeyValuePair<'TKey, 'TValue>(kv.Key, kv.Value.Value)
  34
+                            }
  35
+    let getWithDefault key = 
  36
+        let (succ, value) = transactionValues.TryGetValue(key)
  37
+        match (succ, value) with
  38
+        | true, ((Some _) as v) -> v
  39
+        | _ -> None
  40
+
  41
+    let getOrFail key =
  42
+        let (succ, value) = transactionValues.TryGetValue(key)
  43
+        match (succ, value) with
  44
+        | true, (Some v) -> v
  45
+        | _ -> raise (KeyNotFoundException())
  46
+
  47
+    interface IDictionary<'TKey,'TValue>
  48
+        with
  49
+        member this.GetEnumerator() = 
  50
+            ((current() |> Seq.map (fun kv -> kv :> obj))
  51
+                :> System.Collections.IEnumerable).GetEnumerator()
  52
+        member this.GetEnumerator() = current().GetEnumerator()
  53
+        member this.Clear () =
  54
+            let keys = current() |> Seq.map (fun kv -> kv.Key) |> Array.ofSeq
  55
+            keys |> Seq.iter remove
  56
+        member this.Add(kv) = 
  57
+            transactionValues.[kv.Key] <- Some (kv.Value)
  58
+        member this.Contains(kv) = 
  59
+            let stored = getWithDefault kv.Key
  60
+            stored.IsSome && stored.Value = kv.Value
  61
+        member this.Remove(kv:KeyValuePair<'TKey,'TValue>) =
  62
+            let existing = getWithDefault kv.Key
  63
+            transactionValues.[kv.Key] <- None
  64
+            existing.IsSome && existing.Value = kv.Value
  65
+        member this.CopyTo(array, arrayIndex) = 
  66
+            let en = (this :> IEnumerable<KeyValuePair<'TKey,'TValue>>).GetEnumerator()
  67
+            for x = arrayIndex to (array.Length - 1) do
  68
+              if en.MoveNext() then
  69
+                array.[x] <- en.Current
  70
+            ()
  71
+        member this.Count with get () = current().Count()
  72
+        member this.IsReadOnly with get ()= false
  73
+        member this.Add(key, value) = transactionValues.[key] <- Some value
  74
+        member this.Item
  75
+                with get key = getOrFail key
  76
+                and  set key value = transactionValues.[key] <- Some value
  77
+        member this.ContainsKey key = getWithDefault key |> Option.isSome
  78
+        member this.Remove (key:'TKey) = 
  79
+            let existing = getWithDefault key
  80
+            transactionValues.[key] <- None
  81
+            existing.IsSome
  82
+        member this.TryGetValue(key:'TKey,value:byref<'TValue>) = 
  83
+            match transactionValues.TryGetValue(key) with
  84
+            | true,Some(v) -> value <- v; true
  85
+            | _ -> false
  86
+
  87
+        member this.Keys = current() 
  88
+                            |> Seq.map (fun kv -> kv.Key) 
  89
+                            |> fun s -> new List<'TKey>(s) :> ICollection<'TKey>
  90
+        member this.Values = current() 
  91
+                            |> Seq.map (fun kv -> kv.Value) 
  92
+                            |> fun s -> new List<'TValue>(s) :> ICollection<'TValue>
  93
+
  94
+    interface System.Transactions.IEnlistmentNotification
  95
+        with
  96
+        member this.Commit(enlistment) = 
  97
+            for kv in transactionValues do
  98
+                match kv.Value with
  99
+                | Some v -> backingStore.[kv.Key] <- v
  100
+                | None -> backingStore.Remove kv.Key |> ignore
  101
+            enlistment.Done()
  102
+        member this.InDoubt(enlistment) = enlistment.Done()
  103
+        member this.Prepare(enlistment) = enlistment.Prepared()
  104
+        member this.Rollback(enlistment) = enlistment.Done()
  105
+
  106
+///<summary>A Dictionary implementation that is transaction-aware</summary>
  107
+///Tracks changes that occur during a transaction and ensures that if the 
  108
+///transaction is rolled back, the dictionary will be unchanged. Threads that are participating
  109
+///in the transaction will see the changes as they are made, but threads that are in 
  110
+///other transactions, or no transaction, will not see the changes made in the transaction
  111
+///until it is committed.
  112
+///
  113
+///This dictionary, like System.Collections.Generic.Dictionary, is not thread safe,
  114
+///it can only be safely used by a single thread at a time.
  115
+type TransactionalDictionary<'TKey, 'TValue 
  116
+        when 'TKey:equality
  117
+         and 'TValue: equality> 
  118
+            (backingStore:IDictionary<'TKey,'TValue>) = 
  119
+
  120
+    let transactions = new Dictionary<Transaction,TransactionValues<'TKey, 'TValue>>()
  121
+    let transactionEnded txn = transactions.Remove txn |> ignore
  122
+    let getTxnValues txn : IDictionary<'TKey, 'TValue> = 
  123
+        if txn = null then
  124
+            backingStore
  125
+        else
  126
+            let (containsKey,value) = transactions.TryGetValue txn
  127
+            let dict = 
  128
+                match (containsKey,value) with
  129
+                | true, v -> v 
  130
+                | false, _ -> let v = TransactionValues<'TKey, 'TValue>(backingStore, fun () -> transactionEnded txn)
  131
+                              transactions.[txn] <- v
  132
+                              v
  133
+            dict :> IDictionary<'TKey,'TValue>
  134
+    let getTxnValues () = getTxnValues (Transaction.Current)
  135
+                      
  136
+    interface IDictionary<'TKey,'TValue>
  137
+        with
  138
+        member this.GetEnumerator() = 
  139
+            let tv = getTxnValues() :> System.Collections.IEnumerable
  140
+            tv.GetEnumerator()
  141
+        member this.GetEnumerator() = 
  142
+            let tv = getTxnValues() :> IEnumerable<KeyValuePair<'TKey,'TValue>>
  143
+            tv.GetEnumerator()
  144
+        member this.Clear () =
  145
+            let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  146
+            tv.Clear()
  147
+        member this.Add(kv) = 
  148
+            let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  149
+            tv.Add(kv)
  150
+        member this.Contains(kv) = 
  151
+            let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  152
+            tv.Contains(kv)
  153
+        member this.Remove(kv:KeyValuePair<'TKey,'TValue>) =
  154
+            let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  155
+            tv.Remove(kv)
  156
+        member this.CopyTo(array, arrayIndex) = 
  157
+            let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  158
+            tv.CopyTo(array, arrayIndex)
  159
+        member this.Count 
  160
+            with get () = 
  161
+                let tv = getTxnValues() :> ICollection<KeyValuePair<'TKey,'TValue>>
  162
+                tv.Count
  163
+        member this.IsReadOnly with get ()= false
  164
+        member this.Add(key, value) = 
  165
+            let tv = getTxnValues()
  166
+            tv.[key] <- value
  167
+        member this.Item
  168
+                with get key = let tv = getTxnValues() 
  169
+                               tv.[key]
  170
+                and  set key value = let tv = getTxnValues()
  171
+                                     tv.[key] <- value
  172
+        member this.Remove (key:'TKey) = 
  173
+            let tv = getTxnValues()
  174
+            tv.Remove key
  175
+        member this.TryGetValue(key:'TKey,value:byref<'TValue>) = 
  176
+            let tv = getTxnValues()
  177
+            tv.TryGetValue(key,&value)
  178
+        member this.ContainsKey(key:'TKey) = 
  179
+            let tv = getTxnValues()
  180
+            tv.ContainsKey key
  181
+        member this.Keys =
  182
+            let tv = getTxnValues()
  183
+            tv.Keys
  184
+        member this.Values = 
  185
+            let tv = getTxnValues()
  186
+            tv.Values
  187
+
59  Xoltar.Core/Xoltar.Core.fsproj
... ...
@@ -0,0 +1,59 @@
  1
+<?xml version="1.0" encoding="utf-8"?>
  2
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  4
+  <PropertyGroup>
  5
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
  6
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
  7
+    <SchemaVersion>2.0</SchemaVersion>
  8
+    <ProjectGuid>5e7440b3-0716-46b6-93b1-48aa3d0b1a7b</ProjectGuid>
  9
+    <OutputType>Library</OutputType>
  10
+    <RootNamespace>Xoltar.Core</RootNamespace>
  11
+    <AssemblyName>Xoltar.Core</AssemblyName>
  12
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  13
+    <Name>Xoltar.Core</Name>
  14
+  </PropertyGroup>
  15
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  16
+    <DebugSymbols>true</DebugSymbols>
  17
+    <DebugType>full</DebugType>
  18
+    <Optimize>false</Optimize>
  19
+    <Tailcalls>false</Tailcalls>
  20
+    <OutputPath>bin\Debug\</OutputPath>
  21
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
  22
+    <WarningLevel>3</WarningLevel>
  23
+    <DocumentationFile>bin\Debug\Xoltar.Core.XML</DocumentationFile>
  24
+  </PropertyGroup>
  25
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  26
+    <DebugType>pdbonly</DebugType>
  27
+    <Optimize>true</Optimize>
  28
+    <Tailcalls>true</Tailcalls>
  29
+    <OutputPath>bin\Release\</OutputPath>
  30
+    <DefineConstants>TRACE</DefineConstants>
  31
+    <WarningLevel>3</WarningLevel>
  32
+    <DocumentationFile>bin\Release\Xoltar.Core.XML</DocumentationFile>
  33
+  </PropertyGroup>
  34
+  <ItemGroup>
  35
+    <Reference Include="mscorlib" />
  36
+    <Reference Include="FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  37
+      <Private>True</Private>
  38
+    </Reference>
  39
+    <Reference Include="System" />
  40
+    <Reference Include="System.Core" />
  41
+    <Reference Include="System.Numerics" />
  42
+    <Reference Include="System.Transactions" />
  43
+  </ItemGroup>
  44
+  <ItemGroup>
  45
+    <Compile Include="TransactionalDictionary.fs" />
  46
+    <None Include="Script.fsx" />
  47
+  </ItemGroup>
  48
+  <PropertyGroup>
  49
+    <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
  50
+  </PropertyGroup>
  51
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
  52
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
  53
+       Other similar extension points exist, see Microsoft.Common.targets.
  54
+  <Target Name="BeforeBuild">
  55
+  </Target>
  56
+  <Target Name="AfterBuild">
  57
+  </Target>
  58
+  -->
  59
+</Project>

0 notes on commit 34f20e4

Please sign in to comment.
Something went wrong with that request. Please try again.