Tuesday, December 20, 2016

C++ Unit Test Framework Catch


1. class comparison in REQUIRE need operator == and  toString/template specialization/insertion operator
2. CATCH_TRANSLATE_EXCEPTION customize ex.message

 #define CATCH_CONFIG_MAIN  in stdafx.h

#include "stdafx.h"
#include "c:\__tools\catch.hpp"
#include <ostream>
#include <exception>

 class Book
{
public:
 int Id;
 bool operator==(const Book& b)
 {
  return b.Id == Id;
 }

};

//std::ostream& operator<<(std::ostream& os, Book const& b)
// {
// os << "overloading OS";
// return os;
//};
namespace Catch {
 template<> struct StringMaker<Book> {
  static std::string convert(Book const& value)
  {
   return "String Maker Specialization";
  }
 };

 //std::string toString(Book const& i)
 //{
 // return "to string for Book";
 //}
}
class myException : public std::exception
{
public:
 virtual const char* what() const throw()
 {
  return " my exception";
 }
};

CATCH_TRANSLATE_EXCEPTION(myException& ex)
{
 return ex.what();
}

TEST_CASE("This is a catch test","[Equal][LOG]")
{
 Book b1, b2;
 b1.Id = 90;
 INFO("Start Testing");
 REQUIRE(b1 == b2);
 WARN("One assertion failed");
 REQUIRE_FALSE(1 == 1);

}

TEST_CASE("This is another catch test","[CHK][EXP]")
{
 CHECK_FALSE(1 == 1);
 throw myException();
}



Saturday, December 10, 2016

Compile Time Check IsNullable and IsReferenceType


        public TimeSpan i { get; set; }
        public TimeSpan? j { get; set; }
        public string k { get; set; }
        public Status? Status { get; set; }
        public Data st1 { get; set; }
        public Data? st2 { get; set; }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            
            bool b1 = IsNullable(i);
            bool b2 = IsNullable(j);
            bool b3 = IsNullable(k);
            bool b4 = IsNullable(Status);
            bool b5 = IsNullable(st1);
            bool b6 = IsNullable(st2);
            bool b7 = IsReferenceType(k);
        }
         static bool IsNullable<T>(T t) { return false; }
         static bool IsNullable<T>(T? t) where T : struct { return true; }
         static bool IsReferenceType<T>(T t) where T : class { return true; }
    

    public enum Status
    {
        None,
        Ok,
        Error
    }

    public struct Data
    {

    }

Thursday, December 8, 2016

Shift Operator, ilog2 and test power of 2

(1) shift left of 1 generate all powers of 2.
(2) ilog2 is template specialization.
(3) shift 1 by ilog2(n) will get back n for power of 2 only
(4) compiler say too complex when using recursion for non-template function is_power_of_2

#include "stdafx.h"
#include <iostream>

using namespace std;

template <size_t X>
struct ilog2
{
 enum {value=(1+ilog2<X/2>::value) };
};

template<>
struct ilog2<1> {enum {value=0}; };

template<size_t N>
bool is_pow_of_2()
{
 return ((size_t)1 << ilog2<N>::value == N);
};

int main() {
 
 cout << (1 << 3) << endl; // 8
 cout << (1 << 9) << endl; // 512=2 power 9
 
 cout << ((size_t)1 << ilog2<9>::value == 9) << endl;
 cout << ((size_t)1 << ilog2<512>::value == 512) << endl;
 
 cout << is_pow_of_2<9>() << endl;
 cout << is_pow_of_2<512>() << endl;
 return 0;
}



Wednesday, December 7, 2016

locking, lock free and wait free

locking --- lock_guard + mutex
lock free --- atomic + CAS
wait free --- atomic +fetch_add
ring buffer-- producer makes progress without any wait, so wait-free.


using namespace std;
typedef unsigned long ulong;

ulong _shared = 123UL;
int main() {
 {
  ulong* p=nullptr;  //locking
  *p = _shared;
  mutex M;
  {
   lock_guard<mutex> l(M);
   ++(*p);
  }
 }
 atomic<ulong>* p=0;  //lock free
 *p = _shared;
 ulong xl = p->load(memory_order_relaxed);
 while (!p->compare_exchange_strong(xl, xl + 1, std::memory_order_relaxed)) {}

 p->fetch_add(1, memory_order_relaxed);  //wait free


 // cache line is 64 bytes, ul is 8 bytes, so thread>8=> sit on separate cache line, no sharing faster.

 

 return 0;
}

lock_guard vs shared_lock is exclusive vs. shared in c++14

(1) C++ 14/17 rare write mostly read is Microsoft  ReaderWriter Lock concept.
(2) lock_guard also aware of how many shared lock in effect before exclude locking so some overhead.
(3) shared_lock can try timed 1 ms to see if writing in progress and give up
(4) both lock_guard and shared_lock construct on the same shared_timed_mutex


std::map<std::string, std::string> _map;
std::shared_timed_mutex m;

std::string find_entry(std::string s)
{
 std::shared_lock<std::shared_timed_mutex> guard(m);
 auto it = _map.find(s);
 if (it == _map.end())
 {
  throw runtime_error("not found");
 }
 return it->second;
}
void add_entry(std::string key,::string s)
{
 std::lock_guard<std::shared_timed_mutex> guard(m);
 _map.insert(make_pair(key,s));
}

void do_work_if_get_lock_in_1sec()
{
 shared_lock<shared_timed_mutex> sl(m, std::chrono::seconds(1));
 if (!sl.owns_lock())
  return;
 //do work after getting lock
}

Saturday, December 3, 2016

JSON Tester


#include "stdafx.h"
#include <iostream>
#include "JSONWrapper.hpp"
#include "render.hpp"

using namespace std;

int main() {

 JSONWrapper jw, jw1, jw2;
 //jw.value = true;
 //jw.value = 123.45;
 //jw.value = std::string{ "test" };
 //jw.value = nullptr;

 
 jw1.value = 678.90;
 jw2.value = true;

 JSONArray a{ jw1,jw2 };
 JSONArray b{ jw1,jw2 };
 //jw.value = a;

 JSONObject obj;
 obj.insert(std::pair<string, JSONArray>("k1", a));
 obj["k2"] = b;
 jw.value = obj;
 
 cout << render_json_value(jw.value) << endl;

 return 0;
}



fold.cpp recursion with compile time constant

(1) boost variant size =20, JSONValue variant=6
(2) v.which() = index
(3) using =typedef and decltype is to get typeinfo
(4) (n,N) recursion, Compile constant N=0, N+1 force n recurs 1 more time to get to n=N  
(5) have not see example Max,Max get called

#pragma once
#include <string>
#include <boost\variant.hpp>
#include "render.hpp"
#include "get2.hpp"

using namespace std;

template<size_t N, size_t Max>
struct apply_at
{
 template<typename R, typename T, typename F, typename...Fs>
 static string apply(T&& t, size_t n, F&& f, Fs&&... fs)
 {
  if (n == N)
  {
    return forward<F>(f)(get2<N>(boost::forward<T>(t)));
  }
  else
  {
   return apply_at<N + 1, Max>::template apply<R, T, Fs...>(
    boost::forward<T>(t),
    n,
    forward<Fs>(fs)...);
  }
 }
};

template<size_t Max>
struct apply_at<Max, Max>
{
 template<typename R, typename T, typename...Fs>
 static string apply(T, size_t, Fs...)
 {
  return R();
 }
};

template<typename T,typename F, typename...Fs>
static string fold_at(T&& t, size_t n, F&& f, Fs&&... fs)
{
  using R = decltype(f(get2<0>(t)));
  return apply_at<0, sizeof...(Fs)+1>::template apply<R,T, F, Fs...>(
   boost::forward<T>(t),
   n,
   forward<F>(f),
   forward<Fs>(fs)...
   );
};

template <typename... Ts, typename... Fs>
string fold(const boost::variant<Ts...>& v, Fs&&... fs)
{
 // size boost::variant=60, JSONValue=6, so assert fail
 //static_assert(sizeof...(Ts) == sizeof...(Fs), "# of fun and variant not matching.");
 return fold_at(
  v, v.which(), forward<Fs>(fs)...
 );
};

6 function of JSON render matching 6 type in JSON variant


#pragma once
#include <string>
#include <sstream>
#include "JSONWrapper.hpp"
#include "join.hpp"
#include "fold.hpp"
#include <iomanip>

using namespace std;

string render_bool(bool b) { return b ? "true" : "false"; }
string render_double(double d) { return to_string(d); }
string render_null(nullptr_t) { return "null"; }
string render_string(const string& s)
{
 stringstream ss;
 ss << std::quoted(s);
 return ss.str();
}

string render_json_value(const JSONValue& jsv);

string render_object(const JSONObject& obj)
{
 return string{ "[" }+
  join(obj.begin(), obj.end(), string{ "." },
   [](const JSONObject::value_type& jsv) {
  return render_string(jsv.first) + ":" + render_json_value(jsv.second);
 }) + "]";
}

string render_array(const JSONArray& a)
{
 return string{ "[" }+
  join(a.begin(), a.end(), string{ "," },
   [](const JSONValue& jsv) {
  return render_json_value(jsv);
 }) + "]";
}

string render_json_value(const JSONValue& jsv)
{
 return fold(jsv,
  render_bool, render_double, render_string,
  render_null, render_array, render_object);
}

join.cpp on iterator though vector and map


#pragma once
#include "JSONWrapper.hpp"
#include <functional>

#include <string>

using namespace std;

string join(JSONObject::const_iterator first, JSONObject::const_iterator last, string delimitor,
 std::function<string(const JSONObject::value_type&)> func)
{
 string ret = "";
 for (;first!= last; first++)
 {
  ret += func(*first) + delimitor;
 }
 return ret;
}

string join(JSONArray::const_iterator first, JSONArray::const_iterator last, string delimitor,
 std::function<string(const JSONValue&)> func)
{
 string ret = "";
 for (;first!= last; first++)
 {
  ret += func(*first) + delimitor;
 }
 return ret;
}


Friday, December 2, 2016

get boost variant value using template specialization on literal value

It seems C++17 will have get<0> and get<N> but boost does not have that yet.
boost only have get<type> and which=0,1,2,3,4,5
The following specialization can hack get<N> for now

#pragma once
#include <boost\variant\get.hpp>
#include "JSONWrapper.hpp"
#include <string>

template<int N>
auto get2(JSONValue jsv);

template<>
auto get2<0>(JSONValue jsv)
{
 return boost::get<bool>(jsv);
}

template<>
auto get2<1>(JSONValue jsv)
{
 return boost::get<double>(jsv);
}

template<>
auto get2<2>(JSONValue jsv)
{
 return boost::get<std::string>(jsv);
}

template<>
auto get2<3>(JSONValue jsv)
{
 return boost::get<nullptr_t>(jsv);
}

template<>
auto get2<4>(JSONValue jsv)
{
 return boost::get<JSONArray>(jsv);
}

template<>
auto get2<5>(JSONValue jsv)
{
 return boost::get<JSONObject>(jsv);
}

boost variant defines JSON Wrapper


Note operator JSONValue&() const meant  jw.operator const JSONValue&() the same as jw as in
cout<<render_json_value(jw)<<endl;

#include <vector>
#include <map>
#include <boost\variant.hpp>

typedef decltype(nullptr) nullptr_t;
struct JSONWrapper;
using JSONArray = std::vector<JSONWrapper>;
typedef std::map<std::string, JSONArray> JSONObject;
using JSONValue = boost::variant<bool, double, std::string, nullptr_t, JSONArray, JSONObject>;

struct JSONWrapper {
 JSONValue value;
 operator JSONValue&() { return value; }
 operator const JSONValue&() const { return value; }
};

Tuesday, November 22, 2016

Validate Two properties

to make sure one property change trigger the other property run validation logic,
must call OnVilidate Code into IDataErrorInfo type of logic in its property Setter

<TextBox Grid.Column="1" Text="{Binding ...,ValidatesOnDataErrors=True,NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxWithValidationStyle}">


[MustBeGreaterLessThanAllowSuffix("TheOther", false, true, ErrorMessage = "Please specify ..")]

using System;

using System.ComponentModel.DataAnnotations;

using System.Linq;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]

public class MustBeGreaterLessThanAllowSuffixAttribute : ValidationAttribute

{

public string CompareToPropertyName { get; private set; }

public bool Greater { get; private set; }

public bool IncludeEqual { get; private set; }

public object[] Values { get; private set; }

private static readonly char[] SUFFIXES = new char[4] { 'M', 'm', 'K', 'k' };

public MustBeGreaterLessThanAllowSuffixAttribute(string compareToPropertyName,bool greater,bool includeEqual, params object[] values)

{

CompareToPropertyName = compareToPropertyName;

Greater = greater;

IncludeEqual = includeEqual;

Values = values;

}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)

