31 Mayıs 2016 Salı

boost iostreams memory mapped device

Memory Mapped File Device Sınıfları
Bu sınıflar stream'in memory mapped bir dosyaya  yazmasını veya okumasını sağlar.

mapped_file Sınıfı- Read ve Write
constructor - string
Şöyle yaparız.
mapped_file mmap("C:\\test.bin", mapped_file::readonly);
const_begin metodu
Şöyle yaparız.
char const * it = mmap.const_begin();
const_data metodu
Şöyle yaparız.
const char* data = mmap.const_data();
const_end metodu
Şöyle yaparız.
char const * endit = mmap.const_end();

24 Mayıs 2016 Salı

SQL

SQL Declarative Bir Dildir
C++, Java gibi imperative dillerde kod şöyle yazılır.
Declare a new List called ExpensiveItemsNames;
Foreach Item in Items:
If ItemPrice > 100 then
Add ItemName to ExpensiveItemsNames

SQL declarative bir dil olduğu için kod şöyle yazılır. Kontrol akışı yoktur.
SELECT ItemName FROM Items
WHERE ItemPrice > 100

Left Join
Left join aşağıdaki gibi yapılır.

Bu işleme alternatif olabilecek ve daha hızlı çalıştığı iddia edilen cüme ise not exists kullanmak. Örnek:

Self Join
Aynı tablonun iki defa kendi kendiyle birleştirilmesi demek. Aralarında ilişki bulunan satırları (employee-manager ilişkisi gibi) çekmek için kullanılacağı gibi, bazı satırları elemek için de kullanılabilir.

Aşağıdaki bir self join örneğini buradan aldım.

Inner join'de aynı tabloya iki farklı isim verilir ve bu isimler kullanılarak = operatörü ile bir kesişim alınır. Örnekte nufüsu 0'dan farklı olan tüm regionlar arasında en küçük nufüsa sahip regionlar bulunuyor.

SELECT region, name, population
 FROM bbc x
 WHERE population <= ALL (SELECT population FROM bbc y WHERE y.region=x.region AND population>0)

Inner Join
İki tablonun kesişimini almak demek.
Inner Joining three tables sorusundan aşağıdaki aldım.
Union
Union iki farklı tabloyu birleştirmek için kullanılır.

Union ve Union All arasındaki fark
Sql ile kullanılabilen union ve union all birleştirme operatörleri farklı işler yaparlar.

Konuyu açıklayan güzel bir yazıyı burada buldum. Örnek resimileri de aynı yerden aldım.
A ve B isimli iki tane tablomuz olsun.
Bu iki tabla aynı veriyapısına sahip ve iki tablonun da birleşimini almak istiyoruz. union kullanırsak sonuç distinct ve sort edilmiş olarak veriliyor.  union all kullanırsak sonuç sadece iki tablonun birleşimi oluyor. Herhangi bir ayıklama yapılmıyor.
union ile ayıklama yapıldığı (distinct ve sort işlemleri) aşağıdaki execution plan'den de görülebilir.

Benzer bir örnek ise burada var. Yine aynı yerden aldığım örnekte de görüldüğü gibi union distinct kayıtları getirirken, union all ayıklama yapmadan herşeyi birleştiriyor.

Hibernate ve Union
Hibernate nesne seviyesinde çalıştığı için, SQL gibi union kullanarak bir kümenin alt kümesini döndüremiyor. Bunu yapabilmesi için çalışma esnasında yeni bir nesne tipi yaratabilmesi ve döndürebilmesi gerekir ancak maalesef henüz bu tür yeteneklere sahip değil.

Ancak eğer union işlemi aynı nesne üzerinde ise, hibernate halen kullanılabilir. Bu konu ile ilgili bir cevabı burada bulabilirsiniz.

23 Mayıs 2016 Pazartesi

boost spirit

spirit x3
C++11 ile gelen özelliklerin kullanılabilmesini sağlar. Şöyle kullanılıyor.
namespace x3 = boost::spirit::x3;
Şu satırı dahil ederiz.
#include <boost/spirit/home/x3.hpp>
fusion
Parse işleminde struct gibi nesnelerin kolayca doldurulabilmesini sağlar. Şu satırı dahil ederiz.
#include <boost/fusion/adapted/struct.hpp>
Şöyle yaparız.
struct Point { double x, y, z; };

