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