{

var compToProperty = validationContext.ObjectType.GetProperty(CompareToPropertyName);

var compToValue = compToProperty.GetValue(validationContext.ObjectInstance, null);

return VerifyValidGreaterThanCondition(value, compToValue) ? ValidationResult.Success : new ValidationResult(ErrorMessage);

}

private bool VerifyValidGreaterThanCondition(object value, object compToValue)

{

if (value == null || compToValue == null)

{

return true;

}

string valueNoSuffix = value.ToString().TrimEnd(SUFFIXES);

string compToValueNoSuffix = compToValue.ToString().TrimEnd(SUFFIXES);

double dValue, dCompToValue;

if (!double.TryParse(valueNoSuffix, out dValue) || !double.TryParse(compToValueNoSuffix, out dCompToValue))

{

return true;

}

var dValueMutiplied = dValue * GetMultiplier(value);

var dCompToValueMutiplied = dCompToValue * GetMultiplier(compToValue);

if (Greater)

{

return IncludeEqual ? dValueMutiplied >= dCompToValueMutiplied : dValueMutiplied > dCompToValueMutiplied;

}

return IncludeEqual ? dValueMutiplied <= dCompToValueMutiplied : dValueMutiplied < dCompToValueMutiplied;

}

private double GetMultiplier(object value)

{

if(value==null)

return 1.0;

char suffix = value.ToString().LastOrDefault();

switch (suffix)

{

case 'M':

case 'm':

return 1E6;

case 'K':

case 'k':

return 1E3;

}

return 1.0;

}



[CustomValidation(typeof(VegaTraderSettingValidator), "Check")]

using System.ComponentModel.DataAnnotations;

public class VegaTraderSettingValidator

{

public static ValidationResult Check(string s)

{

return ValidationResult.Success;

}

}



[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]

public class MutualExclusiveDataEntryAttribute : ValidationAttribute

{

public string MutualExclusivePropertyName { get; private set; }

public MutualExclusiveDataEntryAttribute(string mutualExclusivePropertyName)

{

MutualExclusivePropertyName = mutualExclusivePropertyName;

}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)

{

var mutProperty = validationContext.ObjectType.GetProperty(MutualExclusivePropertyName);

if (mutProperty == null)

return ValidationResult.Success;

var mutValue = mutProperty.GetValue(validationContext.ObjectInstance, null);

return VerifyMutualExclsivity(value, mutValue) ? ValidationResult.Success : new ValidationResult(ErrorMessage);

}

private bool VerifyMutualExclsivity(object value, object mutValue)

{

if (value == null || mutValue == null)

return true;

if (!value.IsDefault() && !mutValue.IsDefault())

return false;

return true;

}

}




Saturday, November 19, 2016

Attached Property based TextBox RegEx mask



                {
                    var localTxt = lastValidText;
                    var proposedText = GetProposedText(tbInstance, e1.Text);
                    if (!maskRegEx.IsMatch(proposedText))
                    {
                        e1.Handled = true;
                    }
                };
                
                tbInstance.Loaded += (s, e1) =>
                {
                    if (maskRegEx.IsMatch(tbInstance.Text))
                    {
                        lastValidText = tbInstance.Text;
                        SetHasRegExMisMatch(tbInstance,false);
                    }
                    else
                    {
                        SetHasRegExMisMatch(tbInstance, true);
                    }
                };

                tbInstance.TextChanged += (s, e1) =>
                {
                    if (maskRegEx.IsMatch(tbInstance.Text))
                    {
                        lastValidText = tbInstance.Text;
                        SetHasRegExMisMatch(tbInstance, false);
                    }
                    else
                    {
                        SetHasRegExMisMatch(tbInstance, true);
                    }
                };

                tbInstance.PreviewLostKeyboardFocus += (s, e1) =>
                {
                    var localTxt = lastValidText;
                    if (!maskRegEx.IsMatch(tbInstance.Text))
                    {
                        SetHasRegExMisMatch(tbInstance, true);
                        e1.Handled = true;
                        tbInstance.Text = localTxt;
                        tbInstance.CaretIndex = 99;
                    }
                    else
                    {
                        SetHasRegExMisMatch(tbInstance, false);
                    }
                };            
        }

        private static string GetProposedText(TextBox textBox, string newText)
        {
            var text = textBox.Text;

            if (textBox.SelectionStart != -1)
            {
                text = text.Remove(textBox.SelectionStart, textBox.SelectionLength);
            }

            text = text.Insert(textBox.CaretIndex, newText);

            return text;
        }
    }


C# implicit operator for conversion

implicit operator is conversion operator. 
  //Tuple with Parameter-Less Ctor to enable serialization
    [Serializable]
    public class Tuple2<T1, T2>
    {
        public Tuple2() { }

        public T1 Item1 { get; set; }
        public T2 Item2 { get; set; }

        public static implicit operator Tuple2<T1, T2>(Tuple<T1, T2> t)
        {
            return new Tuple2<T1, T2>()
            {
                Item1 = t.Item1,
                Item2 = t.Item2
            };
        }

        public static implicit operator Tuple<T1, T2>(Tuple2<T1, T2> t)
        {
            return Tuple.Create(t.Item1, t.Item2);
        }
    }

Tuesday, November 15, 2016

Using Pixel shader to highlight data grid row

/// <summary>
    /// Dev Express GridControl does not support multi selection when Master-Detail rows are involved. This behavior highlights multiple rows
    /// and persist onto ViewModel. So it has the effect of multiple selection.
    /// </summary>
    public class MultiRowHighlightBehavior : Behavior<GridControl>
    {

        #region properties

        public int MaxNumberOfRowsHighlighted
        {
            get { return (int)this.GetValue(MaxNumberOfRowsHighlightedProperty); }
            set { this.SetValue(MaxNumberOfRowsHighlightedProperty, value); }
        }
        public static readonly DependencyProperty MaxNumberOfRowsHighlightedProperty = DependencyProperty.Register(
          "MaxNumberOfRowsHighlighted", typeof(int), typeof(MultiRowHighlightBehavior), new PropertyMetadata(int.MaxValue));

        // use IList, INotifyCollectionChanged to avoid generic in DP def e.g. ObservableCollection<T>

        // Pass highlighted Data Rows to VM
        public IList ViewModelHighlightedRows
        {
            get { return (IList)this.GetValue(ViewModelHighlightedRowsProperty); }
            set { this.SetValue(ViewModelHighlightedRowsProperty, value); }
        }
        public static readonly DependencyProperty ViewModelHighlightedRowsProperty = DependencyProperty.Register(
          "ViewModelHighlightedRows", typeof(IList), typeof(MultiRowHighlightBehavior), new PropertyMetadata(null));

        // need to pass in Data Rows for the GridControl, so any removal triggers highlighting updates due to row position changes.
        public INotifyCollectionChanged ViewModelDataRows
        {
            get { return (INotifyCollectionChanged)this.GetValue(ViewModelDataRowsProperty); }
            set { this.SetValue(ViewModelDataRowsProperty, value); }
        }
        public static readonly DependencyProperty ViewModelDataRowsProperty = DependencyProperty.Register(
          "ViewModelDataRows", typeof(INotifyCollectionChanged), typeof(MultiRowHighlightBehavior), new PropertyMetadata(null));


        public string HighLightingColorHex
        {
            get { return (string)this.GetValue(HighLightingColorHexProperty); }
            set { this.SetValue(HighLightingColorHexProperty, value); }
        }
        public static readonly DependencyProperty HighLightingColorHexProperty = DependencyProperty.Register(
          "HighLightingColorHex", typeof(string), typeof(MultiRowHighlightBehavior), new PropertyMetadata(DefaultColorHex));


        public TableViewHitTest HighlightingClickArea
        {
            get { return (TableViewHitTest)this.GetValue(HighlightingClickAreaProperty); }
            set { this.SetValue(HighlightingClickAreaProperty, value); }
        }
        public static readonly DependencyProperty HighlightingClickAreaProperty = DependencyProperty.Register(
          "HighlightingClickArea", typeof(TableViewHitTest), typeof(MultiRowHighlightBehavior), new PropertyMetadata(TableViewHitTest.RowIndicator));


        public bool AllowHighLightingMasterRow
        {
            get { return (bool)this.GetValue(AllowHighLightingMasterRowProperty); }
            set { this.SetValue(AllowHighLightingMasterRowProperty, value); }
        }
        public static readonly DependencyProperty AllowHighLightingMasterRowProperty = DependencyProperty.Register(
          "AllowHighLightingMasterRow", typeof(bool), typeof(MultiRowHighlightBehavior), new PropertyMetadata(false));


        public bool UseShaderEffect
        {
            get { return (bool)this.GetValue(UseShaderEffectProperty); }
            set { this.SetValue(UseShaderEffectProperty, value); }
        }
        public static readonly DependencyProperty UseShaderEffectProperty = DependencyProperty.Register(
          "UseShaderEffect", typeof(bool), typeof(MultiRowHighlightBehavior), new PropertyMetadata(true));

        private const string DefaultColorHex = "#FF3D3D3D";
        private SolidColorBrush _highLightingBrush;


        private enum HighlightingState
        {
            On,
            Off
        }

        #endregion

        #region event

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
            AssociatedObject.Loaded += AssociatedObject_Loaded;




            TrySetHighlightingBrush();
        }

        void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            var sv = VisualTreeHelpers.FindChild<ScrollViewer>(AssociatedObject);
            if (sv != null)
            {
                sv.ScrollChanged += (s, _) => { if (ViewModelHighlightedRows.Count > 0) RedoHilighting(); };
            }
        }

        protected override void OnChanged()
        {
            base.OnChanged();
            if (ViewModelDataRows != null)
            {
                ViewModelDataRows.CollectionChanged += ViewModelDataRows_CollectionChanged;
            }
            if (ViewModelHighlightedRows is INotifyCollectionChanged)  // e.g ObservableCollection<T> is IList and INotifyCollectionChanged
            {
                (ViewModelHighlightedRows as INotifyCollectionChanged).CollectionChanged += ViewModelHighlightedRows_CollectionChanged;
            }
        }

        void ViewModelHighlightedRows_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (ViewModelHighlightedRows.Count == 0) RedoHilighting(); // clear all highlights if collection cleared by outside caller.
        }

        // Rows removed by VM will be removed from highlighted rows if present
        void ViewModelDataRows_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (var i in e.OldItems)
                {
                    if (ViewModelHighlightedRows != null) ViewModelHighlightedRows.Remove(i);
                }
                RedoHilighting();
            }
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                RedoHilighting();
            }
        }

        void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (AssociatedObject.View == null) return;
            var view = AssociatedObject.View as TableView;
            if (view == null) return;

            TableViewHitInfo hitInfo = view.CalcHitInfo(e.OriginalSource as DependencyObject);

            if (hitInfo == null) return;

            // Highlighting happens if user click on Row Header. So highlighting will not interfare with Row/Cell/Expander selection/expanding functionality
            if (hitInfo.HitTest == HighlightingClickArea)
            {
                var row = view.GetRowElementByMouseEventArgs(e) as GridRow;
                if (row == null || row.RowDataContent == null) return;
                var rowData = row.RowDataContent.DataContext as RowData;
                if (rowData == null || ViewModelHighlightedRows == null) return;

                if (!AllowHighLightingMasterRow && IsMasterRow(row) && !HasMarketDepth(rowData.Row)) return;  // use visual tree to check if row =master row, no API found

                if (ViewModelHighlightedRows.Contains(rowData.Row))
                {
                    ToggleHighlighting(row, HighlightingState.Off);
                    ViewModelHighlightedRows.Remove(rowData.Row);
                }
                else
                {
                    if (ViewModelHighlightedRows.Count >= MaxNumberOfRowsHighlighted) return;
                    ToggleHighlighting(row, HighlightingState.On);
                    ViewModelHighlightedRows.Add(rowData.Row);
                }
            }
        }

        private bool HasMarketDepth(object rowDataObject)
        {
            try
            {
                PropertyInfo propInfo = rowDataObject.GetType().GetProperty("HasMarketDepth", BindingFlags.Instance | BindingFlags.Public);

                if (propInfo != null)
                {
                    var val = propInfo.GetValue(rowDataObject, null);
                    return (bool)val;
                }
            }
            catch (Exception)
            {


            }
            return false;
        }

        #endregion

        #region change View and VM, etc.

        // change view only, not ViewModel
        private void ToggleHighlighting(GridRow row, HighlightingState hState)
        {
            try
            {
                var rowIndControl = VisualTreeHelpers.FindChild<RowIndicatorControl>(row);
                var ricBorder = VisualTreeHelpers.FindChild<Border>(rowIndControl);

                SolidColorBrush toggleBrush;
                Effect toggleEff;
                double toggleThickness;
                if (hState == HighlightingState.On)
                {
                    toggleBrush = _highLightingBrush;
                    toggleThickness = 1;
                    toggleEff = new ColorToneEffect() { DarkColor = Colors.Transparent, LightColor = Colors.LightBlue, ToneAmount = 0.1 };
                }
                else
                {
                    toggleBrush = new SolidColorBrush(Colors.Transparent);
                    toggleThickness = 0;
                    toggleEff = null;
                }

                var rowContentBorder = VisualTreeHelpers.FindChild<Border>(row, "RowContentBorder");
                var fixNoneCellstBorder = VisualTreeHelpers.FindChild<Border>(row, "PART_FixedNoneCellsBorder");
                var detailButtonBorder = VisualTreeHelpers.FindChild<Border>(row, "PART_DetailButtonBorder");

                if (UseShaderEffect)  // Shader effect will highlighting on top of all colors across a row
                {
                    ricBorder.Effect = toggleEff;
                    rowContentBorder.Effect = toggleEff;
                    fixNoneCellstBorder.Effect = toggleEff;
                    detailButtonBorder.Effect = toggleEff;
                }
                else
                {
                    ricBorder.Background = toggleBrush;
                    ricBorder.BorderThickness = new Thickness(toggleThickness, toggleThickness, 0, toggleThickness);
                    ricBorder.BorderBrush = toggleBrush;

                    rowContentBorder.BorderBrush = toggleBrush;
                    rowContentBorder.BorderThickness = new Thickness(0, toggleThickness, 0, toggleThickness < 0.5 ? 0.0 : 1.0);

                    fixNoneCellstBorder.BorderBrush = toggleBrush;
                    fixNoneCellstBorder.BorderThickness = new Thickness(0, toggleThickness, 0,
                        toggleThickness < 0.5 ? 0.0 : 1.0);

                    detailButtonBorder.BorderBrush = toggleBrush;
                    detailButtonBorder.BorderThickness = new Thickness(0, toggleThickness, 0, toggleThickness);
                }

            }
            catch (Exception)
            {


            }
        }

        private static bool IsMasterRow(GridRow row)
        {
            try
            {
                var masterRowExpandBorder = VisualTreeHelpers.FindChild<Border>(row, "PART_DetailButtonBorder");
                if (masterRowExpandBorder == null) return false;
                var isMasterRow = VisualTreeHelpers.FindChild<Grid>(masterRowExpandBorder) != null;
                return isMasterRow;
            }
            catch (Exception)
            {
                return false;  // if not sure, let user highlight and un-highlight
            }

        }

        void RedoHilighting()
        {
            if (AssociatedObject == null || AssociatedObject.View == null) return;
            var view = AssociatedObject.View as TableView;
            if (view == null) return;

            var hp = VisualTreeHelpers.FindChild<HierarchyPanel>(view);
            if (hp == null) return;

            AssociatedObject.RefreshData();
            foreach (var c in hp.Children)
            {
                var row = c as GridRow;
                if (row == null || row.RowDataContent == null) continue;
                var rowData = row.RowDataContent.DataContext as RowData;
                if (rowData == null) continue;

                if (ViewModelHighlightedRows.Contains(rowData.Row))
                {
                    ToggleHighlighting(row, HighlightingState.On);
                }
                else
                {
                    ToggleHighlighting(row, HighlightingState.Off);
                }
            }
        }

        private void TrySetHighlightingBrush()
        {
            try
            {
                _highLightingBrush = (new BrushConverter().ConvertFrom(HighLightingColorHex)) as SolidColorBrush;
            }
            catch (Exception)
            {
                _highLightingBrush = (new BrushConverter().ConvertFrom(DefaultColorHex)) as SolidColorBrush;

            }

            if (_highLightingBrush != null) _highLightingBrush.Freeze();
        }

        #endregion

    }

