вторник, 9 ноября 2010 г.

Байтовые преобразования

Возникла стандартная задача преобразовать примитивный тип данных (дабл, лонг и т.д.) в массив байт (грубо говоря сериализовать). И конечно же джава как всегда предлагает нам УМЛ диаграммы даже для такой тривиальной херни. Поэтому пришлось потратить время, чтобы изучить три варианта решения (доступные out-of-the-box в джаве) и узнать какой из них лучше.

 1. Первый вариант, который активно советуют везде и который самый отстойный, - использование поточных классов: ByteArrayOutputStream, обернутый в DataOutputStream. Инстансы поточных классов мы конечно же не создаем каждый раз, но это все равно не спасает
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
...
dos.writeDouble(d);
byte[] result = bos.toByteArray();

 2. Вариант второй - использовать появившийся в Java 1.5 (и оставшийс поныне) годный класс ByteBuffer.
ByteBuffer bb = ByteBuffer.allocate(8);
bb.putDouble(d);
byte[] result = bb.array();

 3. Третий вариант - выполнять все побитово-байтовые операции ручками. Изучать представление дабла было в лом, проверил его лишь для лонга.

Результаты затрачиваемого времени следующие:
Поточный способ : Способ с ByteBuffer : Ручной способ  =  3.42 : 1.37 : 1

Никто и не сомневался, что ручной способ будет быстрее всех. но неожиданной стала большая разница времени выполнения между байтбуфером и поточными классами.
Disclaimer! Тесты были выполнены без надлежащей подготовки, самым что ни на есть кустарным образом, и результаты нельзя трактовать абсолютным образом.

среда, 8 сентября 2010 г.

Подробнее про MongoDB

В предыдущем посте я рассказал, о том, что MongoDB показалась мне интересным решением для моего стартующего проекта. Пока не уверен, буду ли в итоге использовать эту базу данных. Но немножко нарытой информации не помешает.

Поначалу, когда начинаешь читать основные ресурсы про монгу, перестаешь понимать, почему люди до сих пор используют всякие реляционные базы данных, да и вообще все другие базы кроме монги. Ведь она идеальна!
Ресурсы, которые ведут к такому впечатлению:

1. книга MongoDB in Action (традиционно, какую книгу маннинга не начинаю читать - сразу руки чешутся применить технологию): книга еще в процессе написания, но первая свободно доступная глава оттуда создает впечатление, что монгу следует использовать как можно чаще и везде.

2. показательный хэппи случай использования монги вместо мускула

3. конечно же сам сайт монги, читаешь и восхищаешься

4. презентация с советами по оптимизации монги, добавляющая уверенности в успехе

Однако, еще до достижения необходимого уровня экстаза для начала использования монги, удалось нагуглить и другие мнения.

1. критика и обвинения монги (там есть ссылка на самую первую статью автора, затем на якобы-ответ-от-монговцев ну и дальше уже следует читать основную статью)

2. еще один сочный бугурт от попытки реального применения старой версии монги, имеется и небольшое продолжение.

3. здоровенная статья критика монги от девелопера ... CouchDB! здесь имеется закешированный вариант с комментами, в том числе и от разработчиков монги

На десерт более менее объективная (как говорится, не biased) статья о том, как сделать монгу надежнее.

Что же остается сказать от себя. Судя по тому, что я прочитал, монга представляет собой быструю базу данных с отсутствием схемы. Ради этих двух преимуществ жертвуется надежность данных (как при аппаратном сбое так и при нормальном функционировании). Уровень достигаемого компромисса всячески настраивается, в следующем релизе 1.8 обещают некоторый уровень надежности на одиночном сервере. Кроме того, требуется достаточно большой объем оперативной памяти и 64битность сервера для того. чтобы монга могла проявить себя с лучшей стороны.

Толстая база данных

Стоит задача хранить большое количество сообщений приходящих постоянно с транспортных средств. Сообщения содержат параметры в весьма разнообразной форме (имеется несколько типов сообщений, в будущем не исключена возможность динамической, а не фиксированной структуры). Эти параметры в последствии используются для построения разнообразных отчетов.
Конкретно по объему приходящих сообщений: в рабочее время держится уровень 15-20 сообщений в секунду, ночью значительно меньше, но сообщения идут круглосуточно. Хотелось бы обеспечить хранение для средней скорости поступления 100 сообщений в секунду.