BOOST_FUSION_ADAPT_STRUCT(Point,x,y,z)
qi
boost spirit qi yazısına taşıdım.

eol
Satır sonunu belirtir.

qi::int_ - parser
qi::int_ ile şöyle yaparız.
char const* b = "66";
char const* e = b + strlen("66");
int32_t res = 0;
bool valid = boost::spirit::qi::parse(b, e, boost::spirit::qi::int_, res);
qi::int_parser<> ile şöyle yaparız.
int res = 0;
namespace qi = boost::spirit::qi;
bool valid = qi::parse(b, e, qi::int_parser<int, 10>(), res);
qi::lexeme
Verilen string'i birebir eşleşir. Şöyle yaparız.
qi::lexeme["self"]
omit
Belirtilen örüntüyü dikkate almaz.
omit[',' >> double_]
raw
Şöyle yaparız.
qi::raw[qi::lexeme["self"]]
seek
Belirtilen örüntüye kadar yürür.
seek[ eps >> 'x' >> 'y' >> 'z' >> eol ]
str_p - parser
Örnek ver.

qi::uint_ - parser
Semantic action tanımlanabilir. Şöyle yaparız.
auto not_greater_than_12345 = [](const unsigned& attr, auto&, bool& pass) {
  pass = !(attr > 12345U);
};
qi::uint_[not_greater_than_12345]
rule
Parser'ların arka arkaya sıralanması gibi düşünülebilir. Şöyle yaparız.
if_rule=str_p(IF)>>ch_p("(")>>if_mem>>*("and"|"or">>if_mem)>>ch_p(")");
grammar
grammar template olarak tanımlanabilir. Şöyle yaparız.
template <typename Iterator, typename Skipper>
struct grammar : qi::grammar<Iterator, MyType(), Skipper>
{
  ...
}
Şöyle yaparız.
template <typename Iterator>
struct grammar : qi::grammar<Iterator, MyType(),ascii::space_type>
{
  ...
}
constructor
struct içinde tanımlı bir qi::rule ata sınıfa geçilir. Şöyle yaparız.
template <typename Iterator, typename Skipper>
struct grammar : qi::grammar<Iterator, MyType(), Skipper>
{
  grammar() : grammar::base_type(object)
  {
    ..
  }
  private:
    qi::rule<Iterator, QVariant(), Skipper> object;
    ...
};
phrase_parse
Şöyle yaparız. Önce begin ve end iterator tanımlanır.
using It = std::string::const_iterator;
std::string input = "...";
It begin = input.begin(), end = input.end();
Daha sonra beklenen çıktı tipi ile çağrılır.
Foo foo;
bool ok = qi::phrase_parse
(begin, end, grammar<It, qi::space_type>{}, qi::space, foo);
Benzer metod x3 ile şöyle kullanılır. Önce begin ve end iterator tanımlanır. Bu sefer dosyadan okuma yapacağımız için memory mapped file tanımlıyoruz.
std::string const fname = ...;
boost::iostreams::mapped_file mm(fname);
Daha sonra bir vector tanımlarız.
std::vector<Point> v;
Ve dosyayı okuruz.
return phrase_parse(mm.begin(), mm.end(),
            ..., //grameri yazmadım
            blank, v);
Çağrı sonucunu şöyle işleriz.
auto f = input.begin(), l = input.end();

bool ok = qi::phrase_parse(f, l, grammar, qi::space);

if (ok)
  std::cout << "Parse success\n";
else
  std::cout << "Parse failed\n";

if (f!=l)
  std::cout << "Trailing unparsed input: '" << std::string(f, l) << "'\n";

parse metodu
Bu metod begin iterator + end iterator + rule + output şeklinde düşünülebilir.

Delimeter
Bir string'i delimeter/separator ile ikiye ayırma örneği şöyle. Biraz düzenli ifadeye benziyor.
*~char_ ile delimeter'a kadar tüme karakterleri alır. Daha sonra separator gelir. Takiben yine tüm karakterleri alıyor. Yakalanan karakterler left ve right stringlerine dolduruluyor.


#include <boost/spirit/include/qi.hpp>

struct misc {
  static void split(const std::string &input,
                    std::string &left, std::string &right, char separator)
  {
    using namespace boost::spirit::qi;

    parse(input.begin(), input.end(), *~char_(separator) >>
                                       separator >> *char_, left, right);
  }
};