setup Eclipse CDT and optional in c++ 17

(1) create an empty project, cygwin gcc, all the include will be cygwin x86_64, no need to set include path in proj props
(2) set misc flag to have -std=c++17 (lower case)
(3) make sure tool chain editor set CDT internal builder
(4) ignore red squiggles and may rebuild C++ indexes.
(5) how to find C++ header file http://en.cppreference.com/w/cpp/header
(6) sometimes, include file still see "unresolved" error, e.g std::function in . This is caused by preprocessor
    proj->props->C++ general->Preprocessor..etc.->CDT gcc build-in Compiler Settings->uncheck use global, add -std=c++14

 #include <experimental\optional>

using namespace std;
using namespace std::experimental;

optional<pair<string,int>> to_roman(int n)
{
 if(n>10) return {{"X",n-20}};
 if(n>9) return {{"IX",n-9}};
 if(n>5) return {{"V",n-5}};
 if(n>4) return {{"IV",n-4}};
 if(n>1) return {{"I",n-1}};
 return nullopt;  // constexpr inside experimental\optional
}

Saturday, November 12, 2016

MSVC Cuda

(1) cuda is nvidia GPU heterogeneous parallel API integrated in vs 2015
(2) must turn on .net 3.5 window 10 features to compile
(3) search msvc cuda to download nvidia toolkit and vs integration
(4) Control panel, device manager, display adapter shows nvida 5200m for me and cuda capable
(5) must set Cuda/C++ device to Compute_20,sm_20 for NVS 5200M, my labtop cannot do CC=35.
(6) https://en.wikipedia.org/wiki/CUDA#Supported_GPUs list CC=compute capability
(7) can search Cuda.8.0.props file to change CodeGeneration tag to compute=35,sm=35 for all projects.
e.g.C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations
(8) <<<blockSz,WarpSz>>> host to device call with blkSz and Hardware thread size.
(9) __global__ kernel function run on device. __ldg __shfl_down needs 35 so my labtop too old
(10) grid + Block +warp, segments GPU hardware thread into 3-dim cubes. 

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>

cudaError_t full_Reduce(int *out, const int *in, size_t n);

__global__ void full_reduce_kernel(int *out, const int *in,size_t n)
{
 int sum = 0; // in hardware,it is a vector<int> width=32,init 0

 // a thread coming choose a block to start, only consider dim-x, y=z=1
 // 4= each thread process 4 elements
 size_t start = (threadIdx.x + blockIdx.x*blockDim.x) * 4; 

 for (size_t i = start; i < start+4 && i < n; i++)
 {
  sum += in[i]; //again i is vector of 32 addresses
  //sum += __ldg(in + i); //_ldg supported in 35, not 20 but NVS 5200M Compute Capability=2.1
 } 
 // shift of SIMD registers, 32 threads move data half by half to front, invalidate back half
 // __shfl_down support in 35, not 20
 /*sum += __shfl_down(sum, 16);
 sum += __shfl_down(sum, 8);
 sum += __shfl_down(sum, 4);
 sum += __shfl_down(sum, 2);
 sum += __shfl_down(sum, 1);*/
 __shared__ int shared_sum; //not vector
 shared_sum = 0;
 __syncthreads(); // only sync warp in a block
 if (threadIdx.x % 32 == 0)
  atomicAdd(&shared_sum, sum);
 __syncthreads();
 if (threadIdx.x == 0) // shfl_down will make only idx=0 valid
  atomicAdd(out, shared_sum);
}

int main()
{
 const int n = 5;
 const int in[n] = { 1,2,3,4,5 };
 int out[n] = { 0 };
 cudaError_t cudaStatus1 = full_Reduce(out, in, n);
 if (cudaStatus1 != cudaSuccess) {
  fprintf(stderr, "full reduce failed!");
  return 1;
 }

 printf("%d %d %d %d %d\n",out[0],out[1],out[2],out[3],out[4]);
 cudaStatus1 = cudaDeviceReset();
 return 0;
}

cudaError_t full_Reduce(int *out, const int *in, size_t n)
{
 int *dev_in = 0;
 int *dev_out = 0;
 int sz = n * sizeof(int);
 cudaError_t cudaStatus;

 cudaStatus = cudaSetDevice(0);

 cudaStatus = cudaMalloc((void**)&dev_out, sz);
 cudaStatus = cudaMalloc((void**)&dev_in, sz);

 cudaStatus = cudaMemcpy(dev_in, in, sz, cudaMemcpyHostToDevice);
 full_reduce_kernel<<<1,n>>>(dev_out, dev_in,n);  // call dev not int
 cudaStatus = cudaGetLastError();
 if (cudaStatus != cudaSuccess) {
  fprintf(stderr, "full redu kernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
  goto FreeDev;
 }

 cudaStatus = cudaDeviceSynchronize();
 cudaStatus = cudaMemcpy(out, dev_out, sz, cudaMemcpyDeviceToHost);

FreeDev:
 cudaFree(dev_out);
 cudaFree(dev_in);

 return cudaStatus;
}

Thursday, November 10, 2016

C++ threading Primitives:mutex, lock_guard, thread, async,future



#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <future>

using namespace std;

inline int f() { return 42; };
mutex m;

void access_shared_res()
{
 cout << " 1 thread in, endl cannot catch up" << endl;

 lock_guard<mutex> g(m);
 cout << " 1 thread passed " <<this_thread::get_id()<< endl;
 this_thread::sleep_for(chrono::seconds(5));
}

int main()
{
 cout << " main thread " << this_thread::get_id() << endl;
 thread  t1(access_shared_res);
 thread  t2(access_shared_res);
 t1.join();
 t2.join();

 std::future<int> f1 = std::async(std::launch::async, []() {return 8; });
 cout << f1.get() << endl;
 std::future<int> promise = std::async(std::launch::async, &f);
 cout << promise.get() << endl;

 std::string s;
 getline(cin, s);
    return 0;
}


Monday, November 7, 2016

Setup Behavior event of its dependency property and connect to the instance not static

Dependency Prop inside a behavior is static. So its event fires into a static event handler.
But the dependencyObject in the param is the hehavior instance and can call instance method.

       public static readonly DependencyProperty TradingLevelProperty = DependencyProperty.Register(
        "TradingLevel", typeof(TradingLevelTypes), typeof(NumericTextBoxCustomParamBehavior), new PropertyMetadata(TradingLevelTypes.Low, TradingLevelrPropertyChanged));

        public TradingLevelTypes TradingLevel
        {
            get { return (TradingLevelTypes)GetValue(TradingLevelProperty); }
            set { SetValue(TradingLevelProperty, value); }
        }



        private static void TradingLevelrPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var behaviorInstance = dependencyObject as NumericTextBoxCustomParamBehavior;
            if (behaviorInstance != null)
            {
                behaviorInstance.EnsureNonNullableDataVisibility();
            }
        }

        void EnsureNonNullableDataVisibility()
        {
            var scrollContentPresenter = AssociatedObject.FindChild("PART_ScrollContentPresenter");
            if (scrollContentPresenter != null)
            {
                scrollContentPresenter.Visibility=TradingLevel== TradingLevelTypes.ServerDefault? Visibility.Hidden: Visibility.Visible;
            }
        }

accessing optional by de-refence pointer


Eclipse CDT optional is in <experimental\optional> and IDE red squiggly line need to be ignored

p default to either false or default value like 0
*p =default 0 or *p=assigned value if has a value like 90

#include <iostream>
#include <vector>
#include <cstdlib>
#include <experimental\optional>

using namespace std;

int main() {

 std::experimental::optional<int> p;

        cout<<*p<<endl;
 if(!p)
  cout<<"not set"<<endl;

 if(p<=12)
  cout<<"compare to int p=0"<<endl;

 p=90;
 if(p)
 {
  cout<<"access value by* "<<*p<<endl;
 }

 return 0;
}

Sunday, November 6, 2016

iota and random shuffle

iota comes from "not an iota", meaning getting nothing out.
oppsitely, means init with some increasing sequence.
std::shuffle with mt19937 would get random segquence.
mt19937 is a typedef of complicated hex input param for Meresene-Tiwster pseudo random generator
std::random_device{}() is a random seed

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <numeric>
#include <random>

using namespace std;

int main()
{
 vector<double> v(10);
 iota(v.begin(), v.end(), -1.1);
 for (auto n : v)
  cout << n << endl;
 cout << endl;
 shuffle(v.begin(),v.end(), std::mt19937{ std::random_device{}() });
 for (auto n : v)
  cout << n << endl;
 std::string s;
 getline(cin, s);
    return 0;
}



Gather since cannot slide into middle

