23 Mayıs 2015 Cumartesi

boost pool

Giriş
Sınıfları Boost dokümantasyonunun tersine sıralayacağım. pool_alloc STL veriyapıları ile kulllanılır. pool sınıfı malloc gibi çalışır. object_pool ise bir listeye doldurulmuş nesneler gibi düşünülebilir.

pool_alloc sınıfı
pool_allocator vector gibi büyük bellek alanları gerektiren vector,dequeue, string sınıfları ile kullanılır.
fast_pool_allocator ise list, set, map gibi düğümlerler çalışan sınıflar ile kullanılır. Şöyle kullanırız.
typedef std::map<
    int,
    int,
    less<int>,
    boost::pool_allocator<pair<const int, int> >
    > 
    MyMyapType;
fast_pool_allocator muadili için şu yazıya da bakılabilir.

pool sınıfı
malloc gibi çalışır. pool sınıfının kaç byte bellek alanı vereceği ve ilk büyüklüğü constructor metodu ile ayarlanır. İmzası şöyledir.
explicit pool(const size_type nrequested_size,const size_type nnext_size = 32)
Mesela 32 byte'lık bellek döndüren 64 chunk şöyle yaratılır.
boost::pool<> p(32, 64);

object_pool sınıfı
Yaratma
Sınıf şöyle tanımlanır.
boost::object_pool< MyClass > mypool;
construct metodu
Yeni bir nesne yaratmak için şöyle yapılır. Nesnemin constructor metoduna 3 taneye kadar parametre geçebilirim. Eğer daha fazla parametre geçmek istersem derleyici şöyle bir hata verir.
'boost::object_pool<T>::construct' : function does not take 4 arguments
Construct metodu eğer havuzda nesne kalmamışsa, yeni bir chunk belleği yaratır.
MyClass *p = mypool.construct(param1,param2);
Eğer istenirse template kullanan şöyle bir ObjectFactory yazılabilir.
template<typename TType = T, typename... TArgs> 
inline TType* create(TArgs&&... mArgs)
{
  return m_tpPool->construct(mArgs...);
}
construct metodu ve shared_ptr
Constructor metodu raw pointer döner. shared_ptr dönsün istiyorsak şöyle yaparız.
class ClassFactory
{
    boost::object_pool<YourClass> allocator;
public:
    boost::shared_ptr<YourClass> create()
    {
        return boost::shared_ptr<YourClass>(
            allocator.construct(),
            boost::bind(&ClassFactory::destroy, this, _1) );
    }

    void destroy(YourClass* pointer)
    {
        allocator.destroy(pointer);
    }
};
destroy metodu
Nesnenin destructor'ı çağırılır ama nesnenin kullandığı bellek alanı havuza geri döner.
inline void destroy(T* mObj) 
{ 
  m_tpPool->destroy(mObj);
}
free metodu
Nesnenin destructor'ı çağrılmaz ama nesne bellek havuzuna geri döner.

Thread Safe Pool
Bu sınıf thread safe değildir. Thread safe yapmak için mutex ile wrap etmek gerekir.
template <typename T>
class ObjectFactory 
{
    boost::object_pool<T>   m_Pool;
    boost::mutex            m_PoolMutex;

public:

    template<typename TType = T, typename... TArgs> 
    inline TType* create(TArgs&&... mArgs)
    {
        boost::unique_lock<boost::mutex> scoped_lock(m_PoolMutex);
        return m_Pool.construct(mArgs...);
    }

    inline void destroy(T* mObj) 
    { 
        boost::unique_lock<boost::mutex> scoped_lock(m_PoolMutex);
        m_Pool.destroy(mObj); 
    }

};



19 Mayıs 2015 Salı

Locale İşlemleri

Not : Java ile ilgili şeyleri buraya taşıdım. C# ile ilgili şeyleri buraya taşıdım.


Locale Nedir?
Uygulamalar farklı ülkelerin standartlarına göre çalışmak için, o ülkenin gösterim için kullandığı formatlama bilgisini kullanırlar. Bu formatlama bilgisini saklayan sınıfa Locale denilir.

Örneğin her ülkenin tarih, para, zaman için belirlediği ayraçlar bulunur. Nesnelerin toString() veya benzeri bir metodları çağrıldığında, otomatik olarak seçili locale'i kullanarak string oluşturmaları beklenir.

Locale Hangi Alanlardan Oluşur
Programlama dillerinden locale kavramsal olarak alt parçalara ayrılmıştır. Farklı diller bile olsalar alt parçalar arasında kısmi bir örtüşme görülebilir.

C++
C++'ta LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME şeklinde sabitler kullanılarak para, sayı, zaman şeklinde başlıklara bölünmüş.

Locale Bilgisini Saklayan Sınıflar
C++
facet nedir? - Locale alt parçalarının kalıttığı sınıf
C++ dilinde locale ile ilgili formatlama bilgileri facet temel sınıfından türeyen hiyerarşide tutulur. Yani facet, locale alt parçalarının kalıttığı sınıftır.