20 Mayıs 2016 Cuma

Nullable ve Optional

Giriş
Nullable C# ile gelen bir kavram. Bir değişkenin, primitive bile olse, hem gerçek bir değer alabileceğini hem de değeri belirtilmemiş olabileceğini gösteriyor.

Optional ise Nullable ile çok benzer. Primitive tipler yerine nesneler için kullanılıyor.

Nullable ve Girdi Parametresi
Optional bir tipi girdi parametresi olarak kullanmak bazıları tarafından tavsiye edilmiyor. Bu kişiler Optional daha çok döndürülen tip olarak kullanılmalı tezini savunuyorlar.

Guava
Örnek:
Optional<Book> optionalBook = findBook(id);
if (optionalBook.isPresent()) {
    Book book = optionalBook.get();
  }

STL Optional
STL Optional daha standarda girmedi. Ancak yine de nasıl kullanılacağını yazmak istedim. Şimdilik boost optional'ı kullanmak gerekir.

value metodu
Örnek. bool converter ile optional nesnesinin dolu olduğu kontrol edilir. Eğer bu kontrol yapılmazsa value() metodu bad_optional_access exception'ı atar.

if (o)  // redundant check
  f(o.value())

bool converter
Optional sınıfının dolu olup olmadığını anlamak için kullanılır. Örnek: Burada std::optional sınıfının * operatörü ile kullanıldığına dikkat etmek gerekir.
if (o)
  f(*o)
boost optional
boost optional yazısına taşıdım.

Java
ofNullable ve Stream
Optional sınıfının en önemli özelliği ofNullable ile verilen nesneyi sarmalamasıdır. Böylece Java 8 ile gelen stream sınıfları ile rahatlıkla kullanılabilir.
<T> Stream<T> getStream(List<T> list) {
    return Optional.ofNullable(list).map(List::stream).orElseGet(Stream::empty);
}
Bir başka örnekte elimizde şöyle sınıflar olsun
Class A {
    String a1;
}
Class B {
    Optional<A> a;
}
Class C {
    Optional<B> b;
}
Class D {
    Optional<C> c;
}
C'den B'yi. B'den A'yı alana bir zincir kuralım. A değerini veya arada herhangi bir nesne null ise null değerin elde etmek için şöyle yaparız.
String getAValue(D d) {
   return Optional.ofNullable(d)
       .map(D::getC).map(C::getB).map(B::getA).map(A::getA1).orElse(null);
}

C#
C#'ta nesneler tanımlanırken soru işaret ile nullable yapılabilir. Nullable aslında aşağıdaki struct'a benziyor. where T : struct kısıtı yüzüden nullable sadece value type'lar ile kullanılabilir.

public struct Nullable<T> where T : struct
{
    private T value;
    private bool hasValue;
}
Basit bir nullable kullanımı
int? myInt = null;
var hasValue = myInt.HasValue;//false
Bir başka örnek string'e çevrim
string x = null;
x.ToString(); // throws a NullReferenceException

int? y = null;
y.ToString(); // returns ""

Nullable tipler C#'taki Null Coalescing Operator ile de sıkça beraber kullanılırlar.
Örnek:
Type? v = x?.y?.z; 
if (v.HasValue) {
    var value = v.GetValueOrDefault();     
    // code using value 
} 
Lifted Operator for Arithmetic Operations
Nullable tiplere ++, +, --, -, ! ve ~ operatörlerinin uygulanmasını sağlar. Eğe nesne null ise bu özel operatörler null döner.
int? a = null;
a++; // No NullReferenceException
Console.WriteLine(a); // Empty line
Lifted Operator for Conversion
Açıklaması şöyle

6.4.2 Lifted conversion operators
Given a user-defined conversion operator that converts from a non-nullable value type S to a non-nullable value type T, a lifted conversion operator exists that converts from S? to T?. This lifted conversion operator performs an unwrapping from S? to S followed by the user-defined conversion from S to T followed by a wrapping from T to T?, except that a null valued S? converts directly to a null valued T?.

Kod olarak şöyle kullanıyoruz. nullable decimal alan bir metodumuz olsun.
public static string PrintDecimal(decimal? input, string NumberFormat = null){ }
Bu metodu nullable int ile çağırabiliriz.
int? MaxFaltas = 0;
Label.Text = CustomConvert.PrintDecimal(MaxFaltas);