1. Gather is to split at gather point and do two partitions.
2. partition put true in the front. So gather front partition needs not1
3. after partition, iter point to last_true+1. So two for-loop +- differs
4. not1 does work direction on lambda needs function
5. when gather point outside [be], it is a pure partition.

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>

using namespace std;

template <class RI, typename Func>
auto gather(RI b, RI e, RI p, Func f)->pair<RI, RI>
{
 if (b < p && p < e)
 {
  return{ stable_partition(b, p, not1(function<bool(int i)>(f))),
   stable_partition(p, e, f) };
 }
};

int main()
{
 vector<int> v{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 };
 vector<int>::iterator p = v.begin() + 7;
 auto g=gather(v.begin(), v.end(), p, [](int i) {return i%2 == 0; });
 
 for (; g.first != p; ++g.first)
  cout << *g.first << endl;
 cout << "two parti met point" << endl;
 for(; g.second!=p;)
  cout << *--g.second << endl;

 std::string s;
 getline(cin, s);
    return 0;
}


Rotate and Slide

{1,2,3,4,5,6,7,8,9,10}
Rotate(f,m,l) f<m<l,moves [m,l) displace [f,m)=>[m,l)[f,m)
R(2,4,5)=R(f,m,l)=>{1,4,2,3,5...} 
 vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
 rotate(v.begin() + 1, v.begin() + 3, v.begin()+4);

Slide S(p,b,e)=[be)[pb)/S(b,e,p)=[ep)[be)
note pair construct differs to make pair.first= [be) iter

template <typename RI> //random forward iter
auto slide(RI b, RI e, RI p)->pair
{
 if (p < b)
 {
  return{ rotate(p,b,e),p };
 }
 if (e < p )
 {
  return{p, rotate(b, e, p) };
 }
 return{b,e};
};

int main()
{
 vector<int> v{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 };
 auto v1 = v, v2 = v, v3 = v;
 rotate(v1.begin() + 2, v1.begin() + 4, v1.begin()+5);
 auto p_s2 = slide(v2.begin() +6 , v2.begin() + 8, v2.begin() + 2);
 auto p_s11 = slide(v3.begin() + 6, v3.begin() + 8, v3.begin() + 11);
 cout << (*p_s2.first) << endl;
 cout << (*p_s2.second) << endl;

 cout << (*p_s11.first) << endl;
 cout << (*p_s11.second) << endl;

 std::string s;
 getline(cin, s);
    return 0;
}

Saturday, November 5, 2016

nth_element as percentile and std::copy vs std::move

= is simpler than std::copy, while std::move clear original vector. n
std::equal actually iterate through vector to compare.

note copy are needed since nth_element will shuffle elements in place.

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
 vector<int> v{ 7,1,5,9,4,6,8,2,9,0,3 };
 vector<int> v_cp=v;
 //vector<int> v_cp(11);
 //std::copy(v.begin(), v.end(), v_cp.begin());
 cout << (equal(v.begin(), v.end(), v_cp.begin())?"true":"false")<< endl;
 vector<int> v_mv = std::move(v);
 cout << (equal(v_mv.begin(), v_mv.end(), v_cp.begin()) ? "true" : "false") << endl;

 const size_t pctil = v_cp.size()*0.75;
 nth_element(v_cp.begin(), v_cp.begin() + pctil, v_cp.end());
 cout <<"percentile elem="<< v_cp[pctil] << endl;

 v_cp.clear();
 cout << "sizes " << v.size() << " " << v_cp.size() << " " << v_mv.size() << endl;

 std::string s;
 getline(cin, s);
    return 0;
}

Generic Object Comparer

Object.Equals, IEqualalityComparer are actually not generic and the latter only used in Collection or LINQ like Contains.