1. Первая попытка была для реляционной базы данных.
Так как структура сообщений разнится, то я решил выделить параметры сообщения в отдельную таблицу (связывая строки-параметры с сообщением через foreign key). На каждое сообщение приходится примерно 10-15 параметров в среднем. Но тогда получается, что в секунду у меня в среднем будет создаваться 100 * 15 = 1500 строк-параметров. Сколько это в месяц? 1500 * 3600 * 24 * 30 = ...3888000000 . Кхе-кхе-кхе. Я разделю пробелами: 3 888 000 000. Почти 4 миллиарда! Такой объем просто неподъемен для операций джойна (мне надо будет выбирать сообщения для одного транспортного средства и к ним джойнить все соответствующие параметры). Кроме того - сколько это займет на жестком диске? Возможные варианты оптимизации в таком случае - разбиение таблицы (поддерживается постгресом).

2. Альтернативный вариант для реляционной БД - не выделять параметры в отдельную таблицу. Но тогда придется создать пригодную для всех структур сообщений схему. Скорее всего это будет большое число колонок, которые будут заполняться частично в зависимости от сообщения. Решение такое не гибкое и не позволяет детально описывать значения параметров, однако избавляет нас от джойна и излишне большого числа строк. В таком сценарии мы будем ограничены 200-300 миллионами записей в месяц. Неприятно но, думаю, возможно.

Данные, имеющие возраст более месяца можно будет архивировать, так что значения для одного месяца примерно и будут представлять собой среднюю загруженность базы данных.

3. Кардинальная альтернатива - использование дивных зверей из лагеря NoSQL. По крайней мере среди них есть два кандидата, предлагающие решение проблемы разнящейся структуры сообщений. Это MongoDB и CouchDB, так называемые schema-less базы данных. Записи в них грубо говоря имеют JSON вид и ничто не мешает нам добавлять произвольные аттрибуты в произвольную запись. Запросы по атрибутам имеются, что выгодно отличает эти две базы данных от простых key/value баз данных. Однако, произвольность аттрибутов, говорят, ведет к обильному пожиранию дискового пространства. Вобщем тут тоже не без проблем.

На данный момент склоняюсь ко второму варианту. Он хоть архитектурно и не красив, но по крайней мере выглядит наиболее жизнеспособным для реальных боевых условий.

суббота, 28 августа 2010 г.

Trash решение - файлов спасение

Все-таки неприятно использовать rm при очередном наведении порядка в линупсе. И неправильно это, удалять всякие легковесные конфиги и папки безвозвратно. Правильно сперва удалять их в мусорку, а затем по истечении времени и отсутствии признаков паники удалять насовсем.

Поэтому не стоит удивляться, что теме треша уделено достаточное внимание - разработана даже спецификация специально для мусора. А все потому что тупо совать файлы во временную папку это еще далеко не тру треш-стайл. Истинный мусоровоз должен уметь хранить файлы с одинаковыми именами, запоминать время удаления и место, откуда файл был удален. Так что можно будет и восстановить в случае оплошности.

К сожалению дефолтной команды для управления мусором через консоль для своей Xfce-гентушки я не нашел. В портеже тоже не оказалось нужного пекеджа. Пришлось ставить вручную годный тул trash-cli. Он к слову сказать на питоне писан.

Теперь с удовольствием сижу и удаляю файлы, а потом их восстанавливаю... Красота!

P.S. Википедия пишет, что спецификация треша реализована помимо Xfce еще и в KDE и Gnome. Так что trash-cli должен работать и в этих средах.

суббота, 15 мая 2010 г.

Продемонстрируй быдло-сайт!

Как я уже упоминал в предыдущих постах, быдло философия в айти имеет очень важное значение.
Но вот представьте: пишите вы совершенно быдляцкий быдлосайт на джумле, и уже готовы продемонстрировать его заказчику. Но в силу своей нефрилансерской сущности под рукой не имеется машины, имеющей статический ип в интернете. Хостинг для проекта тоже еще не куплен. Беда!

На помощь приходит сервис временного хостинга: http://tempopage.com

Все делается мгновенно: задаете время жизни своего сайта (от 1 часа до 30 дней), выбираете предустановленную CMS (на момент написания доступны Joomla 1.5 и Wordpress 2.7), подтверждаете регистрацию через почту и вуаля! В вашем распоряжении фтп доступ к внутренностям приложения джумлы (признаюсь, не пробовал удалять все и подсовывать другое пхп приложение) и phpMyAdmin доступ к MySQL (доступна 1 база данных).
Все это конечно же бесплатно.
Очень неприятный минус - частые недолгие падения сайта. Зашел на сайт - работает, через 5 мин попробовал - уже недоступен. Однако на главной странице сервиса имеется подозрительная надпись "Beta 1.0v" вне всякого контекста. Можно предположить, что сервис тестируется и улучшается и минус этот будет устранен в дальнейшем.

