Repository: ignite
Updated Branches:
  refs/heads/ignite-1282 c2a1631bb -> 3852b0b65


http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Company.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Company.cs 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Company.cs
new file mode 100644
index 0000000..3e99d34
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Company.cs
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Model
+{
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Company.
+    /// </summary>
+    internal class Company : IPortableMarshalAware
+    {
+        /// <summary>
+        /// ID.
+        /// </summary>
+        public int Id { get; set; }
+
+        /// <summary>
+        /// Name.
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Size.
+        /// </summary>
+        public int Size { get; set; }
+
+        /// <summary>
+        /// Address.
+        /// </summary>
+        public Address Address { get; set; }
+
+        /// <summary>
+        /// Occupation.
+        /// </summary>
+        public string Occupation { get; set; }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="id">ID.</param>
+        /// <param name="name">Name.</param>
+        /// <param name="size">Size.</param>
+        /// <param name="address">Address.</param>
+        /// <param name="occupation">Occupation.</param>
+        public Company(int id, string name, int size, Address address, string 
occupation)
+        {
+            Id = id;
+            Name = name;
+            Size = size;
+            Address = address;
+            Occupation = occupation;
+        }
+
+        /** <inheritDoc /> */
+        public void WritePortable(IPortableWriter writer)
+        {
+            writer.WriteInt("id", Id);
+            writer.WriteInt("size", Size);
+            writer.WriteString("name", Name);
+            writer.WriteString("occupation", Occupation);
+            writer.WriteObject("address", Address);
+        }
+
+        /** <inheritDoc /> */
+        public void ReadPortable(IPortableReader reader)
+        {
+            Id = reader.ReadInt("id");
+            Size = reader.ReadInt("size");
+            Name = reader.ReadString("name");
+            Occupation = reader.ReadString("occupation");
+            Address = reader.ReadObject<Address>("address");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Department.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Department.cs 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Department.cs
new file mode 100644
index 0000000..0b1254b
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Department.cs
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Model
+{
+    /// <summary>
+    /// Department.
+    /// </summary>
+    internal enum Department
+    {
+        /** PR. */
+        Pr, 
+        
+        /** Sales. */
+        Sales, 
+        
+        /** Development. */
+        Development, 
+        
+        /** Engineering. */
+        Engineering, 
+        
+        /** Nose scrunches. */
+        NoseScrunches
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Employee.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Employee.cs 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Employee.cs
new file mode 100644
index 0000000..0061b79
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Employee.cs
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Model
+{
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Employee.
+    /// </summary>
+    internal class Employee : IPortableMarshalAware
+    {
+        /// <summary>
+        /// ID.
+        /// </summary>
+        public int Id { get; set; }
+        
+        /// <summary>
+        /// Name.
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Company ID.
+        /// </summary>
+        public int CompanyId { get; set; }
+
+        /// <summary>
+        /// Age.
+        /// </summary>
+        public int Age { get; set; }
+
+        /// <summary>
+        /// Sex type.
+        /// </summary>
+        public Sex SexType { get; set; }
+
+        /// <summary>
+        /// Salary.
+        /// </summary>
+        public long Salary { get; set; }
+
+        /// <summary>
+        /// Address.
+        /// </summary>
+        public Address Address { get; set; }
+
+        /// <summary>
+        /// Department.
+        /// </summary>
+        public Department Department { get; set; }
+
+        /// <summary>
+        /// Payload.
+        /// </summary>
+        public byte[] Payload { get; set; }
+
+        /// <summary>
+        /// Points.
+        /// </summary>
+        public int Points { get; set; }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="id">ID.</param>
+        /// <param name="name">Name.</param>
+        /// <param name="companyId">Company ID.</param>
+        /// <param name="age">Age.</param>
+        /// <param name="sexType">Sex type.</param>
+        /// <param name="salary">Salary.</param>
+        /// <param name="address">Address.</param>
+        /// <param name="department">Department.</param>
+        /// <param name="payloadSize">Payload size.</param>
+        public Employee(int id, string name, int companyId, int age, Sex 
sexType, long salary, Address address,
+            Department department, int payloadSize)
+        {
+            Id = id;
+            Name = name;
+            CompanyId = companyId;
+            Age = age;
+            SexType = sexType;
+            Salary = salary;
+            Address = address;
+            Department = department;
+
+            Payload = new byte[payloadSize];
+
+            Points = 100;
+        }
+
+        /** <inheritDoc /> */
+        void IPortableMarshalAware.WritePortable(IPortableWriter writer)
+        {
+            writer.WriteInt("id", Id);
+            writer.WriteInt("companyId", CompanyId);
+            writer.WriteInt("age", Age);
+            writer.WriteInt("points", Points);
+            writer.WriteByte("sex", (byte)SexType);
+            writer.WriteByte("department", (byte)Department);
+            writer.WriteLong("salary", Salary);
+            writer.WriteByteArray("payload", Payload);
+            writer.WriteString("name", Name);
+            writer.WriteObject("address", Address);
+        }
+
+        /** <inheritDoc /> */
+        void IPortableMarshalAware.ReadPortable(IPortableReader reader)
+        {
+            Id = reader.ReadInt("id");
+            CompanyId = reader.ReadInt("companyId");
+            Age = reader.ReadInt("age");
+            Points = reader.ReadInt("points");
+            SexType = (Sex)reader.ReadByte("sex");
+            Department = (Department)reader.ReadByte("department");
+            Salary = reader.ReadLong("salary");
+            Payload = reader.ReadByteArray("payload");
+            Name = reader.ReadString("name");
+            Address = reader.ReadObject<Address>("address");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Sex.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Sex.cs 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Sex.cs
new file mode 100644
index 0000000..187469c
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Model/Sex.cs
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Model
+{
+    /// <summary>
+    /// Sex enumeration.
+    /// </summary>
+    internal enum Sex
+    {
+        /** Male. */
+        Male, 
+        
+        /** Female. */
+        Female
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
new file mode 100644
index 0000000..f8ba796
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Portable/PortableWriteBenchmark.cs
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Portable
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Benchmarks.Model;
+    using Apache.Ignite.Core.Impl.Memory;
+    using Apache.Ignite.Core.Impl.Portable;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Portable write benchmark.
+    /// </summary>
+    internal class PortableWriteBenchmark : BenchmarkBase
+    {
+        /** Marshaller. */
+        private readonly PortableMarshaller _marsh;
+
+        /** Memory manager. */
+        private readonly PlatformMemoryManager _memMgr = new 
PlatformMemoryManager(1024);
+
+        /** Pre-allocated addess. */
+        private readonly Address _address = BenchmarkUtils.GetRandomAddress();
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="PortableWriteBenchmark"/> class.
+        /// </summary>
+        public PortableWriteBenchmark()
+        {
+            _marsh = new PortableMarshaller(new PortableConfiguration
+            {
+                TypeConfigurations = new List<PortableTypeConfiguration>
+                {
+                    new PortableTypeConfiguration(typeof (Address)) 
{MetadataEnabled = false}
+                }
+            });
+        }
+
+        /// <summary>
+        /// Populate descriptors.
+        /// </summary>
+        /// <param name="descs">Descriptors.</param>
+        protected override void 
GetDescriptors(ICollection<BenchmarkOperationDescriptor> descs)
+        {
+            descs.Add(BenchmarkOperationDescriptor.Create("WriteAddress", 
WriteAddress, 1));
+        }
+
+        /// <summary>
+        /// Write address.
+        /// </summary>
+        /// <param name="state">State.</param>
+        private void WriteAddress(BenchmarkState state)
+        {
+            var mem = _memMgr.Allocate();
+
+            try
+            {
+                var stream = mem.Stream();
+
+                _marsh.StartMarshal(stream).Write(_address);
+            }
+            finally
+            {
+                mem.Release();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cef4ebb
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Apache.Ignite.Benchmarks")]
+[assembly: AssemblyDescription("Apache Ignite .NET Benchmarks")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache Ignite")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("8fae8395-7e91-411a-a78f-44d6d3fed0fc")]
+
+[assembly: AssemblyVersion("1.5.0")]
+[assembly: AssemblyFileVersion("1.5.0")]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkConsoleResultWriter.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkConsoleResultWriter.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkConsoleResultWriter.cs
new file mode 100644
index 0000000..81ff871
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkConsoleResultWriter.cs
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Result
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Globalization;
+
+    /// <summary>
+    /// Benchmark console result writer.
+    /// </summary>
+    internal class BenchmarkConsoleResultWriter : IBenchmarkResultWriter
+    {
+        /** Cached culture. */
+        private static readonly CultureInfo Culture = new CultureInfo("en-US");
+
+        /** Benchmark. */
+        private volatile BenchmarkBase _benchmark;
+
+        /** <inheritdoc/> */
+        public void Initialize(BenchmarkBase benchmark, ICollection<string> 
opNames)
+        {
+            _benchmark = benchmark;
+        }
+
+        /** <inheritdoc/> */
+        public void WriteThroughput(string opName, long duration, long opCount)
+        {
+            opCount = opCount * _benchmark.BatchSize;
+
+            double durSec = (double)duration / Stopwatch.Frequency;
+
+            Console.WriteLine(opName + ": operations=" + opCount
+                + ", duration=" + durSec.ToString("F2", Culture) + "s"
+                + ", throughput=" + (opCount / durSec) + " (op/s)"
+                + ", latency=" + (durSec * 1000 / opCount).ToString("F3", 
Culture) + "ms"
+                );
+        }
+
+        /** <inheritdoc/> */
+        public void WritePercentiles(string opName, long interval, long[] 
slots)
+        {
+            // No-op.
+        }
+
+        /** <inheritdoc/> */
+        public void Commit()
+        {
+            // No-op.
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkFileResultWriter.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkFileResultWriter.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkFileResultWriter.cs
new file mode 100644
index 0000000..9ff01e6
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/BenchmarkFileResultWriter.cs
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Result
+{
+    using System;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Threading;
+
+    internal class BenchmarkFileResultWriter : IBenchmarkResultWriter
+    {
+        /** Probe file name: percentile. */
+        private const string ProbePercentile = "PercentileProbe.csv";
+
+        /** Probe file name: throughput. */
+        private const string ProbeThroughput = "ThroughputLatencyProbe.csv";
+
+        /** File header: percentile probe. */
+        private const string HdrPercentile = "**\"Latency, 
microseconds\",\"Operations, %\"";
+
+        /** File header: throughput probe. */
+
+        private const string HdrThroughput =
+            "**\"Time, sec\",\"Operations/sec (more is better)\",\"Latency, 
nsec (less is better)\"";
+
+        /** Cached culture. */
+        private static readonly CultureInfo Culture = new CultureInfo("en-US");
+
+        /** Writer. */
+        private readonly Writer _writer = new Writer();
+
+        /** Benchmarks. */
+        private volatile IDictionary<string, BenchmarkTask> _benchmarks;
+
+        /** <inheritdoc/> */
+        public void Initialize(BenchmarkBase benchmark, ICollection<string> 
opNames)
+        {
+            _benchmarks = new Dictionary<string, BenchmarkTask>(opNames.Count);
+
+            // 1. Create folder for results.
+            var now = DateTime.Now;
+
+            var suffix = "-t=" + benchmark.Threads + "-d=" + 
benchmark.Duration +
+                         "-w=" + benchmark.Warmup;
+
+            var path = benchmark.ResultFolder + "\\" + 
now.ToString("yyyyMMdd-HHmmss", Culture) + "-" +
+                       benchmark.GetType().Name + suffix;
+
+            if (Directory.Exists(path))
+                Directory.Delete(path, true);
+
+            Directory.CreateDirectory(path);
+
+            var dateStr = "--Created " + 
DateTime.Now.ToString("yyyyMMdd-HHmmss", Culture);
+            var cfgStr = "--Benchmark config: " + benchmark;
+
+            // 2. For each operation create separate folder and initialize 
probe files there.
+            foreach (var opName in opNames)
+            {
+                var opDesc = benchmark.GetType().Name + "-" + opName + suffix;
+                var opPath = path + "\\" + opDesc;
+
+                Directory.CreateDirectory(opPath);
+
+                var task = new BenchmarkTask(opPath + "\\" + ProbePercentile,
+                    opPath + "\\" + ProbeThroughput);
+
+                _benchmarks[opName] = task;
+
+                File.AppendAllText(task.FilePercentile, dateStr + "\n");
+                File.AppendAllText(task.FilePercentile, cfgStr + "\n");
+                File.AppendAllText(task.FilePercentile, "--Description: " + 
opDesc + "\n");
+                File.AppendAllText(task.FilePercentile, "@@" + 
benchmark.GetType().Name + "\n");
+                File.AppendAllText(task.FilePercentile, HdrPercentile + "\n");
+
+                File.AppendAllText(task.FileThroughput, dateStr + "\n");
+                File.AppendAllText(task.FileThroughput, cfgStr + "\n");
+                File.AppendAllText(task.FileThroughput, "--Description: " + 
opDesc + "\n");
+                File.AppendAllText(task.FileThroughput, "@@" + 
benchmark.GetType().Name + "\n");
+                File.AppendAllText(task.FileThroughput, HdrThroughput + "\n");
+            }
+
+            // 3. Start writer thread.
+            new Thread(_writer.Run).Start();
+        }
+
+        /** <inheritdoc/> */
+        public void WriteThroughput(string opName, long duration, long opCount)
+        {
+            var benchmark = _benchmarks[opName];
+
+            if (!benchmark.FirstThroughput())
+            {
+                var sec = benchmark.Counter();
+
+                var ops = (float) opCount;
+                var latency = (float) 
duration*1000000000/(opCount*Stopwatch.Frequency);
+
+                var text = sec + "," + ops.ToString("F2", Culture) + "," + 
latency.ToString("F2", Culture);
+
+                Write0(benchmark.FileThroughput, text);
+            }
+        }
+
+        /** <inheritdoc/> */
+        public void WritePercentiles(string opName, long interval, long[] 
slots)
+        {
+            var benchmark = _benchmarks[opName];
+
+            var total = slots.Sum();
+
+            long time = 0;
+
+            foreach (var slot in slots)
+            {
+                var val = (float) slot/total;
+
+                Write0(benchmark.FilePercentile, time + "," + 
val.ToString("F2", Culture));
+
+                time += interval;
+            }
+        }
+
+        /** <inheritdoc/> */
+        public void Commit()
+        {
+            _writer.Add(new StopTask().Run);
+
+            _writer.AwaitStop();
+        }
+
+        /// <summary>
+        /// Internal write routine.
+        /// </summary>
+        /// <param name="path">Path.</param>
+        /// <param name="text">Text.</param>
+        private void Write0(string path, string text)
+        {
+            _writer.Add(new WriteTask(path, text).Run);
+        }
+
+        /// <summary>
+        /// Writer.
+        /// </summary>
+        private class Writer
+        {
+            /** Queue. */
+            private readonly BlockingCollection<Task> _queue = new 
BlockingCollection<Task>();
+
+            /** Stop flag. */
+            private volatile bool _stop;
+
+            /// <summary>
+            /// Runner method.
+            /// </summary>
+            public void Run()
+            {
+                while (!_stop)
+                {
+                    var task = _queue.Take();
+
+                    task.Invoke(this);
+                }
+            }
+
+            /// <summary>
+            /// Add task to queue.
+            /// </summary>
+            /// <param name="task">Task.</param>
+            public void Add(Task task)
+            {
+                _queue.Add(task);
+            }
+
+            /// <summary>
+            /// Mark writer stopped.
+            /// </summary>
+            public void Stop()
+            {
+                lock (this)
+                {
+                    _stop = true;
+
+                    Monitor.PulseAll(this);
+                }
+            }
+
+            /// <summary>
+            /// Await for writer stop.
+            /// </summary>
+            /// <returns></returns>
+            public void AwaitStop()
+            {
+                lock (this)
+                {
+                    while (!_stop)
+                        Monitor.Wait(this);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Writer task.
+        /// </summary>
+        /// <param name="writer">Writer.</param>
+        private delegate void Task(Writer writer);
+
+        /// <summary>
+        /// Writer write task.
+        /// </summary>
+        private class WriteTask
+        {
+            /** File name. */
+            private readonly string _fileName;
+
+            /** Text. */
+            private readonly string _text;
+
+            /// <summary>
+            /// Constructor.
+            /// </summary>
+            /// <param name="fileName">File name.</param>
+            /// <param name="text">Text.</param>
+            public WriteTask(string fileName, string text)
+            {
+                _fileName = fileName;
+                _text = text;
+            }
+
+            /// <summary>
+            /// Runner.
+            /// </summary>
+            public void Run(Writer writer)
+            {
+                File.AppendAllText(_fileName, _text + "\n");
+            }
+        }
+
+        /// <summary>
+        /// Writer stop task.
+        /// </summary>
+        private class StopTask
+        {
+            /// <summary>
+            /// Runner.
+            /// </summary>
+            public void Run(Writer writer)
+            {
+                writer.Stop();
+            }
+        }
+
+        /// <summary>
+        /// Benchmark task.
+        /// </summary>
+        private class BenchmarkTask
+        {
+            /** Counter. */
+            private int _ctr;
+
+            /** First throughput flag. */
+            private int _first;
+
+            /// <summary>
+            /// Constructor.
+            /// </summary>
+            /// <param name="filePercentile">File percentile.</param>
+            /// <param name="fileThroughput">File throughput.</param>
+            public BenchmarkTask(string filePercentile, string fileThroughput)
+            {
+                FilePercentile = filePercentile;
+                FileThroughput = fileThroughput;
+            }
+
+            /// <summary>
+            /// File percentile.
+            /// </summary>
+            public string FilePercentile { get; private set; }
+
+            /// <summary>
+            /// File throughput.
+            /// </summary>
+            public string FileThroughput { get; private set; }
+
+            /// <summary>
+            /// Get counter value.
+            /// </summary>
+            /// <returns>Counter value.</returns>
+            public int Counter()
+            {
+                return Interlocked.Increment(ref _ctr);
+            }
+
+            /// <summary>
+            /// Check whether this is the first throughput task.
+            /// </summary>
+            /// <returns>True if first.</returns>
+            public bool FirstThroughput()
+            {
+                return Interlocked.CompareExchange(ref _first, 1, 0) == 0;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/IBenchmarkResultWriter.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/IBenchmarkResultWriter.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/IBenchmarkResultWriter.cs
new file mode 100644
index 0000000..0c78b46
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/Result/IBenchmarkResultWriter.cs
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Benchmarks.Result
+{
+    using System.Collections.Generic;
+
+    /// <summary>
+    /// Result writer interface.
+    /// </summary>
+    internal interface IBenchmarkResultWriter
+    {
+        /// <summary>
+        /// Initialize writer.
+        /// </summary>
+        /// <param name="benchmark">Benchmark.</param>
+        /// <param name="opNames">Operation names.</param>
+        void Initialize(BenchmarkBase benchmark, ICollection<string> opNames);
+
+        /// <summary>
+        /// Write throughput results.
+        /// </summary>
+        /// <param name="opName">Operation name.</param>
+        /// <param name="duration">Duration.</param>
+        /// <param name="opCount">Operations count.</param>
+        void WriteThroughput(string opName, long duration, long opCount);
+
+        /// <summary>
+        /// Write percentile results.
+        /// </summary>
+        /// <param name="opName">Operation name.</param>
+        /// <param name="interval">Slot interval.</param>
+        /// <param name="slots">Slots.</param>
+        void WritePercentiles(string opName, long interval, long[] slots);
+
+        /// <summary>
+        /// Commit all results releasing all associated resources.
+        /// </summary>
+        void Commit();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
index 039813b..ffc6e34 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Tests.Compute
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Compute;
     using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Portable;
     using Apache.Ignite.Core.Resource;
     using NUnit.Framework;
@@ -1105,7 +1106,7 @@ namespace Apache.Ignite.Core.Tests.Compute
 
             cfg.PortableConfiguration = portCfg;
 
-            cfg.JvmClasspath = IgniteManager.CreateClasspath(cfg, true);
+            cfg.JvmClasspath = Classpath.CreateClasspath(cfg, true);
 
             cfg.JvmOptions = TestUtils.TestJavaOptions();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
index 055edcb..d806b36 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/PathUtil.cs
@@ -25,7 +25,7 @@ namespace Apache.Ignite.Core.Tests.Examples
     /// </summary>
     public static class PathUtil
     {
-        public static readonly string IgniteHome = 
IgniteManager.GetIgniteHome(null);
+        public static readonly string IgniteHome = 
Impl.Common.IgniteHome.Resolve(null);
 
         /// <summary>
         /// Full Apache.Ignite.exe path.

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
index 5a90c20..590f0e6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteManagerTest.cs
@@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Tests
     using System;
     using System.IO;
     using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Common;
     using NUnit.Framework;
 
     /// <summary>
@@ -33,18 +34,18 @@ namespace Apache.Ignite.Core.Tests
         [Test]
         public void TestIgniteHome()
         {
-            var env = 
Environment.GetEnvironmentVariable(IgniteManager.EnvIgniteHome);
-            
-            Environment.SetEnvironmentVariable(IgniteManager.EnvIgniteHome, 
null);
+            var env = 
Environment.GetEnvironmentVariable(IgniteHome.EnvIgniteHome);
+
+            Environment.SetEnvironmentVariable(IgniteHome.EnvIgniteHome, null);
 
             try
             {
-                
Assert.IsTrue(Directory.Exists(IgniteManager.GetIgniteHome(null)));
+                Assert.IsTrue(Directory.Exists(IgniteHome.Resolve(null)));
             }
             finally
             {
                 // Restore
-                
Environment.SetEnvironmentVariable(IgniteManager.EnvIgniteHome, env);
+                Environment.SetEnvironmentVariable(IgniteHome.EnvIgniteHome, 
env);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Process/IgniteProcess.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Process/IgniteProcess.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Process/IgniteProcess.cs
index fd08116..2d9fbeb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Process/IgniteProcess.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Process/IgniteProcess.cs
@@ -24,6 +24,7 @@ namespace Apache.Ignite.Core.Tests.Process
     using System.Text;
     using System.Threading;
     using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
     /// Defines forked Ignite node.
@@ -147,7 +148,7 @@ namespace Apache.Ignite.Core.Tests.Process
             // Add test dll path
             args = args.Concat(new[] {"-assembly=" + 
GetType().Assembly.Location}).ToArray();
 
-            _proc = Start(ExePath, IgniteManager.GetIgniteHome(null), 
outReader, args);
+            _proc = Start(ExePath, IgniteHome.Resolve(null), outReader, args);
         }
 
         /// <summary>
@@ -177,9 +178,9 @@ namespace Apache.Ignite.Core.Tests.Process
             };
 
             if (!string.IsNullOrEmpty(ggHome))
-                procStart.EnvironmentVariables[IgniteManager.EnvIgniteHome] = 
ggHome;
+                procStart.EnvironmentVariables[IgniteHome.EnvIgniteHome] = 
ggHome;
 
-            
procStart.EnvironmentVariables[IgniteManager.EnvIgniteNativeTestClasspath] = 
"true";
+            
procStart.EnvironmentVariables[Classpath.EnvIgniteNativeTestClasspath] = "true";
 
             procStart.CreateNoWindow = true;
             procStart.UseShellExecute = false;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
index 3287e2f..ea0c6ef 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
@@ -23,6 +23,7 @@ namespace Apache.Ignite.Core.Tests
     using System.Linq;
     using System.Threading;
     using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Tests.Process;
     using NUnit.Framework;
 
@@ -109,7 +110,7 @@ namespace Apache.Ignite.Core.Tests
         /// <returns></returns>
         public static string CreateTestClasspath()
         {
-            return IgniteManager.CreateClasspath(forceTestClasspath: true);
+            return Classpath.CreateClasspath(forceTestClasspath: true);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj 
b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 561273a..b776c0f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -170,6 +170,7 @@
     <Compile Include="Impl\Collections\ReadOnlyCollection.cs" />
     <Compile Include="Impl\Collections\ReadOnlyDictionary.cs" />
     <Compile Include="Impl\Common\AsyncResult.cs" />
+    <Compile Include="Impl\Common\Classpath.cs" />
     <Compile Include="Impl\Common\CompletedAsyncResult.cs" />
     <Compile Include="Impl\Common\CopyOnWriteConcurrentDictionary.cs" />
     <Compile Include="Impl\Common\DelegateConverter.cs" />
@@ -180,6 +181,7 @@
     <Compile Include="Impl\Common\IgniteArgumentCheck.cs" />
     <Compile Include="Impl\Common\IFutureConverter.cs" />
     <Compile Include="Impl\Common\IFutureInternal.cs" />
+    <Compile Include="Impl\Common\IgniteHome.cs" />
     <Compile Include="Impl\Common\LoadedAssembliesResolver.cs" />
     <Compile Include="Impl\Common\PortableResultWrapper.cs" />
     <Compile Include="Impl\Common\TypeCaster.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Classpath.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Classpath.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Classpath.cs
new file mode 100644
index 0000000..f1c8627
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/Classpath.cs
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Common
+{
+    using System;
+    using System.Text;
+    using System.IO;
+
+    /// <summary>
+    /// Classpath resolver.
+    /// </summary>
+    internal static class Classpath
+    {
+        /** Environment variable: whether to set test classpath or not. */
+        internal const string EnvIgniteNativeTestClasspath = 
"IGNITE_NATIVE_TEST_CLASSPATH";
+
+        /** Classpath prefix. */
+        private const string ClasspathPrefix = "-Djava.class.path=";
+
+        /// <summary>
+        /// Creates classpath from the given configuration, or default 
classpath if given config is null.
+        /// </summary>
+        /// <param name="cfg">The configuration.</param>
+        /// <param name="forceTestClasspath">Append test directories even if 
<see cref="EnvIgniteNativeTestClasspath" /> is not set.</param>
+        /// <returns>
+        /// Classpath string.
+        /// </returns>
+        public static string CreateClasspath(IgniteConfiguration cfg = null, 
bool forceTestClasspath = false)
+        {
+            return CreateClasspath(IgniteHome.Resolve(cfg), cfg, 
forceTestClasspath);
+        }
+
+        /// <summary>
+        /// Creates classpath from the given configuration, or default 
classpath if given config is null.
+        /// </summary>
+        /// <param name="ggHome">The home dir.</param>
+        /// <param name="cfg">The configuration.</param>
+        /// <param name="forceTestClasspath">Append test directories even if
+        ///     <see cref="EnvIgniteNativeTestClasspath" /> is not set.</param>
+        /// <returns>
+        /// Classpath string.
+        /// </returns>
+        internal static string CreateClasspath(string ggHome, 
IgniteConfiguration cfg, bool forceTestClasspath)
+        {
+            var cpStr = new StringBuilder();
+
+            if (cfg != null && cfg.JvmClasspath != null)
+            {
+                cpStr.Append(cfg.JvmClasspath);
+
+                if (!cfg.JvmClasspath.EndsWith(";"))
+                    cpStr.Append(';');
+            }
+
+            if (!string.IsNullOrWhiteSpace(ggHome))
+                AppendHomeClasspath(ggHome, forceTestClasspath, cpStr);
+
+            return ClasspathPrefix + cpStr;
+        }
+
+        /// <summary>
+        /// Appends classpath from home directory, if it is defined.
+        /// </summary>
+        /// <param name="ggHome">The home dir.</param>
+        /// <param name="forceTestClasspath">Append test directories even if
+        ///     <see cref="EnvIgniteNativeTestClasspath"/> is not set.</param>
+        /// <param name="cpStr">The classpath string.</param>
+        private static void AppendHomeClasspath(string ggHome, bool 
forceTestClasspath, StringBuilder cpStr)
+        {
+            // Append test directories (if needed) first, because otherwise 
build *.jar will be picked first.
+            if (forceTestClasspath || 
"true".Equals(Environment.GetEnvironmentVariable(EnvIgniteNativeTestClasspath)))
+            {
+                AppendTestClasses(ggHome + "\\examples", cpStr);
+                AppendTestClasses(ggHome + "\\modules", cpStr);
+            }
+
+            string ggLibs = ggHome + "\\libs";
+
+            AppendJars(ggLibs, cpStr);
+
+            if (Directory.Exists(ggLibs))
+            {
+                foreach (string dir in Directory.EnumerateDirectories(ggLibs))
+                {
+                    if (!dir.EndsWith("optional"))
+                        AppendJars(dir, cpStr);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Append target (compile) directories to classpath (for testing 
purposes only).
+        /// </summary>
+        /// <param name="path">Path</param>
+        /// <param name="cp">Classpath builder.</param>
+        private static void AppendTestClasses(string path, StringBuilder cp)
+        {
+            if (Directory.Exists(path))
+            {
+                AppendTestClasses0(path, cp);
+
+                foreach (string moduleDir in 
Directory.EnumerateDirectories(path))
+                    AppendTestClasses0(moduleDir, cp);
+            }
+        }
+
+        /// <summary>
+        /// Internal routine to append classes and jars from eploded directory.
+        /// </summary>
+        /// <param name="path">Path.</param>
+        /// <param name="cp">Classpath builder.</param>
+        private static void AppendTestClasses0(string path, StringBuilder cp)
+        {
+            if (path.EndsWith("rest-http", StringComparison.OrdinalIgnoreCase))
+                return;
+
+            if (Directory.Exists(path + "\\target\\classes"))
+                cp.Append(path + "\\target\\classes;");
+
+            if (Directory.Exists(path + "\\target\\test-classes"))
+                cp.Append(path + "\\target\\test-classes;");
+
+            if (Directory.Exists(path + "\\target\\libs"))
+                AppendJars(path + "\\target\\libs", cp);
+        }
+
+        /// <summary>
+        /// Append jars from the given path.
+        /// </summary>
+        /// <param name="path">Path.</param>
+        /// <param name="cpStr">Classpath string builder.</param>
+        private static void AppendJars(string path, StringBuilder cpStr)
+        {
+            if (Directory.Exists(path))
+            {
+                foreach (string jar in Directory.EnumerateFiles(path, "*.jar"))
+                {
+                    cpStr.Append(jar);
+                    cpStr.Append(';');
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteHome.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteHome.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteHome.cs
new file mode 100644
index 0000000..335c55a
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/IgniteHome.cs
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Common
+{
+    using System;
+    using System.Linq;
+    using System.IO;
+    using System.Reflection;
+    using Apache.Ignite.Core.Common;
+
+    /// <summary>
+    /// IgniteHome resolver.
+    /// </summary>
+    internal static class IgniteHome
+    {
+        /** Environment variable: IGNITE_HOME. */
+        internal const string EnvIgniteHome = "IGNITE_HOME";
+
+        /// <summary>
+        /// Calculate Ignite home.
+        /// </summary>
+        /// <param name="cfg">Configuration.</param>
+        /// <returns></returns>
+        public static string Resolve(IgniteConfiguration cfg)
+        {
+            var home = cfg == null ? null : cfg.IgniteHome;
+
+            if (string.IsNullOrWhiteSpace(home))
+                home = Environment.GetEnvironmentVariable(EnvIgniteHome);
+            else if (!IsIgniteHome(new DirectoryInfo(home)))
+                throw new 
IgniteException(string.Format("IgniteConfiguration.IgniteHome is not valid: 
'{0}'", home));
+
+            if (string.IsNullOrWhiteSpace(home))
+                home = Resolve();
+            else if (!IsIgniteHome(new DirectoryInfo(home)))
+                throw new IgniteException(string.Format("{0} is not valid: 
'{1}'", EnvIgniteHome, home));
+
+            return home;
+        }
+
+        /// <summary>
+        /// Automatically resolve Ignite home directory.
+        /// </summary>
+        /// <returns>Ignite home directory.</returns>
+        private static string Resolve()
+        {
+            var probeDirs = new[]
+            {
+                
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+                Directory.GetCurrentDirectory()
+            };
+
+            foreach (var probeDir in probeDirs.Where(x => 
!string.IsNullOrEmpty(x)))
+            {
+                var dir = new DirectoryInfo(probeDir);
+
+                while (dir != null)
+                {
+                    if (IsIgniteHome(dir))
+                        return dir.FullName;
+
+                    dir = dir.Parent;
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Determines whether specified dir looks like a Ignite home.
+        /// </summary>
+        /// <param name="dir">Directory.</param>
+        /// <returns>Value indicating whether specified dir looks like a 
Ignite home.</returns>
+        private static bool IsIgniteHome(DirectoryInfo dir)
+        {
+            return dir.Exists &&
+                   dir.EnumerateDirectories().Count(x => x.Name == "examples" 
|| x.Name == "bin") == 2 &&
+                   (dir.EnumerateDirectories().Count(x => x.Name == "modules") 
== 1 ||
+                    dir.EnumerateDirectories().Count(x => x.Name == 
"platforms") == 1);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs
index af2557c..67af684 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs
@@ -21,12 +21,10 @@ namespace Apache.Ignite.Core.Impl
     using System.Collections.Generic;
     using System.Diagnostics.CodeAnalysis;
     using System.Globalization;
-    using System.IO;
     using System.Linq;
-    using System.Reflection;
     using System.Runtime.InteropServices;
     using System.Text;
-    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Memory;
     using Apache.Ignite.Core.Impl.Unmanaged;
     using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
@@ -36,15 +34,6 @@ namespace Apache.Ignite.Core.Impl
     /// </summary>
     internal static unsafe class IgniteManager
     {
-        /** Environment variable: IGNITE_HOME. */
-        internal const string EnvIgniteHome = "IGNITE_HOME";
-
-        /** Environment variable: whether to set test classpath or not. */
-        internal const string EnvIgniteNativeTestClasspath = 
"IGNITE_NATIVE_TEST_CLASSPATH";
-        
-        /** Classpath prefix. */
-        private const string ClasspathPrefix = "-Djava.class.path=";
-
         /** Java Command line argument: Xms. Case sensitive. */
         private const string CmdJvmMinMemJava = "-Xms";
 
@@ -132,9 +121,9 @@ namespace Apache.Ignite.Core.Impl
         /// <returns>JVM.</returns>
         private static void* CreateJvm(IgniteConfiguration cfg, 
UnmanagedCallbacks cbs)
         {
-            var ggHome = GetIgniteHome(cfg);
+            var ggHome = IgniteHome.Resolve(cfg);
 
-            var cp = CreateClasspath(ggHome, cfg, false);
+            var cp = Classpath.CreateClasspath(ggHome, cfg, false);
 
             var jvmOpts = GetMergedJvmOptions(cfg);
             
@@ -211,195 +200,6 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /// <summary>
-        /// Append jars from the given path.
-        /// </summary>
-        /// <param name="path">Path.</param>
-        /// <param name="cpStr">Classpath string builder.</param>
-        private static void AppendJars(string path, StringBuilder cpStr)
-        {
-            if (Directory.Exists(path))
-            {
-                foreach (string jar in Directory.EnumerateFiles(path, "*.jar"))
-                {
-                    cpStr.Append(jar);
-                    cpStr.Append(';');
-                }
-            }
-        }
-
-        /// <summary>
-        /// Calculate Ignite home.
-        /// </summary>
-        /// <param name="cfg">Configuration.</param>
-        /// <returns></returns>
-        internal static string GetIgniteHome(IgniteConfiguration cfg)
-        {
-            var home = cfg == null ? null : cfg.IgniteHome;
-
-            if (string.IsNullOrWhiteSpace(home))
-                home = Environment.GetEnvironmentVariable(EnvIgniteHome);
-            else if (!IsIgniteHome(new DirectoryInfo(home)))
-                throw new 
IgniteException(string.Format(CultureInfo.InvariantCulture, 
-                    "IgniteConfiguration.IgniteHome is not valid: '{0}'", 
home));
-
-            if (string.IsNullOrWhiteSpace(home))
-                home = ResolveIgniteHome();
-            else if (!IsIgniteHome(new DirectoryInfo(home)))
-                throw new 
IgniteException(string.Format(CultureInfo.InvariantCulture, 
-                    "{0} is not valid: '{1}'", EnvIgniteHome, home));
-
-            return home;
-        }
-
-        /// <summary>
-        /// Automatically resolve Ignite home directory.
-        /// </summary>
-        /// <returns>Ignite home directory.</returns>
-        private static string ResolveIgniteHome()
-        {
-            var probeDirs = new[]
-            {
-                
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
-                Directory.GetCurrentDirectory()
-            };
-
-            foreach (var probeDir in probeDirs.Where(x => 
!string.IsNullOrEmpty(x)))
-            {
-                var dir = new DirectoryInfo(probeDir);
-
-                while (dir != null)
-                {
-                    if (IsIgniteHome(dir))
-                        return dir.FullName;
-
-                    dir = dir.Parent;
-                }
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Determines whether specified dir looks like a Ignite home.
-        /// </summary>
-        /// <param name="dir">Directory.</param>
-        /// <returns>Value indicating whether specified dir looks like a 
Ignite home.</returns>
-        private static bool IsIgniteHome(DirectoryInfo dir)
-        {
-            return dir.Exists &&
-                dir.EnumerateDirectories().Count(x => x.Name == "examples" || 
x.Name == "bin") == 2 &&
-                (dir.EnumerateDirectories().Count(x => x.Name == "modules") == 
1 ||
-                    dir.EnumerateDirectories().Count(x => x.Name == 
"platforms") == 1);
-        }
-
-        /// <summary>
-        /// Creates classpath from the given configuration, or default 
classpath if given config is null.
-        /// </summary>
-        /// <param name="cfg">The configuration.</param>
-        /// <param name="forceTestClasspath">Append test directories even if 
<see cref="EnvIgniteNativeTestClasspath" /> is not set.</param>
-        /// <returns>
-        /// Classpath string.
-        /// </returns>
-        internal static string CreateClasspath(IgniteConfiguration cfg = null, 
bool forceTestClasspath = false)
-        {
-            return CreateClasspath(GetIgniteHome(cfg), cfg, 
forceTestClasspath);
-        }
-
-        /// <summary>
-        /// Creates classpath from the given configuration, or default 
classpath if given config is null.
-        /// </summary>
-        /// <param name="ggHome">The home dir.</param>
-        /// <param name="cfg">The configuration.</param>
-        /// <param name="forceTestClasspath">Append test directories even if
-        ///     <see cref="EnvIgniteNativeTestClasspath" /> is not set.</param>
-        /// <returns>
-        /// Classpath string.
-        /// </returns>
-        private static string CreateClasspath(string ggHome, 
IgniteConfiguration cfg, bool forceTestClasspath)
-        {
-            var cpStr = new StringBuilder();
-
-            if (cfg != null && cfg.JvmClasspath != null)
-            {
-                cpStr.Append(cfg.JvmClasspath);
-
-                if (!cfg.JvmClasspath.EndsWith(";", StringComparison.Ordinal))
-                    cpStr.Append(';');
-            }
-
-            if (!string.IsNullOrWhiteSpace(ggHome))
-                AppendHomeClasspath(ggHome, forceTestClasspath, cpStr);
-
-            return ClasspathPrefix + cpStr;
-        }
-
-        /// <summary>
-        /// Appends classpath from home directory, if it is defined.
-        /// </summary>
-        /// <param name="ggHome">The home dir.</param>
-        /// <param name="forceTestClasspath">Append test directories even if
-        ///     <see cref="EnvIgniteNativeTestClasspath"/> is not set.</param>
-        /// <param name="cpStr">The classpath string.</param>
-        private static void AppendHomeClasspath(string ggHome, bool 
forceTestClasspath, StringBuilder cpStr)
-        {
-            // Append test directories (if needed) first, because otherwise 
build *.jar will be picked first.
-            if (forceTestClasspath || 
"true".Equals(Environment.GetEnvironmentVariable(EnvIgniteNativeTestClasspath)))
-            {
-                AppendTestClasses(ggHome + "\\examples", cpStr);
-                AppendTestClasses(ggHome + "\\modules", cpStr);
-            }
-
-            string ggLibs = ggHome + "\\libs";
-
-            AppendJars(ggLibs, cpStr);
-
-            if (Directory.Exists(ggLibs))
-            {
-                foreach (string dir in Directory.EnumerateDirectories(ggLibs))
-                {
-                    if (!dir.EndsWith("optional", 
StringComparison.OrdinalIgnoreCase))
-                        AppendJars(dir, cpStr);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Append target (compile) directories to classpath (for testing 
purposes only).
-        /// </summary>
-        /// <param name="path">Path</param>
-        /// <param name="cp">Classpath builder.</param>
-        private static void AppendTestClasses(string path, StringBuilder cp)
-        {
-            if (Directory.Exists(path))
-            {
-                AppendTestClasses0(path, cp);
-
-                foreach (string moduleDir in 
Directory.EnumerateDirectories(path))
-                    AppendTestClasses0(moduleDir, cp);
-            }
-        }
-
-        /// <summary>
-        /// Internal routine to append classes and jars from eploded directory.
-        /// </summary>
-        /// <param name="path">Path.</param>
-        /// <param name="cp">Classpath builder.</param>
-        private static void AppendTestClasses0(string path, StringBuilder cp)
-        {
-            if (path.EndsWith("rest-http", StringComparison.OrdinalIgnoreCase))
-                return;
-            
-            if (Directory.Exists(path + "\\target\\classes"))
-                cp.Append(path + "\\target\\classes;");
-
-            if (Directory.Exists(path + "\\target\\test-classes"))
-                cp.Append(path + "\\target\\test-classes;");
-
-            if (Directory.Exists(path + "\\target\\libs"))
-                AppendJars(path + "\\target\\libs", cp);
-        }
-
-        /// <summary>
         /// JVM configuration.
         /// </summary>
         private class JvmConfiguration

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
index 1bcb658..71d3247 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs
@@ -42,5 +42,6 @@ using System.Runtime.InteropServices;
 
 [assembly: InternalsVisibleTo("Apache.Ignite")]
 [assembly: InternalsVisibleTo("Apache.Ignite.Core.Tests")]
+[assembly: InternalsVisibleTo("Apache.Ignite.Benchmarks")]
 
 #endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/3852b0b6/modules/platforms/dotnet/Apache.Ignite.sln
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.sln 
b/modules/platforms/dotnet/Apache.Ignite.sln
index 64355aa..8d93ffd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.sln
+++ b/modules/platforms/dotnet/Apache.Ignite.sln
@@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = 
"Apache.Ignite.ExamplesDll",
                {27F7F3C6-BDDE-43A9-B565-856F8395A04B} = 
{27F7F3C6-BDDE-43A9-B565-856F8395A04B}
        EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = 
"Apache.Ignite.Benchmarks", 
"Apache.Ignite.Benchmarks\Apache.Ignite.Benchmarks.csproj", 
"{8F507DBE-56F9-437F-82D4-74C02EC44E41}"
+EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", 
"Solution Items", "{E0784F76-949C-456E-A529-A55D0E389165}"
        ProjectSection(SolutionItems) = preProject
                Apache.Ignite.FxCop = Apache.Ignite.FxCop
@@ -90,6 +92,14 @@ Global
                {DFB08363-202E-412D-8812-349EF10A8702}.Release|x64.Build.0 = 
Release|x64
                {DFB08363-202E-412D-8812-349EF10A8702}.Release|x86.ActiveCfg = 
Release|x86
                {DFB08363-202E-412D-8812-349EF10A8702}.Release|x86.Build.0 = 
Release|x86
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Debug|x64.ActiveCfg = 
Debug|x64
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Debug|x64.Build.0 = 
Debug|x64
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Debug|x86.ActiveCfg = 
Debug|x86
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Debug|x86.Build.0 = 
Debug|x86
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Release|x64.ActiveCfg = 
Release|x64
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Release|x64.Build.0 = 
Release|x64
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Release|x86.ActiveCfg = 
Release|x86
+               {8F507DBE-56F9-437F-82D4-74C02EC44E41}.Release|x86.Build.0 = 
Release|x86
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE


Reply via email to