This ObjectComparer is T, but does not consider reference type property.
The ignore will eliminate reference type and also those properties not to be considered in equality by users. so more flexible than Equals

    class ObjectComparer
    {
        public static bool PublicInstancePropertiesEquals<T>( T self, T to, params string[] ignore) where T : class
        {
            if (self != null && to != null)
            {
                var type = typeof(T);
                var ignoreList = new List<string>(ignore);
                var allProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var p in allProperties)
                {
                    if (!ignoreList.Contains(p.Name))
                    {
                        var selfValue = type.GetProperty(p.Name).GetValue(self, null);
                        var toValue = type.GetProperty(p.Name).GetValue(to, null);

                        if ((selfValue==null && toValue!=null) || (selfValue != null && !selfValue.Equals(toValue)))
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
            return self == to;
        }
    }

partition_copy has front back container

partition got a itr point to the begin of back partition, but it is not incrementable.
partition_copy allows pass in two containers through back/front_insert so can increment.
Note that vector is random iter but cannot use front_insert, why?
Note Stable Partition keep tag1 partition "Stabilize" and then partition by tag2 the back container


#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
#include <list>

using namespace std;

enum  attrib
{
 a0,a1, a2, a3, a4, a5, a6, a7, a8, a9,
 tag1 = a4,
 tag2 = a7
};

struct Entity
{
 attrib EntityAttrib;
};


int main()
{
 vector<Entity> v = { {a7},{ a1 }, { a5 }, { a9 }, { a4 }, { a6 }, { a8 }, { a2 }, { a3 }, {a0} };

 auto parti_tag1_itr=partition(v.begin(), v.end(), [](const Entity& e) {return e.EntityAttrib < tag1; });
 int c_front = count_if(v.begin(), v.end(), [](const Entity& e) {return e.EntityAttrib < tag1; });

 for(int i=0;i<c_front;i++)
     cout << (*(--parti_tag1_itr)).EntityAttrib << endl;
 cout << endl;

 vector<Entity> front_parti(10);
 list<Entity> back_parti(10);
 partition_copy(v.begin(), v.end(), back_inserter(front_parti), front_inserter(back_parti), [](const Entity& e) {return e.EntityAttrib > tag1; });

 for (auto e : front_parti)
 {
  cout << e.EntityAttrib << endl;
 }

 std::string s;
 getline(cin, s);
    return 0;
} 

stable_partition(back_parti.begin(), back_parti.end(), [](const Entity& e) {return e.EntityAttrib < tag2; });

Wednesday, November 2, 2016

sort partial_sort and stable and copy sementics

(1) Sort is the starting algo, stable means keep previous order so it only follows
(2) back_inserter convert object to an iterator.
(3) partition move true item in a container to front. false to back.
(4) partial/partition_copy moves and output two iterators.
(5) partial_sort means take 8 and sort until find top 5. so out_copy would be size 5

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>

using namespace std;

struct Person
{
 string FirstName;
 string MiddleName;
 string LastName;
};

int main()
{
 vector<Person> v{ {"Jason","P","Pierepaul"},{"Rob","C","Nokowich"},{"Jane","X","Smith"},{"Joe","A","Smith" }};

 sort(v.begin(), v.end(), [](const Person& a, const Person& b) {return a.MiddleName < b.MiddleName; });
 stable_sort(v.begin(), v.end(), [](const Person& a, const Person& b) {return a.FirstName<b.FirstName; });
 stable_sort(v.begin(), v.end(), [](const Person& a, const Person& b) {return a.LastName<b.LastName; });

 vector<int> v2 = { 42,17,89,22,34,78,63,12,57,99 };
 partial_sort(v2.begin(), v2.begin() + 5, v2.begin() + 8, greater<int>());

 vector<int> out_copy(5);
 partial_sort_copy(v2.begin(), v2.begin()+8, out_copy.begin(), out_copy.end(),greater<int>());

 vector<int> v3 = { 12,89,31,18,7,72,69,50,49,50,51,49 };
 vector<int>::iterator parti_itr = partition(v3.begin(), v3.end(), [](const int i) { return i < 50; });

 vector<int> true_parti, false_parti;
 partition_copy(v3.begin(), v3.end(), back_inserter(true_parti), back_inserter(false_parti), [](const int i) {return i < 50; });


 std::string s;
 getline(cin, s);
    return 0;
}


Tuesday, November 1, 2016

async void vs async task behave different


(1) for async-void, 2nd resume will never happen. 1st resume does happen
(2) for async-Task, both resume will not happen.

So async-void does not block Event Handler, but itself will be blocked forever
async-task Both event handler and itself will be blocked.
In both cases, UI is responsive=> There is a suspension point and UI return to do other things.
But resume gets affected

       private async void button_Click(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("thread id:{0}", Thread.CurrentThread.ManagedThreadId);
          // m();
            await mT();
            Debug.WriteLine("Resume 1");
        }

        async void m()
        {
            Debug.WriteLine("thread id:{0}", Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => {
                Debug.WriteLine("thread id:{0}",Thread.CurrentThread.ManagedThreadId);
                for (;;) { }
            });
            Debug.WriteLine("Resume 2");
        }

        async Task mT()
        {
            Debug.WriteLine("thread id:{0}", Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => {
                Debug.WriteLine("thread id:{0}", Thread.CurrentThread.ManagedThreadId);
                for (;;) { }
            });
            Debug.WriteLine("Resume 2");
        }

Sunday, October 30, 2016

Writing Linux C++ code in VS 2015

(1) Install VC++ for Linux development Extnsion
(2) sudo apt-get install openssh-server g++ gdb gdbserver on target e.g Raspery Pi.
(3) Too->Options-> search connection->conn manager to set up SSH connection to ARM Raspery Pi
(4) VS project cross platform console app, main.cpp, remote gdb
(5) Headless app will run inside Debug->Linux Console.
(6) Raspery Pi ~/project will have file to run ./console1.out
#inlcude  is all that needed for now

Using VS code C++ extension for MSVC project

(1) delete all .vscode related file in the MSVC project directories
(2) Extension search C++ to install C++ Extension from Microsoft
(3) Open Folder to point to the project direct and open .cpp file
(4) ctl-shift-build, bring up config task, select "MS build task" nothing to change in task.json
(5) hit Debug and config launch, select "C++ Launch Windows", set program "c:\test\demo\debug\demo.exe"
if missing include then set includePath in c_cpp_properties.json to point to the include path under Win32

Saturday, October 29, 2016

using iterator_trait to get iterator type to *value and iterator category template specialization to get iter type


tag dispatching--template specialization can be based on the tag

So Dispatch() can pass in typename iterator_traits<T>::iterator_category() to find matching specialization
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <list>
#include <iterator>
#include <forward_list>

using namespace std;

template<typename InputIter, typename Func>
void adjacent_pair2(InputIter first, InputIter last, Func func)
{
 if (first != last)
 {
  typename std::iterator_traits<InputIter>::value_type trailer = *first;
  //auto trailer = *first;  // C++ 11,14 cannot tell type
  ++first;
  for (; first != last; ++first)
  {
   func(trailer, *first);
   trailer = *first;
  }
 }
};

template<class C>
void print_iter_category(C c, std::random_access_iterator_tag)
{
 cout << "from random iter tag specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::bidirectional_iterator_tag)
{
 cout << "from bi-direct iter tag specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::input_iterator_tag)
{
 cout << "from input iter specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::output_iterator_tag)
{
 cout << "from output iter specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::forward_iterator_tag)
{
 cout << "from fwd iter specialization" << endl;
}

template<typename T>
void Show(T t)
{
 print_iter_category(t, typename iterator_traits<T>::iterator_category());
 print_iter_category(t, iterator_traits<T>::iterator_category());;
}


int main()
{
 vector<int> v = { 2,16,36,109,8,999,90,5 };

 func_cout a_func;
 adjacent_pair2<vector<int>::iterator, func_cout>(v.begin(), v.end(),a_func);

 list<int> l;
 Dispatch(l.end());  /bi-dir

 Dispatch(v.begin()); // vector is random iter

 istream_iterator<int> isIter;
 Dispatch(isIter);
 
 ostream_iterator<int> osIter(cout);
 Dispatch(osIter);

 forward_list<int> fl;
 Dispatch(fl.begin());   //fwd

 std::string s;
 getline(cin, s);
    return 0;
}



C++ iterator, Func as operator () or std:function and predicate as func

(1) there are various kinds of iterators: forward, random, input, output,bi-directional, iterator_traits::iterator_category
(2) for(; ...) will avoid post increment iterator, since some does not support iter++
(3) C++ func are struct with operator() overridden or std::function as a function_ptr
(4) iterator can be de-referenced or indexed in *, []

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

template<typename ForwardIter, typename Func>
void adjacent_pair(ForwardIter first, ForwardIter last, Func func)
{
 if (first != last)
 {
  ForwardIter trailer = first;
  ++first;
  for (; first != last; ++first, ++trailer)
   func(*trailer, *first); 
 }
};

template<typename SourceIter, typename TargetIter, typename Predicate>
std::pair<SourceIter, TargetIter> copy_while(SourceIter srcFirst, SourceIter srcLast, TargetIter tgt, Predicate p)
{
 for (; srcFirst != srcLast && p(*srcFirst); ++srcFirst,++tgt )
  *tgt = *srcFirst;
 return std::make_pair(srcFirst,tgt);
};

struct func_cout
{
 inline void operator() (int a, int b) const { cout << a << " " << b << endl; }
};

struct func_predicate_even
{
 inline bool operator() (int a) const { return a % 2==0; }
} 

inline void print(int a,int b) { cout << a << "|" << b << endl;}

int main()
{
 vector<int> v = { 2,16,36,109,8,999,90,5 };

 func_cout a_func;
 adjacent_pair<vector<int>::iterator, func_cout>(v.begin(), v.end(),a_func);
 std::function<void(int,int)> f_ptr = print;
 adjacent_pair<vector<int>::iterator, std::function<void(int, int)>>(v.begin(), v.end(), f_ptr);

 vector<int> w(5);
 func_predicate_even pred;
 auto ret_iter = copy_while(v.begin(),v.end(), w.begin(),pred);
 cout << *ret_iter.first <<"**"<< *ret_iter.second <<"copied "<<w[1]<< endl;

 std::string s;
 getline(cin, s);
    return 0;
}


Thursday, October 27, 2016

Transform a type into awaitable by Adapter or pass trhough


#include "stdafx.h"

#include <experimental\coroutine>
#include <iostream>
#include <string>
#include <future>
#include <thread>

using namespace std;
using namespace std::experimental;

template<typename T>
struct await_adapter
{
 T const& t_;
 bool await_readY() const;
 void await_suspend(std::experimental::coroutine_handle<> h) const;
 auto await_resume() const;
};

template<typename T>
class IAsyncOperation 
{

};

template<typename T>
await_adapter<IAsyncOperation<T>> operator co_await(IAsyncOperation<T> const& async)
{
 return async;
};

struct pass_through
{
 int result;
 bool await_ready() { return true; }
 void await_suspend(std::experimental::coroutine_handle<> h) {};
 auto await_resume() { return result; }
};

struct value
{
 int result;
};

pass_through operator co_await(value v)  // overload operator to make awaitable
{
 return{ v.result };
};

void test()
{
 auto i = co_await pass_through{ 123 };
 auto j = co_await value{ 456 };
}

int main()
{
 cout << "main thread id:" << std::this_thread::get_id() <<endl;
 test();
 //cout << r.get() << endl; //get causes return, no SM setup
 
 std::string s;
 getline(cin, s);
    return 0;
}


Tuesday, October 25, 2016

co_await vs. future.get()

co_wait will setup a state machine to return, future has to call get() to return

#include "stdafx.h"
#include <experimental\coroutine>
#include <iostream>
#include <string>
#include <future>
#include <thread>

using namespace std;
using namespace std::experimental;

std::future<int> produceAsync()
{
 return std::async(std::launch::async, [] {
  cout << " future thread id:"<< std::this_thread::get_id()<<endl;
  std::this_thread::sleep_for(5s);
  return 42;
 });
}

std::future<void> ConsumeAsync()
{
 auto r = co_await produceAsync(); // set up resume state machine
 cout << r << endl;
}

int main()
{
 cout << "main thread id:" << std::this_thread::get_id() <<endl;
 ConsumeAsync();


 auto r = produceAsync();
 //cout << r.get() << endl; //get causes return, no SM setup

 std::string s;
 getline(cin, s);
    return 0;
}



Monday, October 24, 2016

generator pipeline and accumulate


#include "stdafx.h"
#include <experimental\generator>
#include <experimental\coroutine>
#include <iostream>
#include <string>
#include <numeric>

using namespace std;
using namespace std::experimental;

std::experimental::generator<int> gen()
{
 for (int i = 0;; ++i)
  co_yield i;
};

std::experimental::generator<int> take_until(std::experimental::generator<int> g, int sentinel)
{
 for (auto v : g)
 {
  if (v == sentinel)
   break;
  co_yield v;
 }
}


int main()
{
 auto g1 = take_until(gen(), 10);
 auto a = std::accumulate(g1.begin(), g1.end(), 0);
  cout << a << endl;

 std::string s;
 getline(cin, s);
    return 0;
}


how future made avaitable

This is some information of internal coroutinea

awaiter-co_wait as operator on future and traits into coroutine
struct future_awaiter
{
 future<T>& _f;
 bool await_ready() {
  _f.then([ch]() {});
  return _f.is_ready();
 }
 void await_suspend(coroutine_handle<> ch)
 {
  _f.then([ch]() {ch.resume(); })
 }
 auto await_resume() { return _f.get(); }
};

template<typename T>
future_awaiter<T> operator co_await(future<T>& value) // transform future=>awaitable
{
 return future_awaiter<T>(value);
};

 // make future a coroutine type by specialization
 template<typename T, typename... Arguments>
 struct coroutine_traits<future<T>, Arguments...>
 {
  struct promise_type
  {
   promise<T> _promise;
   future<T> get_return_object() { return _promise.get_future(); }
   auto initialize_suspend() { return suspend_never{}; }
   auto final_suspend() { return suspend_never{}; }
   template<typename U>
   void return_value(U&& value) { _promise.set_value(std::forward<U>(value)); }
   void set_exception(std::exception_ptr ex) { _promise.set_exception(std::move(ex)); }
  };
 };

co_wait co_return co_yield


coroutine can yield from generator, return from future and wait a async lambda
#include "stdafx.h"
#include <experimental\generator>
#include <experimental\coroutine>
#include <future>
#include <iostream>
#include <string>

using namespace std;
using namespace std::experimental;


future<int> compute()
{
 int ret= co_await std::async([]
 {
  return 30;
 });

 co_return ret;
}

std::experimental::generator<int> gen()
{
 for (int i = 0; i < 10; ++i)
  co_yield i;
};

int main()
{
 for (auto v : gen())
 {
  cout << v << endl;  
 }

 auto i = compute();
 cout << i.get() << endl;
 std::string s;
 getline(cin, s);
    return 0;
}


Sunday, October 16, 2016

Delayed Evaluation and Expression template

Instead of loop through vector index multiple times when adding mutiple vector.
could keep ref to sum of two and later loop-through once to reduce temp var

#include <iostream>
#include <vector>
#include <cstdlib>

using namespace std;

// temp var one-by-one
//template<typename T>
//inline vector<T> operator+(const vector<T>& x, const vector<T> y)
//{
// vector<T> sum(x.size());
// for(int i=0;i<x.size();i++)
//  sum[i]=x[i]+y[i];  //temp var
// return sum;
//}

// delayed evaluation expression template

template <typename T>
struct vector_sum
{
 const vector<T> &x, &y;
 vector_sum(const vector<T> &x, const vector<T> &y) :x(x), y(y) {}
 T operator[](int i) const { return x[i] + y[i]; }  // indexer
};

template<typename T>
vector_sum<T> operator+(const vector<T>& x, const vector<T>& y)
{
 return{ x,y }; // delayed evaluation to a single loop
};

template<typename T> class vector  // new impl of vector
{
 const vector<T> &data;
 vector& operator=(const vector_sum<T>& that)  //assignment
 {
  check_size(size(that));
  int my_size = size(that);
  for (int i = 0; i<my_size; ++i)
   data[i] = that[i];  // now loop through.
  return *this;
 }
};

int main() {
 std::vector<int> x = { 1,2,3 };
 std::vector<int> y = { 4,5,6 };
 auto s = x + y;
 cout << s[2] << endl;

 return 0;
}

Saturday, October 15, 2016

type traits compile time if in typedef


#include "stdafx.h"
#include <iostream>
#include <type_traits>
#include <typeinfo>

using namespace std;

template<bool cond, typename T, typename ElseT>
struct conditional2 {
 using type = T;
};

template<typename T, typename ElseT>
struct conditional2<false, T, ElseT>
{
 using type = ElseT;
};


int main() {

 typedef conditional2<true, int, char>::type T1;
 typedef conditional2<1 == 2, int, char>::type T2;
 cout << typeid(T1).name() << " " << typeid(T2).name() << endl;
 return 0;
}



type traits is_const and variadic template extending std::min

Eclipse CDT tool chain has an issue--"using std::is_heap" not declared in  
so used VS 2015 instead.

#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <type_traits>

using namespace std;

template<typename T>
struct is_const2
{
 static const bool value = false;
};

template<typename T>
struct is_const2<const T>  // specialization
{
 static const bool value = true;
};

template<typename T>
inline T min2(const T& t) { return t; }

template<typename T, typename ...P>
inline auto min2(const T& t, const P& ...p)
{
 using res_type = std::common_type_t<T, P...>;
 return std::min(res_type(t), res_type(min2(p...)));
};

int main() {

 cout << "test " << is_const2<const int*>::value << endl;
 cout << "test " << std::is_const<int* const>::value << endl;
 cout << "test " << is_const2<const int&>::value << endl;

 const int i = 123;
 const double j = 456.1;
 const char k = 'a';

 auto m = min2(i,j,k);

 return 0;
}


Rx Replay


Hot= publish(), cold=hot replay(), hot connect, cold connect
        private void SetupReplayObservable()
        {
           var HotObservable = Observable.FromEvent(
                    h => _Manager.DataReceived += h,
                    h => _Manager.DataReceived -= h).Publish();
           InfoObservable = HotObservable.Replay();
           HotObservable.Connect();
           InfoObservable.Connect();
        }

Sunday, October 9, 2016

What are the frequency of HFT

Some data collected for High Frequency Trading:

penny made each, 40 Million per day=> 1.5 Trades per ms =>42M per 7 hour period(9:30-4:30)
HFT account for 70% trades in the market, use to be only 30%.
At open Citadel executed 20M shares in 3 minutes --- HFT and Market Maker, 14% of Market trades

Memory Model in Drawing

Saturday, October 8, 2016

Set Up IDE to compile C++17 code constexpr with statement, recursion in body

(1) VS 2015 cannot compile constexpr with statement body.
(2) Eclipse CDT (C++ dev tool) can but need the following install/setup/config
(3) cdt need compiler and cygwin64 must be installed (latest version 2.6.0)
(4) C++ 17 is supported in 2.6.0 but may not be supported in MinGW.
(5) during cygwin64 install to c:\cygwin64, must install package under devel--gcc,g++, make, gdb
(6) cdt download is cdt 9.1.0 =Eclipse neon 1.
(7) windows->preference->C/C++->Environment add path c:\cygwin64\bin
(8) project ->properties->C/C++ build ->Toolchain Editor ->Current Toolchain=CygWin gcc, builder=CDT internal builder
(9) same as (8), C++ compiler->settings->includes "C:\cygwin64\lib\gcc\x86_64-w64-mingw32\5.4.0\include"
(10) same as (9) C++ compiler->misc->other flag -std=c++17
(11) project ->C/C++ index -> rebuild/search/un-resolved can help to find out why some include are not found
(12) right click on a project can also access properties



#include <iostream>
#include <cmath>
using namespace std;

constexpr bool is_prime(int i)
{
 if (i == 1) return false;
 if (i % 2 == 0)
  return i == 2;
 double max_check =sqrt(i) + 1;
 for (int j = 3; j < max_check; j += 2)
  if (i%j == 0) return false;
 return true;
}
using namespace std;

int main() {
 cout << "test " <<is_prime(67)<< endl; 
 return 0;
}

contexpr with recursion and new if statement

constexpr bool is_prime2(int i, int div)
{
 return div>=i?true:(i%div==0?false:is_prime2(i,div+2));
}

constexpr bool is_prime(int i)
{
 return i==1?false:(i%2==0?i==2:is_prime2(i,3));
}

Dependency Walker for .Net

No such thing exactly but the following tools are close:

git https://github.com/mikehadlow/AsmSpy

open in VS 2012, restore missing packages
(maybe Install-Package Microsoft.Extensions.CommandLineUtils)
maybe working in CS 2013.

copy AsmSpy, etc in /bin to App
asmspy . all >refList.txt

other tools

http://www.amberfish.net/
http://www.ndepend.com/


Thursday, October 6, 2016

template fibonacci


template<long n>
struct fibonacci {
 static const long value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
};

template<> struct fibonacci<1> { static const long value = 1; };
template<> struct fibonacci<2> { static const long value = 1; };

Wednesday, October 5, 2016

Specialization Template

#include "stdafx.h"

template<int i> struct D { D(void*); operator int(); };

template<int p, int i> struct is_prime {
 enum {prim=(p==2) ||(p%i)&&is_prime<(i>2?p:0),i-1>::prim };
};
template<> struct is_prime<0,0> { enum { prim = 1 }; };
template<> struct is_prime<0,1> { enum { prim = 1 }; };


int main()
{
 auto p = is_prime<243, 20>::prim;
    return 0;
}

Saturday, October 1, 2016

VMMap and RamMap

VMMap:
(1) VM Types: image,mapped-file, Heap, stack(for threads)
(2) VM alloc: Committed, Reserved, Private, Shareable 
(3) Task manager does not show type
(4) Working set = RAM
(5) Graph1 -- coloring Private data in private bytes along non-data
    Graph 2 -- Working set with portion colored as private data
          shows how much private data actually in WS.


RamMap
(6) Page List: Working Set =>Modified Page List (still in RAM)
               => StandBy Page List (Disk) by ModPage Writter
(7) Process Explorer/System Info shows all page List: Zero
    StandBy, Modify, Free.
(8) Did global or heap var in your app pass through the list?


(9) File Summary: For each process, Page List view
(10) Priority summary: How much re-pupose on Priority 7=> Ram Pressure
(11) Physical Pages: Mapped-File full path

Thursday, September 29, 2016

C++ 17 on Compiler Explorer

http://gcc.godbolt.org/
Clang support C++17 more feature than gcc 6.9


//Clang 3.9.0 compiler option -std=c++11

#include <tuple>

using namespace std;

int test1()
{
  return 99;
}

std::tuple<int,int> test()
{
 return make_tuple<int>(1,2); 
}

int main()
{
  // const auto [s1,s2]=test(); // structured binding not working
  if( const auto i=test1();i==1) { //if-init works
  }
    return 0;
}

Sunday, September 25, 2016

Pool vs New Thread schedule for Rx and a C++ optimzed book





https://s3-ap-southeast-1.amazonaws.com/mylekha-ebook/IT+%26+Programming/c_c%2B%2B_c%23/Optimized-C%2B%2B.pdf





NewThread is EventLoopThread inside each nested call and new on each non-nested.

when subscription on background blocks more than 50ms use NewThread, otherwies use Pool Thread

macro for property definition


#define VIRTUAL_VAL_RO_PROPERTY(Access, PropertyType,PropertyName,Field) \
    property PropertyType PropertyName        \
    {                        \
    virtual PropertyType __clrcall get()            \
    {                    \
    return Field;            \
    }                    \
    } \
private:                    \
    PropertyType Field;                \
    \
Access:

volatile, reinterpre_case, constexpr, lambda and destructuring in C++14 and 17


#include "stdafx.h"
#include <iostream>

using namespace std;

namespace {
 volatile uint8_t &memory(const uint16_t loc)
 {
  return *reinterpret_cast<uint8_t*>(loc);
 }

 struct VIC_II
 {
  static constexpr uint16_t COLOR = 0xd020;
  volatile uint8_t &border()
  {
   return memory(COLOR);
  }
  volatile uint8_t& display(const uint8_t col, const uint8_t row)
  {
   return memory(1024 + col + row * 40);
  }


  auto test()
  {
   return std::make_tuple<int,int,int>(1, 2, 3);
  }
 };
}
int main()
{
 const auto le = [](uint8_t i) {cout << i << endl; };

 le(3);
 VIC_II vic;
 vic.border() = 1;
 vic.border() = 2;
 memory(1024) = 'a';
 vic.display(1, 2) = 'b';
 
// destructuring inside if does not work in VS 2015
// i.e. structured binding + if initializer
 if ( auto [s1, s2, s3] = vic.test();s1==1)
 {

 }
    return 0;
}

volatile, reinterpre_case, constexpr, lambda and destructuring in C++14 and 17


#include "stdafx.h"
#include 

using namespace std;

namespace {
 volatile uint8_t &memory(const uint16_t loc)
 {
  return *reinterpret_cast(loc);
 }

 struct VIC_II
 {
  static constexpr uint16_t COLOR = 0xd020;
  volatile uint8_t &border()
  {
   return memory(COLOR);
  }
  volatile uint8_t& display(const uint8_t col, const uint8_t row)
  {
   return memory(1024 + col + row * 40);
  }


  auto test()
  {
   return std::make_tuple(1, 2, 3);
  }
 };
}
int main()
{
 const auto le = [](uint8_t i) {cout << i << endl; };

 le(3);
 VIC_II vic;
 vic.border() = 1;
 vic.border() = 2;
 memory(1024) = 'a';
 vic.display(1, 2) = 'b';
 
// destructuring inside if does not work in VS 2015
 if ( auto [s1, s2, s3] = vic.test();s1==1)
 {

 }
    return 0;
}

Monday, July 4, 2016

PE 64 vs 32 bit, std::data() vs c_str, version replace in csproj, CLang


PE headers in DLL telling x86 vs. x64:
x86:
PE  L
x64:
PE  d†

Better use std string data():
std string c_str() is null terminated char only convertion, must use data() if source is encoded from binary data.

Clang and MinGw:
VS 2015 update 3 bring down Clang in a checkbox "Clang with MS codeGen", using LLVM for cross platform, Low Level VM
clang, clang++ are under "program files .. visual studio vs" directory and some androi directory after update 3
MinGW is Windows Implementation of gcc


csproj and Nuget packages.config version changes
find . -type f -print | xargs grep "1.6.0.1"
$ sed -i 's/1.6.0.1/1.6.0.2/g' project1.csproj
$ find /proj/code -type f -exec sed -i 's/1.6.0.1/1.6.0.2/g' {} \;

#!/bin/bash
      for fl in *.php; do
      mv $fl $fl.old
      sed 's/FINDSTRING/REPLACESTRING/g' $fl.old > $fl
      rm -f $fl.old
      done

Saturday, April 16, 2016

Basics of Cmd/Batch file

@echo off color 0F  2E start http://www.cnn.com start 99.txt

set /p input=
if %input%==1 (  REM must be if (    ) else (
goto L1
) else  (
goto L99
)
:L1 LEnd set /p input=enter somthing || set input=nothing REM prompt
echo. > %filename%.%extension%  REM =touch in bash but 1 empty line with dot
ping www.cnn.com -n 5 >nul or 2>nul :: n=count nul not null 2=error

for %%i in (1 2 3) do (
REM % escape % to show 1% 2% 3% vs %%i loop var
echo %%i%%  
)

setlocal enabledelayedexpansion  REM ! =% but delayed
set v=test
REM =test when parse =90 when exec so show 90 test
set v=90 & echo !v! %v% ^^!  REM escape ! by ^^

for /r %%i in ( * ) do ( for /d REM rooted =file d=dir for /f %%i in ('dir /b') do (
:main setlocal   endlocal  dir /b /a:D /o-D REM bare folder /a:-D not folder sort D=datetime -D=desc

%CD% %~dp0 %~dp1 REM currDir param 0=1.cmd 1,2 dir only so c:\%~fs0 REM full path filename
echo %CD% pushD c:\1 echo %CD% PopD REM chg dir chg back %~n0 %~x0 REM filename ext
for /f %%i in ('dir /b') do (
echo %%~di  %%~pi %%i  REM show drive letter working dir and filename
)

for /f "Tokens=1,3" %%g in ('dir') do (echo %%h) REM %%g %%H %%i with tokens=
for /f "tokens=* delimis=," in (1.txt) .. REM similar to bash cut

:: function is label and pass in var and modify var byref %~1= param
:function1
echo f1 %~1 set %~1=9
call :function1 ro_val set v=-1 call :function1 v :: show 9

Array
set a[0]=A
set a[1]=B
set a[2]=C

set i=0
:loop
if %i% equ 3 goto :eof
:: usebackq=alternate quote, back quote ` =command processing
for /f "usebackq delims== tokens=2" %%j in (`set a[%i%]`) do (
 echo %%j 
)
set /a i=%i%+1


Sunday, April 10, 2016

MS Build project with Assembly version update

(1) evt.trading.build .\1\1.sln are the solution/build file structure
(2) msbuild .\Evt.Trading.Build /property:Configuration=Release /p:BUILD_NUMBER="1.0.17.239" 
(3) msbuild path C:\Program Files (x86)\MSBuild\14.0\Bin
(4) 1.sln can have C++/CLI project, may consider Nuget file repo for non-nugget lib.
(5) on Team City, BUILD_NUMBER need to be defined.
(6) TAP_WPF is the shell Title = Assembly.GetExecutingAssembly().GetName().Version.ToString();



<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         ToolsVersion="14.0" DefaultTargets="Compile">
  <ItemGroup>
    <BuildArtifacts  Include=".\__buildartifacts" />
    <SolutionFile Include=".\1\1.sln" />
  </ItemGroup>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)'=='' ">Debug</Configuration> <!-- msbuild /property:Configuration=Release-->
    <SolutionRoot>$(MSBuildProjectDirectory)</SolutionRoot>
  </PropertyGroup>
  
  <Target Name="Clean" >
    <RemoveDir Directories ="@(BuildArtifacts)" />
  </Target>
  
  <Target Name="Init" DependsOnTargets="Clean" >
   <MakeDir Directories="@(BuildArtifacts)" />
  </Target>
  
  <Target Name="Compile" DependsOnTargets="Init;UpdateAssemblyVersion;">
    <MSBuild  Projects="@(SolutionFile)" Targets="Rebuild"  Properties="OutDir=%(BuildArtifacts.FullPath);Configuration=$(Configuration)"/>
  </Target>


<UsingTask TaskName="RegexTransform" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <Items ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
        </ParameterGroup>
        <Task>
            <Using Namespace="System.IO" />
            <Using Namespace="System.Text.RegularExpressions" />
            <Using Namespace="Microsoft.Build.Framework" />
            <Code Type="Fragment" Language="cs">
                <![CDATA[
            foreach(ITaskItem item in Items) {
              string fileName = item.GetMetadata("FullPath");
              string find = item.GetMetadata("Find");
              string replaceWith = item.GetMetadata("ReplaceWith");
              
              if(!File.Exists(fileName)) {
                Log.LogError(null, null, null, null, 0, 0, 0, 0, String.Format("Could not find version file: {0}", fileName), new object[0]);
              }
              string content = File.ReadAllText(fileName);
              File.WriteAllText(
                fileName,
                Regex.Replace(
                  content,
                  find,
                  replaceWith
                )
              );
            }
          ]]>
            </Code>
        </Task>
    </UsingTask>

    <ItemGroup>
        <RegexTransform Include="$(SolutionRoot)\TAP_WPF\Properties\AssemblyInfo.cs">
            <Find>(?<major>\d+)\.(?<minor>\d+)\.\d+\.(?<revision>\d+)</Find>
            <ReplaceWith>$(BUILD_NUMBER)</ReplaceWith>
        </RegexTransform>
    </ItemGroup>
  
    <Target Name="UpdateAssemblyVersion" Condition="'$(BUILD_NUMBER)' != ''">   <!--  msbuild .\Evt.Trading.Build /property:Configuration=Release /p:BUILD_NUMBER="1.0.17.235"-->
        <RegexTransform Items="@(RegexTransform)" />
    </Target>


</Project>


Linux Admin braindump --Rasbian, Unbuntu


SD Formatter (SD card Association), RasberryPi.org download NOOBS 1G boot menu+Rasbian
[Putty SSH shutdown RasPi] halt -h //wait all LED off, cmd poweroff not work
passwd pi useradd  -p xxxxxx -G adm jimmy groups //list all groups cut -d: -f1 /etc/group
raspi-config //enable SSH change password reboot pm-hibernate 
ifconfig -a iwlist scan hostname -I iwlist wlan0  essid Cap15 //try to get wifi dhclient wlan0 ifconfig wlan0 up/down service ssh start
cd=cd / cal cal-3 cal 7 14 1995 date date --date "30 days ago" "30 days"  free -m top shit-f s %MEM [esc] // sort by mem
lsb-release -a uname -r //system, kernel info distrowatch.com
tty w=who chvt apt-get update/dist-upgrade ssn localhost exit lsscsi lsub lspci lshw //hardware info uptime uname -a which lsscsi //file path
/dev /sys /proc /proc/interrupts //pseudo file system IRQ 0=system timer 75=nic //use cat/ls on pfile watch -n1 head -n 10 interrupts // 1sec realtime interrupts upd hwclock --systohc // copy system time to hardware clock see rtc0 upd gnome-system-monitor //=taskmgr cat /sys/block/sda/size cd /dev/sda cd /proc/14 cat stack  /sys vs /dev meta data

sofware management
/var/lib/rpm /apt  rpm -qa apt list rpm -i/-e 
rpm -vhU https://nmap.org/dist/nmap-7.12-1.x86_64.rpm
rpm -qf $(which nmap)
apt-get install yum

RH/CentOS -- rpm -qpi //query pkg info -qpl //list /etc/repo.d loca.repo [local] baseurl=file:///repo mkdir /repo yum install createrepo createrepo /repo yum install nmap //w/o repo this will not work

debian/ubuntu --- dpkg -i -r -s -L -l dpkg-reconfig apt repository apt-get update ls /var/cache/apt apt-cache search postfix
cat /etc/apt/sources.list //rabian or ubuntu repo url  apt-cache pkgnames postfix //search a pkg to install

shared lib--user module
ldd /bin/ls DLL=.so .ko //shared kernel cat /etc/ld.so.conf //PATH less /etc/ld.so.conf.d/libc.conf ldd $(which useradd) ldconfig ldconfig -p mkdir /testlib cp librt.so.0 export LD_LIBRARY_PATH=/testlib/ ldd /bin/ls  // dependency shows testlib unset LD_...

shared lib--kernel module
lsmod | grep psmouse = grep psmouse /proc/modules // show size dependcy modinfo psmouse modprobe -r psmouse modprobe psmouse //remove add
ls /etc/modprobe.d less blacklist.conf //not loading outdated modules

file management
lsblk ls -l /dev/sda //show brw-rw.. b=block lsblk /dev/sda fdisk -l /dev/sda  gdisk parted /dev/sda print mkfs. XFS ext4 apt-cache pkgnames xfs mkdir -p /data/{d1,d2} // can mount to dir  blkid /dev/sdb1  mount mount -t ext4 -o acl,noexec /dev/sdb1 /mnt unmount /mnt /etc/fstab

Swap file
mkswap swapon --show = free -m /var/swap on RasPi /dev/sda6 gdisk

partprobe /dev/sda6 //avoid reboot to sync new parti cat/proc/partitions ls /dev/sda* mkswap /dev/sda3 swapon /dev/sda3 gdisk /dev/sda6 select p=print parti table n=new parti 3=sda3 8200=linux swap file others like Microsoft reserved
swapoff /dev/sda3 swap on -p 10 /dev/sda3 //priority 10 vi /etc/fstab sw, pri=10 //mount by editing
add a new line /dev/sda3 none swap, pri=10 0 0 //no mount point, 0 dump 0 check on restart
mount -a //read, refresh mount map swapon -a //read swap file swapon -s =show 
dd if=/dev/zero of=/root/swapfile1 count=1000 bs=1024 //init NULL dd=disk imaging copy mkswap /rro/swapfile1 // not mkfs
swap -p 10 /root/swapfile1 swapon -s grep swap /etc/fstab  //now swapfile1 is virtual mem swapfile
du df dd //file and disk usage imaging tune2fs e2fsck dumpfs debugfs //tunable ext2,3,4 check tune2fs -L 'label1' /dev/sda5
df -lhT //local human type du -hs /etc //human size dumpe2fs /dev/sda5 mount
dd if=/dev/sda of=/data/backup/file1 count=1 bs=512 //back up 1st boot rec fdisk -l //show boot rec
tar -cvf /data/backup/etc.tar /etc //backup etc create verbose file
debugfs /dev/sda5 ls ls -d <14>=deleted file stat <14> apt-get install extundelete extundelete --inode 89 /dev/sdb1 //inode=fs data structure extundelete --restore-file dir1/1.confi /dev/sdb1 ~RECOVERED_FILES mount -a cp //need manually copy files

permission
id sudo -i //switch to root user cannot change root passwd su - ask password  exit //logout super user
ugo=usr group other rwx symbolic/octal 7=111=rwx 6=110=rw 4=100=r chmod chown chgrp stat umask
stat f1.txt =ls -l //verbose show octal and sym mkdir -p /data/dir{1,2,3} umask //show defautl 2=0002 umask 0 //now 0000 =>true default for files touch f1.txt =>rw-rw-rw //666 not 664 by umask umask 007=>touch f3.txt show rw-rw-r-- x not set even allowed
umask 007 // 7=rwx, 6=rw 4=r 1=x not allow 0=any can be set
ls -ld . //drwx-rw- current dir perm chmod 777 chmod u=rwx g=rw o=r chmod +rw -rw
chgrp users /dir1 //perm now for users not root 
sticky bit on dir --- /dir1 -rwx /dir1/f1.txt -r-- // readonly still can delete if parent dir rw chmod o+t /dir1 can no longer delete f1.txt ls -ld /dir1 drwxrwxrwxT //t=sticky bit prevent readlonly file deletion for others
hard/soft link --- . is a link current dir ls -a //at least two links . ..   filename inode[meta data] are two links stat->stat file->stat f1.txt ls -ld doc find /usr/share/doc -maxdepth 1 -type d |wc -l // count subdir | head -n 3 
ln f1.txt hl1 //hard link ln -s f1.txt sl1 //soft link  stat f1.txt //show same inode for hard diff for soft ls -li f.txt //show inode
dd if=/dev/zero of=/data/big.txt count=1 bs=1024M //create 1G file for testing

Linux Boot up and Service Control
find . -name "menu.lst" /etc/init grep -i default_run * //case insensitive runlevel 0=halt 1=single user 2=multi no gui/no netw 3=no gui 5=full gui 6=reboot //no 4  init 0 init 2 ubuntu/debia 2=3=5 /etc/init upstart rc-sysinit.conf env DEFAULT_RUN_LEVEL=2
runlevel = who -r //show N 2 N5  telinit 6 telinit 3 halt =into BIOS
boot procedure: pwr self-test =>locate MBR (master boot rec) =>boot loader (kernel/Ram disk) =>kernel/Ram disk =>init Daemon (RunLevel 5 for desktop 3 for server)
grub grub2 menu.lst Grand Unified boot loader shutdown poweroff reboot shutdown -r now shutdown -h 18:27 "donw at 6pm" -h +5"in 5min" shhutdown -c //cancel or Ctrl+c

service status start stop restart netstat -anl ls /etc/init.d /etc/inittab chkconfig --list sshd update-rc.d -f sshd remove update-rc.d sshd defaults



Wednesday, April 6, 2016

Prism bits


CompositeCommand
namespace   Infrastructure {
public static class GlobalCommands
{
         static GlobalCommands()
         {
             SaveAll = new CompositeCommand(); // better than field init ??
         }


  public CompositeCommand SaveAllCommand {get; set;}
}

}

//Register child command
Infrastructure.GlobalCommands.SaveAll.RegisterCommand(Save_Local_Command)

// not binding but static ref
<Button Content="Save All" Command="{x:static inf:GlobalCommands.SaveAllCommands}"


Event aggregator---CompositePresentationEvent Publish/Subscribe

View Injection --- using Region Manager or MEF ServiceLocator.GetInstance+Region Manager

Shared Service
using module to host a singleton servivice so that module does not hard-reference another module

infrastructure:IPersonRepository
ServiceModule::PersonRepository : IPersonRepository
Init() { _container.Ressolve<IPersonRepository>(new ContainerControlledLifetimeManager()); //singleton

usage _repository.Save();  //DI IRepository to _repository

RegionContext
DataContext Master/Detail vs Region Master/Detail (Parent/Child)
<ListBox Name="lb" /> <ContentControl prism:RegionManager.RegionContext={Binding SelectedItem ElementName=lb />
DetailView::ctor() { RegionContext.GetObservableContext(this).PropertyChanged +=(s,e)=> { var ctx=(ObservableObject<object>) s; (ViewModel as IPersonDetailViewModel).SelectedPerson=ctx.value as Person;} // note Model Person now in  View, should be inside VM select a person by ID

State based Navigation
Not really move but to update layout, same data/task but different look and feel

Busy Indicator in Async loading 
<toolkit:BusyIndicator IsBuzy={Binding IsBusy}><LisBox/>

Replace Layout by DataTrigger <DataTrigger Binding={Binding IsChecked, ElementName=ToggleBtn1} Value=T>
<Setter Property =ItemTemplate  ItemPanel />

User Interaction through Command -- popup vs in-place editing
DelegateCommand EditCommand
prop SelectedPerson {set {EditCommand.RaiseCanExecuteChanged(); }
<toolkit:ChildWindow WindowState={Binding WindowState}><Grid  DataContext=SelectedPerson >
prop WindowState WindowState

View Based Nav
infrastructure::AppCmds {static CompositeCommand Nav;}
<Button Command={x:static inf:AppCmds.Nav} CommandParam={x:type views:ViewA} . // use type as URI no databinding here.
DelegateCommand<object> Nav_local= new ((obj)=>{RegionManager.RegisterNavigation(ContentRegion,obj);}
Nav.RegisterCommand(Nav_local) // local command has URL set and connect to button by global cmd
Module A/B regtype must use full name of view tyoe as URI
Container.RegisterType(typeof(ViewA)); // very specific syntax here

Monday, April 4, 2016

Git Braindump

View 
tree .git cat .git/HEAD cat .git/refs/heads/master git reflog git checkout -b topic git reset --head git reset --head [SHA] //point to ci git checkout master grh [SHA] gl master topic gbrt //all branch in time order  git log ..[branchname] //msg, not including head git status --short git add --update // staging grep -r'<<<<' // conflicts gl HEAD@{1} alias gm="git merge --no--ff" gmf="merge --ff--only" //no fast forward
Merge == new commit, no chg hist, Rebase = recommit a set of ci on top of new point, new hist
git rebase --abort gp origin local:remote git push :[branchname] //delete remote branch git log --patch filename git log -S'key word' // search entire commit  git log --patch -S"" //patch format git log --all --simplify-by-decoration //only tagged, branched git l --simplify-by-decoration git clean -n // untracked ignored -n= safe dry run rvm use default@global gem install git-smart git smart-pull 

Between Remote and Local
msysgit windows install, tortoisegit --mimic svn gitextensioin instead.(window explorer integration)
git init //create repo c:\prog x86\Git\etc\gitconfig  c:\Users\w3333\.gitconfig git config
git remote rm origin git remote -v git remote add origin git@github.com:jqd/myproj.git
git clone http://.../proj.git git log --oneline --graph |wc -l git shortlog -sne git show HEAD~10 git remote -v //verbose show fetch/push url  protocols http/git/ssh/file cat .git/config

git branch [-r] //remote gita tag git remote -v git remote add origin http://../jqd/proj1.git=>git fetch //pull down git fetch origin //where  git log origin/master //chg in remote but not in head git log //not integrated into local yet git merge origin/master //now local will have  remote chg and git log will show ff
git pull=git fetch;git merge origin/mster
git branch --set-upstream orgin/master // remote tracking branch git pull git clone set upstream automatically
git status git commit -am 'msg' git push  //ask uid/pwd for http
git remote add origin git@github.com.jqd.proj1.git //use SSH version url no more uid/pwd ssh key git tag v1.0 git tag git tag -a "msg" v1.0 git push --tags //tag must be pushed

Working locally
git init git status git add f2.txt
git commit // brings up vim/notepad, git commit -a "msg" //avoid editor  git add -u // stage not add file not the same as git add -A //truly add, no more untracked
git add f1.txt //stage not add,  rm f2.txt=> git add -u =>git commit //del=>stage=>ci del
git diff dd6819..a15ec6 //only need 6 in SHA git diff HEAD~1..HEAD = git diff HEAD~1 //back 1

git checkout f1.txt //override changes git reset --hard HEAD //back to HEAD throw away local git reset --hard HEAD~1 //set head back git reset --soft HEAD~1 //move changes back to working/loc copy, head no changes
git clean -n //dry run clean up working dir git clean -f //force

vim .gitignore /logs /logs/*.txt git add .gitignore git commit -a "add ig" .gitignore.

Branch/Merge/Rebase
git log --oneline --graph --all --decorate //show head,tag,branch,master git config
git config --global alias.gla "log --graph --oneline --all --decorate" git lga //git log all cat ~/.gitconfig
git branch feature1 git checkout feature1 = git checkout -b feature1 //branch and switch locally.

git lga=> make changes=>gig commit -am "msg" =>git lga=>4577ae [HEAD,feature1 //head feature both point to changes

git checkout master=>2332dc6 [HEAD naster] //head point away

git branch fix1 974b5a=>git checkout fix1=>changes=>git commit -am""=>git lga [HEAD fix1] // shows a new [5a78cb7 HEAD] above everyone including master
git branch -m fix bug123 // move=rename git branch -d bug123 //cannot del since change not merged to master
git branch -D bug123 // force del=D
git reflot =>git branch bug123 5a78cb => git checkout bug123 //un-delete if<30days

git checkout f3 =>make changes=>git stash=>git stash list=>(switch away fix bug123)=> git check f3=>git stash apply // come back to f3 work
git reset --hard HEAD => git stash apply //still restore from stash git stash pop =apply but loss on hard-reset git stash drop git stash branch f3_addl
git checkout masgter=>git merge f1  //ff master to f1 [f1,master,HEAD] git branch -d f1 [master,HEAD]
git mergetool //beyoundcompare kdiff3 git diff --cached //repo vs. staging git commit -m "merg into master"
git branch f3 v1.0 // branch from [tag,master]=>[HEAD,f3] git show f3
git checkout f3=> changes=> git commit -am => git rebase master=>git lga //f3 not longer from [tag,master] rather it is on top of master 
git checkout master => git merge f3 //ff merf just move [master HEAD,f3]
git rebase master=>conflict tools=>rm *.orig =>git diff --cahsed=>git rebase --continue Rebase = replay commit on top of mast but rebase is dangerous 

Cherry Picking
git checkout master //have two commits but only want 1 in master, cannot rebase or merge 
git cherry-pick 6fa4327 => git lga 19ae38f7 [HEAD,master] "fix from 6fa4327"



git fetch origin master  git push = git push origin master // ff [master origin/master HEAD]
git push origin v1.0_fix  //new remote branch created git branch -r  // show orign/master origin/v1.0__fix 
git push origina v1.0_fix:v10_remote_name // give it a name
(strange way to delete remote branch by local name=null) git push origin :v10_remote_anme
git rebase -i HEAD~3 //modify last 3 commit message may need git rebase --continue/abort. git log --graph --oneline to check git reset --hard 7e458f9 // delete commit from local
git log --cc --since="6am" --author="joe" | git diff-tree -v

start git repo
(1) There are no git command to create Repo.
(2) General structure  Project/Repos  e.g. eTrading/ET-Options, ET-RFQ, ET-Equity
    for personal git, there are no project ( or default just one for your own repo)
      https://stash-prod1.us.myFirm.net:8443/projects/eTrading
      https://stash-prod1.us.myFirm.net:8443/users/w123
(3) git clone empty repo would get local repo established but no origin
   git clone https://stash-prod1.us.myFirm.net:8443/projects/eTrading/ET-Options.git
   git clone https://W123@stash-prod1.us.myFirm.net:8443/scm/~w123/e-trading.git
(4) init-commit local-add origin-push master--connecting to git
    (There are no develop yet)
cd existing-project
git init
git add --all
git commit -m "Initial Commit"
git remote add origin https://W123@stash-prod1.us.myFirm.net:8443/scm/~w123/e-trading.git
git push origin master

(5) switch code tracking on git
cd existing-project
git remote set-url origin https://W123@stash-prod1.us.myFirm.net:8443/scm/~w123/e-trading.git
git push origin master

submodule --- point to a specific commit of other repo, not tracking
git clone url_superProj => subm_dir empty git submodule update --init // bring down a subm commit
cat .gitmodules shows url dir of subm inside superproject
git submodule add url path_subm git status git log git push origin master:master brnch:brnch // all for separate commit of subm. must fork if no perm for subm.
git add subm_name // upd to new commit in the subm, not automatically bring down
cd subm_dir git push origin master:master // must push separately and 1st
git reset HEAD subm_name // remove changes or branching git push origin b1:b1 // new remote branching.
git submodule update 

A successful git branching model in Git command

http://nvie.com/posts/a-successful-git-branching-model/

(1) Develop a feature
// only branch from develop for features

git checkout -b myfeature develop

// merge back to develop no fast forward
// no ff=> merge has ci obj clear hist

git checkout develop
git merge --no-ff myfeature

// clean up

git branch -d myfeature
git push origin develop

(2) Release --always from develop, stay for a while
git checkout -b release-1.2 develop
./bump-version.sh 1.2
git commit -a -m "Bumped version number to 1.2"

(3) Release -- close up by merge

git checkout master
git merge --no-ff release-1.2
git tag -a 1.2

git checkout develop
git merge --no-ff release-1.2

git branch -d release-1.2

(4) Hotfix --always from master

git checkout -b hotfix-1.2.1 master
./bump-version.sh 1.2.1
git commit -a -m "Bumped version number to 1.2.1"
git commit -m "Fixed severe production problem"

git checkout master
git merge --no-ff hotfix-1.2.1
git tag -a 1.2.1

git checkout develop
git merge --no-ff hotfix-1.2.1

git branch -d hotfix-1.2.1

HTML5/Web Socket Realtime trading App feasible ?


1. WebSocket is bi-directional, full-duplex, single tcp conn, lean
2. Keypad support --- how web gui knows keypad, vendor javascript?
3. javascript development framework? DI, MVVM, Formatter (Augular2)
4. Browser vs store app on Win8/10  --- if wait a few years, no need for OpenFin
5. Testing and Perf/diag tools.  (Karma, Protractor)
6. Java WS-Server =Model/Service WS-Duplex =DataProvider Augular=VM/Xaml/DataBinding
7. Performance:  WS-Dup > Rx ? Angular >Xaml ? javascript databinding > C# databinding ?


Possible issues
(1) Floating window out of range in multi-monitor
(2) how do you resize windows from OpenFin? infinitely small ?
(3) How could two network traffics not reduce performance? (WS and Streambase)
    in WPF WS is replaced by Rx in memory.
(4) WebSocket Play!Framework vs. raw Tcp comparison 10x slower
     http://eng.kifi.com/websockets-vs-regular-sockets/

intranet: use Tcp Socket
internet WebSocket init using Http then negotiate WS protocol to be Tcp like



Sunday, April 3, 2016

Strategy, Swap and Algo


delta cross
(1) a future hedge, both maturity and currency of
   mismatch underlying
(2) P+C, negative move of C=>positive move of P

Collars -- put-call after stock gain-hedge wrapper
booster -- 1x2 call ratio spread c-2c
straddle --p+c
strangle --p+c different strike, wider.
butterfly- c-2c+c= short one call spread +long a call spread
Risk Reversal -- c-p

dividend swap -- fixed vs total div paid by underlying
             x Notional shares, single stock or basket
variance swap-- one lege pay var of Px move, one pay fix strike.
     (var strike, realized var, vega notional)
     Exchange Rate, interest rate, stock index vol.

Correlation swap--

which swap are delta 1-- divd, all swap are delta 1???

algo:
reserve -- block options, post small slice,rest in reserve
       replenish on exec, stop loss cxl, auto-hedge each slice
price movement -- walk from mid to stop, sweep/re-sweep by short-lived
       limit order. stop walk if underlying cross threshold, auto-hedge
       on execution.
vol post---reserve+limit price=continous re-calc(spot,vol limit)
         each exec => stock order, keep delta exposure thresthold
vol stealth --limit=continous re-calc(spot,vol limit), 
     monitor NBBO Sweep by IOC,exec=>stock order for delta
NBBO =national best bid/offer.

Practical SVN


svn checkout https://ch9:8443/svn/demo/trunk . (trunk per app)
branches, tag are not for main dev
tortoise svn command line --C:\Program Files\TortoiseSVN\bin
svn add 1.txt svn commit 1.txt -m "RTEC-1234: Comment"
svn ci -m "ci current dir implicitly"

Three types of SCM
Locking ---
Merging  --SVN
Distributed ---Git

SVN-- update as often as you can to minimize merge issue
ignore-- parent folder tsvn->property-> svn:ignore bin \n *.exe
commit changes to properties such as ignore
branch for feature/release/cutomized version

switch branch/trunk vs separate local dir for branch/trunk
checkout branch to its own loc dir vs. same loc dir as trunk with switch.
either way not affecting server.  switch+ci -- careful where committed. n
Suggested Server structure:  
branches 
tags swi
trunk

Merge--- switch loc dir to trunk --> merge branch to local working copy
-->Edit Conflict -->commit --> mark some file as "Resolvled"

Merge require switch to destination first
most common merge--re-integrate branch=> branch to trunk.

tagging-- switch to tags server directory during branching.
not really read-only but make sure do not commit
https://ch9:8443/svn/demo/tags/release-1.0.17.241

Show log-- 
search commit messages RTEC-9730 -- include Jira # better search
"stop on copy and rename"--- merged branch will only show changes on
the branch after created from trunk, much shorter
"include merged revision" --- on trunk see all branch chg from merges

Commit Monitor---
http://stefanstools.sourceforge.net/CommitMonitor.html

Branching Strategy --
per feature -- too many, merge issues.overhead
per release --- off to work on a release,better as post release 
per developer/team --CI not well supported.
Branch as needed --- best strategy
 (1) everyone work on trunk, see merge issue sooner
 (2) when release needed,branch and never merge back 
 (3) branch bug fix/hot fix stay in branch and merge back if fit
     ( trunk could have a re-write without hot fix)
 (4) CI easier and effective on trunk
 (5) never need to deal with merging unless Hot Fix.
 (6) Exception: experiemental feature branch may merge back

Merge in/Merg out ---Merge trunk to branch->resolve conflict--> test
  --> merge branch to trunk(trivial no conflicts)

"Merge a range of Revision":
(1) Cherry Picking--switch to trunk local ->merge branch to trunk->Show Log
  --> pick time or pick individual chg in the log->merge->edit conflicts
  --> commit
(2) Rollback merge --switch to trunk -->Merge trunk to trunk -->
    -->show log find the entry of the merge -->pick "reverse merge"
    --> commit => merge rollback


Saturday, April 2, 2016

Fix Log Tag Printer in Python


#!/usr/bin/env python3
""" show fix log tag per line,e.g flt.py log.txt 52 49 55  """

import os
import sys
""" mod """
def get_tag_values(line,tags):
    tag_values=[]   
    for t in tags:
        if t+"=" in line:
            tag_values.append(line.split(t+"=")[1].split("=")[0])
    return tag_values

def show_tags_per_line(file,tags):
    os.chdir(".")
    with open(file) as lines:
        for line in lines:
            v=get_tag_values(line,tags)
            if len(v) >0:
                print(v)
                
def ask_help(argv):
    if len(argv)<2:
        pass
    v=argv[1]
    if v=="/h" or v=="/help" or v=="-h" or v=="-help":
        print(__doc__)
        sys.exit(0)
    
if __name__=='__main__':
    ask_help(sys.argv)
        
    tags=sys.argv[2:]
    file=sys.argv[1]
    show_tags_per_line(file,tags);

Fix Protocol Braindump


Spec PDF
http://cdn.batstrading.com/resources/membership/BATS_US_EQUITIES_FIX_SPECIFICATION.pdf

http://www.fixtradingcommunity.org/FIXimate/FIXimate3.0/
http://fixparser.com/
ef311b37

Commonly used Tags
58 -- Free form text, error message
44- limit price
8 --begin
35 msgtype (0=heartbeat 1=test 5/A=logout/logon 2=resent/request D=new order single
   9=ordcxlrequest 8=execrpt(F,PF,ZF) 4=seg# resend 3=reject)

Example of Tag 35
35-3+ tag45 =>reject with tag 45 Seq #
35-2+tag7(20) and Tag16(30) =>Resend with begin 20, end 30
35-2, only see 12,14 missing 13
35-4 => user did not logout, next day see high Seq#

49/5-- sender/tgt compId=Routing Tag
34 --Seq #, connection troubleshooting
50/59 --Sender/Tgt subid, which trader on both side
43/97--PossDup/Resend--possible resend, new seq #
52/122-- sending/original timestamp
372/373 ---refmsgtype/reason for 35/3 reject
123 --GapFillFlag ----Do not resend expired order 35/4 Y=> req-sequencing

Order Entry Message
1-Acct 11-CientOrderID 60--Transaction Timestamp (Latency Complaints
55--Symbol 65--sufix FB.TO .PK (Toronto, pinksheet) .SS China 54-side
38-Tot Qty 111-Max Floor, Display Qty, on exch floor
40--ordertype 2=limit p=Pegged 59 --Time In Force 0-day 6=GTC good tc 
IOC=Imm or cxl, FOK fill or kill
126--Expire time
32=100 38=100 => 39=4  LastShr/OrdQty=> filled=2
110=110 38=210 32=10 minQty=> wrong data
38=100 110=200 wrong setup 
18 --execinst --- R=primary Peg P=mkt peg M=Mid Pt Peg
Peg=Limit order matching bets=Mkt ord
110--MinQty 31/32=Last Px/Share
39-- Order Status(New=0,PF,ZF 2=Filled, Done for day, Expired)

filter using bash
$ cat log.txt | grep '52=' |grep -v 'Note' | awk '{gsub(/52=/,"____SendTime____");print}' | awk '{gsub(/54=2/,"____SELL____");print}'
must have tag 52 but does not have 'Note' replace 52 as SendTS 54=2 as SELL order
cat *.log | grep | awk combined log