понедельник, 1 марта 2010 г.

Python GUI

Решил значит я написать десктопное приложение на питоне, в котором требовался бы определенный набор виджетов, а так же рисование несложных, но интерактивных 2д высеров. И сразу же увяз в болоте различных вариантов графического представления. С ним у питона не все гладко.

Итак на данный момент что известно

  • wxPython - бегемот, однако вроде активно юзается. Депенденси для него составляет 29 неприятных метров. Бегемотность и является самым большим минусом.
  • PyQT - еще более бегемотистый (но и по всей видимости более продвинутый - имеется релиз для 3го питона) бегемот. Минус опять же размер депенденси ( в которую входит нафиг не сдавшиеся мне вспомогательные С++ костыли из qt-core).
  • pygame - надстройка над SDL для питона. Примеры игрух выглядят весьма убого. Так же немного не прельщает реализация собственного мейн цикла. Полноценной библиотеки виджетов нету. Депенденси небольшая, однако работа со звуком мне на данный момент не нужна, с виджетами как уже сказал проблема. Посему смысл использования теряется.
  • кучи всяких дохлых библиотек не дошедших даже до релиза 1.* : AnyGui, EasyGui, OcempGUI, Ocean, PyUi
То, что подает надежды
  • pyFLTK - байндинг питона на FLTK, некий легковесный с++ гуи тулкит. И pyFLTK, и FLTK доступны в генту портеже, оба проекта живы.
  • AVC - позволяет не привязываться к определенному ГУИ фреймворку а легко
    переключаться между ними:  GTK+, Qt3, Qt4, Tk, wxWidgets, Swing в Jython.
  • Tkinter - вроде в последних версиях начал выглядеть прилично, плюс здесь можно найти библиотеки для него, первая pmw очевидно жива и даже входит в gentoo portage. Также обнаружено расширение Tix. Также упоминались некоторое расширение тем ttk, есть даже какой-то проект. Надо проработать тему расширений для Tkinter.
Так что на данный момент хотелось бы попробовать [AVC +] Tkinter.

четверг, 11 февраля 2010 г.

Struts 2 и две submit кнопки в форме

На самом деле кнопок может быть и больше. Но именно столько мне необходимо было предоставить. Сценарий прост: надо произвести два разных действия по реакции на одну  иту же форму. обычными ресетами тут не обойтись. Поэтому встречаем костыль-решение, которое я взял отсюда (надеюсь автор не будет против на распространение такой нужной информации).


1. в кнопках пишем

<input type="submit" name="submitSave" value="Сохранить"/>
<input type="submit" name="submitCancel" value="Отмена"/>

2. в стратс экшене пишем

private boolean submitSave = false;
private boolean submitCancel = false;
   
public void setSubmitSave(boolean submitSave) {
    this.submitSave = true;
}
public void setSubmitCancel(boolean submitCancel) {
    this.submitCancel = true;
}

Вуаля, вот он костылек, в сеттерах. После этого можно юзать булеан филды и быть счастливым.



CSS будни

Очередная бородатая проблема с нормальным размещением контента на странице с использованием CSS. На этот раз было необходимо просто центрировать по вертикали один <div> внутри другого <div>'а. Совершенно простая задача, но решается через костыли (увы-увы, мой милый цсс, ты слишком идеален для нашего грязного мира).

Подходы которые не работают (и которые не следует даже пытаться реализовать):
  • аналогично центрированию по горизонтали margin-top: auto; margin-bottom: auto;
  • margin-top: 50%; даже при определенной высоте отца-контейнера приводит к каким-то рандомным скаканиям
Делать правильно нужно так:
  1. ставим у дива-отца position: relative; и не забываем задать его высоту.
  2. ставим у дива-сына position: absolute; и top: 50%;


понедельник, 1 февраля 2010 г.

Graphviz: начало

Да. Нелегко девелопить небольшой проект. Так и тянутся руки применять совершенно ненужные фичи чтобы поиграться с ними. Вот такова и история Graphviz в моей жизни. Так или иначе, о нем есть что рассказать.
Использовать Graphviz я решил по причине сильного нежелания генерить картинки диаграмм классов в какой-нить UML тулзе и потом вставлять эту картинку в вики проекта. Не хотелось при каждом изменении заново открывать диаграмму в тулзе, заново генерить картинку, заново ее вставлять в вики. Мне показалось, что данная последовательность действий - это, как говорят, overkill. Ведь я всего лишь хочу отобразить отношения между сущностями (оххохо). И для этого мне совершенно неважно как они будут расположены относительно друг друга. В случае с UML тулзой я решаю и эту ненужную задачу (конечно для красивых презентаций это задача нужна, но не в случае с вики). Примерно так же думали и разработчики Graphviz.