facet sınıfı kopyalanamaz. C++ standardında bir çok facet sınıfı hazır geliyor. Örneğin ctype sınıfının std::locale::facet sınıfında türediği burada görülebilir.

Aşağıdaki facet şeklini de buradan aldım ve kalıtım görülebilir.


facet'ten türetme
Kendi facet sınıfımızı hazır gelen sınıflardan kalıtarak oluşturabiliriz. Örnekte rakamlar hariç diğer tüm karakterleri boşluk (space) olarak okuyan bir ctype facet var.

struct digits_only: std::ctype<char> {
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table() {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
        return &rc[0];
    }
};

locale sınıfı nedir? - Tüm facetleri birleştiren sınıf
locale sınıfı, facetlerden kalıtan tüm nesneleri birleştirip belli bir ülke ile eşleştiren sınıftır.

Bir locale bir çok facet'ten oluşmaktadır. Aşağıdaki şekili buradan aldım ve bunu gösteriyor.
ctype facet ne işe yarar
Bu facet ile karakterler sınıflandırılır (isdigit(), isascii() vs.) ve karakterlerin büyük, küçük harf dönüşümü yapılabilir.

Locale Sınıfı İçindeki Facet'e Nasıl Erişilir
std::use_facet() metodu ile erişilir. Örnek'te local'den ctype facet alınıyor. Daha sonra facet'in toupper() metodu çağırılıyor.
std::ctype<char> const &ctype_facet = std::use_facet<std::ctype<char> >(some_locale);
char upper_a = ctype_facet.toupper('a');

Locale Sınıfına Yeni Facet Tipi Nasıl Yerleştirilir
En kolay yöntemi locale sınıfının constructor metoduna facet nesnesinin parametre olarak verilmesi. Örnek: Facet sınıfının desctructor metodu protected olduğu için heap'te yaratılması gerekir.
std::locale numbers(std::locale(), new digits_only);
 
Clasic Locale ve Facet Kullanımı
Örnek:

std::stringstream ss;
local_time_facet* output_facet = new local_time_facet();
ss.imbue(std::locale(std::locale::classic(), output_facet));
output_facet->format("%Y-%m-%dT%H:%M:%S %Q");
ss << ldt;
Stream'in Kendi Locale Nesnesi ve Facet Kullanımı
getloc() metodu ile stream'in locale nesnesi alınabilir.
Örnek:


Ayraçlara Göre Formatlama Yapan Metodlar

Win32
GetDateFormat metodu
Örnek:
SYSTEMTIME create_local_time;

TCHAR time[128] = {0};
const TCHAR *format = _T("yyyy/MM/dd");
GetLocalTime(&create_local_time);
GetDateFormat( LOCALE_USER_DEFAULT, 0, &create_local_time, format, time, 128);
Locale ve String Karşılaştırma
Bazı ülkelerde farklı karakterler aynı gibi algılanıyor. Örneğin Almanca'da Hauptstrasse ve Hauptstraße aynı kelimeler. Bu kelimeleri farklı işlemek istersek StringComparer sınıfını kullanarak aşağıdaki gibi yapabiliriz.



Kabuktan Locale'i Ayarlamak
Uygulamalar çalıştırıldıkları kabuğun locale ayarlarını kullanırlar. Bazen uygulama yerine kabuk locale ayarlarını değiştirmek daha kolay olabilir.

bash'te locale için kullanılabilecek her alanı locale komutu ile görebiliriz. Diğer Unix türevlerinde alanların isimler değişiklik gösterir. Türkçe Linux'ta alanların değeri "tr_TR.UTF-8" dir
root@icubes:[~]# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

LC_ALL her alanı ayrı ayrı ayarlamak yerine tümüne birden bir değer atamak için kullanılır.
C locale'ini kullanmak istersek en başa aşağıdaki satırları yazmak gerek.
# Set to "C" locale so we can parse messages from commands
LANG=C
export LANG
Locale dosyaları nerededir?
Linux'ta locale dosyaları /usr/share/i18n/locales/ dizini altında. Örneğin Türkçe locale dosyası /usr/share/i18n/locales/tr_TR. Bu dosya okunabilir denemez. Kendine göre bir formatı var.


18 Mayıs 2015 Pazartesi

JMX

Giriş
JMX ile bazı uygulamaların ayarlarını değiştirmek mümkün.

1. Yöntem
Şöyle yaparız. Önce bir URL'ye bağlantı açarız. Daha sonra bağlantının invoke metoduna çağırmak istediğimiz bean'in metod ve parametrelerini geçeriz.
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

JMXServiceURL url = new JMXServiceURL("URL");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("com.example.package:service=EXOB");
Object  Params[] = {"str"};
String  Sig[] = {String.class.getName()};
mbsc.invoke(mbeanName,"routine1",Params,Sig);
jmxc.close();

2. Yöntem
MBean Proxy kullanırız.
EXOBMBean exob = JMX.newMBeanProxy(mbs, name, EXOBMBean.class);
exob.routine1();