Для моей задачи я использовал не весь Graphviz, а только его подмодуль - dot.
Полезной оказалась статья http://www.ffnn.nl/pages/articles/media/uml-diagrams-using-graphviz-dot.php показывающая примеры использования DOT language для рисования диаграммы классов. В статье не показаны примеры различных типов стрелок (вы же помните эти глупые стрелки агрегации и композиции!), для этого юзаем параметр arrowhead.
Следует также помнить что для включения DOT маркапа в вики трака нужно поставить плагин, а в самой вики писать

{{{
#!graphviz

здесь ваш DOT-код

}}}

Вот как я стильно заюзал DOT для своей диаграмки

{{{
#!graphviz
digraph G {
node [
shape = "record"
]
Report->Message [arrowhead = diamond ]
FieldValue->Report [arrowhead = odiamond]
Field->ReportType [arrowhead = odiamond]
Field->FieldValue [arrowhead = diamond]
}
}}}

Trac: удовольствие разработки

Мдя, вот такой пафосный заголовок, но действительно интересно становится, когда упорядочиваешь проект с помощью Trac.

Немножко ознакомившись с Trac, начал искать разную инфу. Теперь мне пора закрывать все 50 открытых вкладок и поэтому решил сохранить все полезное в этом посте. Вот что получилось:
Кроме того нашел-таки способ рисовать диаграммы в вики с помощью маркапа:
  1. Ставим себе визуализатор http://www.graphviz.org
  2. Ставим плагин http://trac-hacks.org/wiki/GraphvizPlugin
  3. Наслаждаемся автоматическим рисованием стрелочек, кружочков и квадратиков по мановению руки.
Синтаксис для Graphviz весьма простой, но требуется время чтобы нагуглить то, что нужно. Поэтому в следующем посте размещу кое-что полезное по нему.

Trac: начало

На самом деле я имел удовольствие познакомиться с Trac уже давно. Однако знакомство то было мимолетным, оставив лишь приятное впечатление легкости интерфейса по сравнению с другими системами проджект менеджмента/баг трекинга.

По умолчанию следует думать, что в траке все замечательно. Исключения составляют следующие соображения:

  • на одном из форумов было указано на то, что из-за системы перекрестных ссылок в репозитории-вики-тикетах использование репозитория в другом проекте (например при создании форка проекта) приносит большие головные боли. Иными словами перекрестные ссылки создают связанность всех компонентов, которая очень удобна но только при сохранении целостности проекта.

  • я не нашел (пока) удобного варианта для быстрого редактирования хотя бы простых диаграмм в вики трака



При установке плагинов для windows версии трака следует проделать следующий костылек (найден в ридми BitNami Trac):

NOTE FOR WINDOWS USERS: Currently,
the easy_install Python script works a little funky
on Windows. We're already working on fixing it, but
installing Python eggs using the mentioned operating
systems needs a bit of extra tweaking. To install
a Trac plugin like WebAdmin, for example, you will
need to follow the guidelines available at
http://trac.edgewall.org/wiki/WebAdmin , and after
that, stop your servers using the Start Menu Shortcuts and copy

* python/DLLs
* python/Lib

folders to

* apache2/bin

overwriting its contents. That done, launch
the servers again and everything should work fine.


среда, 20 января 2010 г.

Быстрая быдлоустановка CMS

Многие знают о таком замечательном проекте как AppServ, помогающем перейти к написанию среднестатистического веб сайта практически сразу, не заморачиваясь о том, как все необходимое добро (апач, майскл и пхп) настроить и связать друг с другом.
Недавно наткнулся на неплохой сайтец предлагающий нечто похожее, но уже для всяких багтрекингов, проджект менеджмент тулзов и CMS. Вот он, спаситель нашего времени: http://bitnami.org/ Доступны стеки (так они называют свои пребилд пакеты "все в одном") для всех основных платформ.
В итоге смог поставить Trac за 5 мин и изучить как и что в нем за 30. Хотя до этого потратил несколько часов чтобы поставить питон, либу к питону, еще одну либу к питону, узнать что коннектор к базе данных для нового питона еще не готов, переставить все предыдущее, поставить коннектор к базе данных, скачать Trac, попытаться поставить все это добро и лишиться терпения.
Да здравствует быдло установка!