<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7406927564845666646</id><updated>2012-02-16T18:43:57.186+10:00</updated><category term='watcom'/><category term='gcc'/><category term='couchdb'/><category term='jdbc'/><category term='benchmarks'/><category term='java'/><category term='erlang'/><title type='text'>Досрочно завершим!</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-8280737415145884717</id><published>2009-06-29T05:57:00.005+10:00</published><updated>2009-06-29T06:20:10.169+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><category scheme='http://www.blogger.com/atom/ns#' term='watcom'/><title type='text'>watcom vs gcc</title><content type='html'>Для удовлетворения любопытства, скачал openwatcom 1.8 (такой бывший когда то известным компилятор c/c++), исходники под линукс. собрал, и попробовал тестовую задачку, вот эту вот: &lt;a href="http://shootout.alioth.debian.org/u32q/benchmark.php?test=binarytrees&amp;lang=gcc&amp;box=1"&gt;http://shootout.alioth.debian.org/u32q/benchmark.php?test=binarytrees&amp;amp;lang=gcc&amp;amp;box=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Резуьтаты:&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;GCC&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;walrus@home:/home/walrus/sandbox$ gcc btr.c -O3 -o btr_gcc -lm&lt;br /&gt;walrus@home:/home/walrus/sandbox$ time ./btr_gcc 20&lt;br /&gt;stretch tree of depth 21  check: -1&lt;br /&gt;2097152  trees of depth 4  check: -2097152&lt;br /&gt;524288  trees of depth 6  check: -524288&lt;br /&gt;131072  trees of depth 8  check: -131072&lt;br /&gt;32768  trees of depth 10  check: -32768&lt;br /&gt;8192  trees of depth 12  check: -8192&lt;br /&gt;2048  trees of depth 14  check: -2048&lt;br /&gt;512  trees of depth 16  check: -512&lt;br /&gt;128  trees of depth 18  check: -128&lt;br /&gt;32  trees of depth 20  check: -32&lt;br /&gt;long lived tree of depth 20  check: -1&lt;br /&gt;&lt;br /&gt;real 1m2.138s&lt;br /&gt;user 1m1.852s&lt;br /&gt;sys 0m0.120s&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;watcom&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;walrus@home:/home/walrus/sandbox$ PATH=$PATH:/opt/watcom/binl WATCOM=/opt/watcom owcc -I/opt/watcom/h  -O3 -obtr_wc  btr.c &lt;br /&gt;walrus@home:/home/walrus/sandbox$ time ./btr_wc 20&lt;br /&gt;stretch tree of depth 21  check: -1&lt;br /&gt;2097152  trees of depth 4  check: -2097152&lt;br /&gt;524288  trees of depth 6  check: -524288&lt;br /&gt;131072  trees of depth 8  check: -131072&lt;br /&gt;32768  trees of depth 10  check: -32768&lt;br /&gt;8192  trees of depth 12  check: -8192&lt;br /&gt;2048  trees of depth 14  check: -2048&lt;br /&gt;512  trees of depth 16  check: -512&lt;br /&gt;128  trees of depth 18  check: -128&lt;br /&gt;32  trees of depth 20  check: -32&lt;br /&gt;long lived tree of depth 20  check: -1&lt;br /&gt;&lt;br /&gt;real 0m47.934s&lt;br /&gt;user 0m47.675s&lt;br /&gt;sys 0m0.136s&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;62 секунды против 48 в пользу watcom-а. Ай да старик watcom!! Вот это да!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UPD&lt;/span&gt; Да, забыл - ubuntu 9.04 32 AMD, 4000+, gcc gcc версия 4.3.3 (Ubuntu 4.3.3-5ubuntu4), watcom :&lt;br /&gt;&lt;blockquote&gt; owcc -v&lt;br /&gt;Open Watcom C/C++32 Compiler Driver Program Version 1.8beta1 LA&lt;br /&gt;Portions Copyright (c) 1988-2002 Sybase, Inc. All Rights Reserved.&lt;br /&gt;Source code is available under the Sybase Open Watcom Public License.&lt;br /&gt;See http://www.openwatcom.org/ for details.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-8280737415145884717?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/8280737415145884717/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=8280737415145884717' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/8280737415145884717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/8280737415145884717'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2009/06/watcom-vs-gcc.html' title='watcom vs gcc'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-1628244138034154040</id><published>2008-09-05T00:18:00.003+10:00</published><updated>2009-06-29T06:20:35.504+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='couchdb'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><title type='text'>couchdb benchmark еще раз</title><content type='html'>Попробоавл тот же тест, но 10 процессов по 10000 записей. Суммарные цифры - 100_000 записей за 2308 сек. То есть 43 записи/сек. Примерно так же как и в прошлом тесте. Похоже, быстрее уде не разогнать.&lt;br /&gt;&lt;br /&gt;Размер базы при 100000 записях - 0.6G&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-1628244138034154040?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/1628244138034154040/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=1628244138034154040' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/1628244138034154040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/1628244138034154040'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/09/couchdb-benchmark_04.html' title='couchdb benchmark еще раз'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-3427813830492947743</id><published>2008-09-05T00:10:00.004+10:00</published><updated>2009-06-29T06:20:56.117+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='couchdb'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><title type='text'>couchdb benchmark II</title><content type='html'>Однако не все так плохо.. &lt;br /&gt;&lt;br /&gt;Если запустить 50 программ, каждая из которых пытается вставить по 200 записей (те же 10000 записей, что и в прошлом тесте), то вставка всех записей укладывается в 220 сек. Значит - суммарно скорость вставки при 50 процессах - 45 записей в секунду.&lt;br /&gt;&lt;br /&gt;Кстати - база couchdb с 10000 записями (структура в предыдущем сообшении блога) занимает 54.3M.&lt;br /&gt;&lt;br /&gt;На компьютере Intel 3.2GHz, RAM 1G, ubuntu 8.04&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-3427813830492947743?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/3427813830492947743/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=3427813830492947743' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3427813830492947743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3427813830492947743'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/09/couchdb-benchmark-ii.html' title='couchdb benchmark II'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-3131192150933223266</id><published>2008-09-04T22:53:00.007+10:00</published><updated>2009-06-29T06:21:21.373+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='couchdb'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><title type='text'>couchdb benchmark</title><content type='html'>Захотелось попробовать новую couchdb. Выглядит она хорошо, и все сделано удобно. Однако прежде чем ее использовать в каком-нибудь проекте, хотелось бы оценит ее возможности более точно.&lt;br /&gt;&lt;br /&gt;Прежде всего посмотрим скорострельность.&lt;br /&gt;Для этого напишем мелкую программу на питоне, которая вставляет ну.. 10000 записей. и пусть пишет сколько секунд прошло с начала теста.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;from couchdb import Server&lt;br /&gt;import time&lt;br /&gt;&lt;br /&gt;server = Server('http://localhost:5984/')&lt;br /&gt;del server['benchmark']&lt;br /&gt;&lt;br /&gt;db = server.create('benchmark')&lt;br /&gt;benchstart = int(time.time())&lt;br /&gt;print "Begin test %s"%benchstart&lt;br /&gt;for i in range(1,10000):&lt;br /&gt;    doc_id = db.create({'type': 'BenchRecord', 'intfld': i, 'charfld': 'SomeName%s'%i })&lt;br /&gt;    if i % 100 == 0:&lt;br /&gt;#        print "%s :: %s "%(datetime.datetime.today(),i)&lt;br /&gt;         bench_offset = int(time.time()) - benchstart&lt;br /&gt;         print "%d\t%d "%(bench_offset,i)&lt;br /&gt;&lt;br /&gt;print "End test, %d sec"%(int(time.time()) - benchstart)&lt;br /&gt;del server['benchmark']&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Запускаем - получили в результате:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Begin test 1220531930&lt;br /&gt;6 100 &lt;br /&gt;11 200 &lt;br /&gt;17 300 &lt;br /&gt;23 400 &lt;br /&gt;29 500 &lt;br /&gt;35 600 &lt;br /&gt;40 700 &lt;br /&gt;46 800 &lt;br /&gt;52 900 &lt;br /&gt;58 1000 &lt;br /&gt;64 1100 &lt;br /&gt;70 1200 &lt;br /&gt;76 1300 &lt;br /&gt;82 1400 &lt;br /&gt;87 1500 &lt;br /&gt;93 1600 &lt;br /&gt;99 1700 &lt;br /&gt;105 1800 &lt;br /&gt;111 1900 &lt;br /&gt;117 2000 &lt;br /&gt;123 2100 &lt;br /&gt;129 2200 &lt;br /&gt;135 2300 &lt;br /&gt;140 2400 &lt;br /&gt;146 2500 &lt;br /&gt;152 2600 &lt;br /&gt;158 2700 &lt;br /&gt;164 2800 &lt;br /&gt;170 2900 &lt;br /&gt;176 3000 &lt;br /&gt;182 3100 &lt;br /&gt;188 3200 &lt;br /&gt;194 3300 &lt;br /&gt;200 3400 &lt;br /&gt;206 3500 &lt;br /&gt;212 3600 &lt;br /&gt;218 3700 &lt;br /&gt;224 3800 &lt;br /&gt;229 3900 &lt;br /&gt;235 4000 &lt;br /&gt;241 4100 &lt;br /&gt;247 4200 &lt;br /&gt;254 4300 &lt;br /&gt;260 4400 &lt;br /&gt;266 4500 &lt;br /&gt;272 4600 &lt;br /&gt;278 4700 &lt;br /&gt;284 4800 &lt;br /&gt;290 4900 &lt;br /&gt;296 5000 &lt;br /&gt;302 5100 &lt;br /&gt;309 5200 &lt;br /&gt;315 5300 &lt;br /&gt;321 5400 &lt;br /&gt;327 5500 &lt;br /&gt;333 5600 &lt;br /&gt;339 5700 &lt;br /&gt;345 5800 &lt;br /&gt;351 5900 &lt;br /&gt;357 6000 &lt;br /&gt;363 6100 &lt;br /&gt;369 6200 &lt;br /&gt;376 6300 &lt;br /&gt;382 6400 &lt;br /&gt;388 6500 &lt;br /&gt;394 6600 &lt;br /&gt;400 6700 &lt;br /&gt;406 6800 &lt;br /&gt;412 6900 &lt;br /&gt;418 7000 &lt;br /&gt;424 7100 &lt;br /&gt;430 7200 &lt;br /&gt;436 7300 &lt;br /&gt;442 7400 &lt;br /&gt;448 7500 &lt;br /&gt;454 7600 &lt;br /&gt;460 7700 &lt;br /&gt;466 7800 &lt;br /&gt;472 7900 &lt;br /&gt;478 8000 &lt;br /&gt;484 8100 &lt;br /&gt;490 8200 &lt;br /&gt;496 8300 &lt;br /&gt;502 8400 &lt;br /&gt;508 8500 &lt;br /&gt;514 8600 &lt;br /&gt;520 8700 &lt;br /&gt;526 8800 &lt;br /&gt;532 8900 &lt;br /&gt;538 9000 &lt;br /&gt;544 9100 &lt;br /&gt;550 9200 &lt;br /&gt;556 9300 &lt;br /&gt;562 9400 &lt;br /&gt;568 9500 &lt;br /&gt;574 9600 &lt;br /&gt;580 9700 &lt;br /&gt;587 9800 &lt;br /&gt;593 9900 &lt;br /&gt;End test, 599 sec&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Отсюда мораль. &lt;br /&gt;&lt;br /&gt;1)Вставка 100 записей за (в  среднем) 6 секунд. Немного. 16 записей/сек&lt;br /&gt;&lt;br /&gt;2)достаточно линейно , в диапазоне до 10000 записей.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-3131192150933223266?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/3131192150933223266/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=3131192150933223266' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3131192150933223266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3131192150933223266'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/09/couchdb-benchmark.html' title='couchdb benchmark'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-3325772147516389097</id><published>2008-08-16T23:43:00.001+10:00</published><updated>2008-08-16T23:44:46.484+10:00</updated><title type='text'></title><content type='html'>&lt;table height="1" cellspacing="0" cellpadding="0" border="0"&gt;&lt;tr&gt;&lt;td height="1"&gt;&lt;embed src="http://www.myheritagefiles.com/video/L/28/nsxi84_7016384a8d6a84wpi7kt84" width="340" height="340" type="application/x-shockwave-flash" wmode="transparent"&gt;&lt;/embed&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;a href="http://www.myheritage.com/index.php?lang=RU"  &gt;MyHeritage&lt;/a&gt;: &lt;a href="http://www.myheritage.com/index.php?lang=RU"  &gt;Генеалогические деревья&lt;/a&gt; - &lt;a href="http://www.myheritage.com/FP/Company/genealogy.php?lang=RU"  &gt;Генеалогия&lt;/a&gt; - &lt;a href="http://www.myheritage.com/FP/Company/celebrities.php?lang=RU"  &gt;Знаменитости&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-3325772147516389097?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/3325772147516389097/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=3325772147516389097' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3325772147516389097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/3325772147516389097'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/08/myheritage.html' title=''/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-888921286269456260</id><published>2008-06-22T05:26:00.005+10:00</published><updated>2010-08-11T14:12:06.543+10:00</updated><title type='text'>Марк Твен</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;"Если вам понадобится подвергнуть молодого человека тяжелому и мучительному наказанию, возьмите с него слово, что он в течение года будет вести дневник."&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;img height='1' width='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-888921286269456260?l=walrus16.blogspot.com'/&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-888921286269456260?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/888921286269456260/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=888921286269456260' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/888921286269456260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/888921286269456260'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/06/blog-post.html' title='Марк Твен'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-2489174978279078852</id><published>2008-06-06T01:11:00.009+10:00</published><updated>2008-06-06T01:47:59.494+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>erlang &amp; postgresql auth</title><content type='html'>Для прямого доступа из эрланга в postgresql (минуя odbc) есть хорошая библиотечка, написанная  Martin Carlsson из Erlang Training &amp; Consulting ltd (&lt;a href="http://erlang-consulting.com/aboutus/opensource.html"&gt;Здесь&lt;/a&gt;). &lt;br /&gt;У нее есть один недостаток - она рассчитана только на md5  authentication в постгресе.&lt;br /&gt;&lt;br /&gt;Если приложение разрабатывается с нуля, то md5 auth - не представляет проблемы, как захотим, так и настроим, но в нашем случае уже есть большой и толстый postgresql сервер, со своими админами и правилами выделения учетных записей. В этом сервере метод доступа у большинства аккаунтов - password. И никак это не поправишь. В отличие от технических проблем - административные проблемы плохо поддаются решению..&lt;br /&gt;&lt;br /&gt;Пришлось прочитать хорошенько документацию postgresql, раздел где описан протокол, и поправить erlang-овскую библиотеку. Вот, чтобы не забыть, что я там наисправлял, и  выкладываю diff&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diff -Naur oldsrc/psql_logic.erl src/psql_logic.erl&lt;br /&gt;--- oldsrc/psql_logic.erl       2006-09-18 17:46:20.000000000 +0200&lt;br /&gt;+++ src/psql_logic.erl  2008-03-12 17:41:48.000000000 +0100&lt;br /&gt;@@ -139,6 +139,12 @@&lt;br /&gt;     AuthDigest = psql_protocol:md5digest(State#state.digest, Salt),&lt;br /&gt;     psql_connection:command(State#state.connection, {send, AuthDigest}),&lt;br /&gt;     {next_state, authentication, State};&lt;br /&gt;+&lt;br /&gt;+authentication({psql, authentication, &lt;&lt;0,0,0,3&gt;&gt;}, State) -&gt;&lt;br /&gt;+    CTPassw = psql_protocol:ctpasswd(State#state.password),&lt;br /&gt;+    psql_connection:command(State#state.connection, {send, CTPassw}),&lt;br /&gt;+    {next_state, authentication, State};&lt;br /&gt;+&lt;br /&gt; authentication({psql, authentication, &lt;&lt;0,0,0,0&gt;&gt;}, State) -&gt;&lt;br /&gt;     {next_state, setup, State};&lt;br /&gt; authentication({psql, error, Error}, State) -&gt;&lt;br /&gt;diff -Naur oldsrc/psql_protocol.erl src/psql_protocol.erl&lt;br /&gt;--- oldsrc/psql_protocol.erl    2006-09-18 17:46:24.000000000 +0200&lt;br /&gt;+++ src/psql_protocol.erl       2008-03-12 17:41:31.000000000 +0100&lt;br /&gt;@@ -21,7 +21,7 @@&lt;br /&gt;         to_string/1]).&lt;br /&gt; &lt;br /&gt; -export([authenticate/4,&lt;br /&gt;-        md5digest/2,&lt;br /&gt;+        md5digest/2,ctpasswd/1,&lt;br /&gt;         copy_done/0,&lt;br /&gt;         q/1]).&lt;br /&gt; &lt;br /&gt;@@ -65,6 +65,9 @@&lt;br /&gt;     Auth = md5([Digest, Salt]),&lt;br /&gt;     {password_message, &lt;&lt;"md5", Auth/binary, 0:8&gt;&gt;}.&lt;br /&gt; &lt;br /&gt;+ctpasswd(Passw) -&gt;&lt;br /&gt;+    PB = list_to_binary(Passw),&lt;br /&gt;+    {password_message, &lt;&lt; PB/binary,0:8 &gt;&gt;}.&lt;br /&gt;+&lt;br /&gt; copy_done() -&gt;&lt;br /&gt;     {'copy_done', []}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-2489174978279078852?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/2489174978279078852/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=2489174978279078852' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/2489174978279078852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/2489174978279078852'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/06/erlang-postgresql-auth.html' title='erlang &amp; postgresql auth'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-6073991111566053096</id><published>2008-03-11T23:21:00.008+10:00</published><updated>2008-03-12T00:34:34.914+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>erlang snmp client</title><content type='html'>Вот понадобилось опрашивать некоторые железные switch через snmp из erlang. Первая попытка понять что для этого нужна (наскоком, по Буденновски) - не удалась. на erlang.org полно документации как писать и управлять snmp сервера, но вот информация по клиентам - разбросана по крупицам.  Так что пришлось собраться и создать картину у себя в голове, как должен выглядить snmp клиент.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Общая картина&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_qBKy8gbHL84/R9aWub9NqiI/AAAAAAAAAgE/4MwZSCirwtY/s1600-h/snmp_blog.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_qBKy8gbHL84/R9aWub9NqiI/AAAAAAAAAgE/4MwZSCirwtY/s320/snmp_blog.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5176490546231618082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Общая идея такая. Нет одной такой командочки типа snmpwalk. Мы вынуждены строить целую систему для того чтобы опросить железку. &lt;br /&gt;&lt;br /&gt;Есть snmp manager, мы его должны настроить и запустить, даже если у нас только клиент. Этот snmp manager содержит список snmp user. Я сначала думал что snmp user - это что-то типа community, оказалось - нет.. Snmp user в erlang - это такой &lt;span style="font-weight:bold;"&gt;модуль&lt;/span&gt;, который содержит просто набор callback для приема ответов от устройств.  &lt;br /&gt;&lt;br /&gt;Manager должен либо определять этого user-а в свой конфигурации, либо зарегистрировать его с помощью snmpm:register_user(имя, модуль).&lt;br /&gt;&lt;br /&gt;Дальше нам нужны agents. То есть manager каждому такому user назначает (в конфиге, либо с помощью snmpm:register_agent ) набор агентов которых опрашивать. Вот эти агенты как раз и содержат реквизиты опрашиваемых железок. Там, IP, community, port, версию протокола и т.д.&lt;br /&gt;&lt;br /&gt;Когда все это настроено, можно посылать из manager-а запрос. Например с помощью snmpm:ag(). Manager поищет в настройках который это агент(по адресу). Пошлет асинхронный запрос на железку, а когда придет ответ, Manager по привязанным user/agent, сообразит на которого user (ну грубо говоря в какой модуль) его переслать. &lt;br /&gt;&lt;br /&gt;В данном случает придет ответ на &lt;span style="font-style:italic;"&gt;handle_pdu(Addr, Port, ReqId, SnmpResponse, UserData)&lt;/span&gt; в том user-е к которому привязан  агент, куда посылался запрос.&lt;br /&gt;&lt;br /&gt;В следующих постах приведу примеры кода.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-6073991111566053096?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/6073991111566053096/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=6073991111566053096' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/6073991111566053096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/6073991111566053096'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/03/erlang-snmp-client.html' title='erlang snmp client'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_qBKy8gbHL84/R9aWub9NqiI/AAAAAAAAAgE/4MwZSCirwtY/s72-c/snmp_blog.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-5656492389474586302</id><published>2008-02-29T03:04:00.003+10:00</published><updated>2009-06-29T06:21:57.035+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmarks'/><title type='text'>Performance degradation for gcc</title><content type='html'>Просмативая свои старые архивы, нашел мелкую программу sieve- решето Эратосфена, которая была написана на разных языках. И там же валялся бинарник этой программы, скомпилированной gcc в далеком (по моему 2002) году. Запустил из интереса - получилось&lt;br /&gt;&lt;br /&gt;103763 iterations in 10.000000 seconds. &lt;br /&gt;&lt;br /&gt;Скомпилировал текущей версией gcc из ubuntu - получилось &lt;br /&gt;96992 iterations in 10.000000 seconds&lt;br /&gt;&lt;br /&gt;Вот тебе бабушка и Юрьев день!&lt;br /&gt;&lt;br /&gt;Какой был в 2002 gcc не помню, file a.out покзывает&lt;br /&gt;&lt;br /&gt;a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), not stripped&lt;br /&gt;&lt;br /&gt;Теперь у нас gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2), file показывает&lt;br /&gt;a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped&lt;br /&gt;&lt;br /&gt;То есть все честно.. Но медленнее..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-5656492389474586302?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/5656492389474586302/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=5656492389474586302' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/5656492389474586302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/5656492389474586302'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/02/performance-degradation-for-gcc.html' title='Performance degradation for gcc'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-6142914768585949656</id><published>2008-02-28T23:32:00.006+10:00</published><updated>2008-02-28T23:49:47.369+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Этот удивительный erlang - (sinan)</title><content type='html'>Решил для erlang попробовать sinan - систему построения application и релизов.. Вот такое он мне выдал сообщение при опечатке в конфигурационном файле:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;{error_logger, {{2008, 2, 28}, {14, 27, 26}}, "** Generic server ~p terminating \n** Last message in was ~p~n** When Server state == ~p~n** Reason for termination == ~n** ~p~n", [&lt;0.70.0&gt;, {parse, "/home/walrus/erlang_1/_build.cfg"}, {state, #Fun&lt;sin_parse_handle.parse_config_file.1&gt;, {dict, 9, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [["build_dir", 95, 98, 117, 105, 108, 100], ["default_flavor", 100, 101, 118, 101, 108, 111, 112, 109, 101, 110, 116], ["tasks"|{dict, 12, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [["dist"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "release"]], [], [], [], [], [["description", "Creates an tarball of the distribution including ", "release information. Check documentation for the ", "dist task for configuration information "]], [], [["handler", 115, 105, 110, 95, 100, 105, 115, 116, 95, 98, 117, 105, 108, 100, 101, 114]], [], []}}}]], [["release"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "build"]], [], [], [], [], [["description", "Creates the *.rel,  *.boot and *.script into the ", "&lt;build-area&gt;/realeases/&lt;vsn&gt; directory. It also ", "builds up a release tar bal into the ", "&lt;build-area&gt;/tar/ directory"]], [], [["handler", 115, 105, 110, 95, 114, 101, 108, 101, 97, 115, 101, 95, 98, 117, 105, 108, 100, 101, 114]], [], []}}}], ["help"|{dict, 2, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [], [], [], [["description", "Provides help information for the available tasks"]], [], [["handler", 115, 105, 110, 95, 104, 101, 108, 112]], [], []}}}]], [], [["depends"|{dict, 4, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "discover"]], [["callable"|true]], [], [], [], [["description", "Analyzes all of the dependencies in the project ", "and pulls down those that arn't curently available ", "locally"]], [], [["handler", 115, 105, 110, 95, 100, 101, 112, 101, 110, 100, 115]], [], []}}}]], [["check_depends"|{dict, 4, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "discover"]], [["callable"|false]], [], [], [], [["description", "Checks that dependencies have been run.  ", "If dependencies have not been run attempts to ", "run depends task"]], [], [["handler", 115, 105, 110, 95, 100, 101, 112, 101, 110, 100, 115, 95, 99, 104, 101, 99, 107]], [], []}}}]], [], [], [["discover"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [["callable"|false]], [], [], [], [["description", "Discovers information about the project and ", "updates the project information"]], [], [["handler", 115, 105, 110, 95, 100, 105, 115, 99, 111, 118, 101, 114]], [], []}}}]], [["analyze"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "build"]], [], [], [], [], [["description", "Runs dialyzer on the project and outputs information ", "to the user. This task may take a significant amount ", "of time"]], [], [["handler", 115, 105, 110, 95, 97, 110, 97, 108, 121, 122, 101]], [], []}}}]], [], [["doc"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "build"]], [], [], [], [], [["description", "Runs edoc across all sources in the project and ", "outputs it into the build area"]], [], [["handler", 115, 105, 110, 95, 101, 100, 111, 99]], [], []}}}]], [["clean"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends"]], [], [], [], [], [["description", "Removes the build area and everything underneath"]], [], [["handler", 115, 105, 110, 95, 99, 108, 101, 97, 110]], [], []}}}]], [["build"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "check_depends"]], [], [], [], [], [["description", 67, 111, 109, 112, 105, 108, 101, 115, 32, 97, 108, 108, 32, 111, 102, 32, 116, 104, 101, 32, 99, 111, 109, 112, 105, 108, 97, 98, 108, 101, 32, 102, 105, 108, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116]], [], [["handler", 115, 105, 110, 95, 101, 114, 108, 95, 98, 117, 105, 108, 100, 101, 114]], [], []}}}], ["test"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "build"]], [], [], [], [], [["description", 82, 117, 110, 115, 32, 97, 108, 108, 32, 111, 102, 32, 116, 104, 101, 32, 101, 120, 105, 115, 116, 105, 110, 103, 32, 101, 117, 110, 105, 116, 32, 117, 110, 105, 116, 32, 116, 101, 115, 116, 115, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116]], [], [["handler", 115, 105, 110, 95, 116, 101, 115, 116]], [], []}}}], ["shell"|{dict, 3, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [["depends", "build"]], [], [], [], [], [["description", "Starts an erlang shell with all of the correct ", "paths preset so the developer can noodle with the ", "code to his hearts content"]], [], [["handler", 115, 105, 110, 95, 115, 104, 101, 108, 108]], [], []}}}]]}}}]], [], [], [["ignore_dirs", "_", "."], ["flavors"|{dict, 2, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [["release"|{dict, 1, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [["build", 45, 68, 78, 79, 84, 69, 83, 84, 61, 49, 32, 45, 87, 49]]}}}]], [], [["development"|{dict, 1, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [["build", 43, 100, 101, 98, 117, 103, 95, 105, 110, 102, 111, 32, 45, 87, 49]]}}}]], [], [], [], [], [], [], [], [], []}}}]], [], [["ignore_apps"], ["default_task", 98, 117, 105, 108, 100]], [["config_dir", 99, 111, 110, 102, 105, 103]], [], [], [], [["build"|{dict, 2, 16, 16, 8, 80, 48, {[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []}, {{[], [], [], [], [], [], [], [], [["args"]], [], [], [], [], [], [["task"|undefined]], []}}}]]}}}, #Ref&lt;0.0.0.94&gt;}, {{badrecord, dict}, [{dict, fold_dict, 3}, {fconf_engine, handle_call, 3}, {gen_server, handle_msg, 6}, {proc_lib, init_p, 5}]}]}&lt;br /&gt;{error_logger, {{2008, 2, 28}, {14, 27, 26}}, crash_report, [[{pid, &lt;0.70.0&gt;}, {registered_name, []}, {error_info, {{badrecord, dict}, [{dict, fold_dict, 3}, {fconf_engine, handle_call, 3}, {gen_server, handle_msg, 6}, {proc_lib, init_p, 5}]}}, {initial_call, {gen, init_it, [gen_server, &lt;0.34.0&gt;, &lt;0.34.0&gt;, fconf_engine, [#Ref&lt;0.0.0.94&gt;, #Fun&lt;sin_parse_handle.parse_config_file.1&gt;], []]}}, {ancestors, [fconf_conf_sup, fconf_sup, &lt;0.31.0&gt;]}, {messages, []}, {links, [&lt;0.34.0&gt;]}, {dictionary, []}, {trap_exit, false}, {status, running}, {heap_size, 17711}, {stack_size, 21}, {reductions, 7529}], []]}&lt;br /&gt;{error_logger, {{2008, 2, 28}, {14, 27, 26}}, supervisor_report, [{supervisor, {local, fconf_conf_sup}}, {errorContext, child_terminated}, {reason, {{badrecord, dict}, [{dict, fold_dict, 3}, {fconf_engine, handle_call, 3}, {gen_server, handle_msg, 6}, {proc_lib, init_p, 5}]}}, {offender, [{pid, &lt;0.70.0&gt;}, {name, fconf_engine}, {mfa, {fconf_engine, start_link, [#Ref&lt;0.0.0.94&gt;, #Fun&lt;sin_parse_handle.parse_config_file.1&gt;]}}, {restart_type, temporary}, {shutdown, 2000}, {child_type, worker}]}]}&lt;br /&gt;{error_logger, {{2008, 2, 28}, {14, 27, 26}}, "unexpected error ~p: ~p~n", [{{{badrecord, dict}, [{dict, fold_dict, 3}, {fconf_engine, handle_call, 3}, {gen_server, handle_msg, 6}, {proc_lib, init_p, 5}]}, {gen_server, call, [&lt;0.70.0&gt;, {parse, "/home/walrus/erlang_1/_build.cfg"}, 5000]}}, [{gen_server, call, 3}, {sin_engine, process_build_config, 3}, {sin_engine, start_run, 3}, {sin_engine, run_engine, 3}, {sin_engine, init, 1}, {gen_server, init_it, 6}, {proc_lib, init_p, 5}]]}&lt;br /&gt;{error_logger, {{2008, 2, 28}, {14, 27, 26}}, "run complete~n", []}&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ошибка была в том что в конфиге (приведен весь конфиг):&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;project : {&lt;br /&gt;  name : voip&lt;br /&gt;  vsn : "1.0"&lt;br /&gt;),&lt;br /&gt;  &lt;br /&gt;  repositories : ["http://repo.elware.org/pub"]&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Вместо &lt;span style="font-weight:bold;"&gt;}&lt;/span&gt; стоит &lt;span style="font-weight:bold;"&gt;)&lt;/span&gt;. Определенно, понимание сообщений sinan-а требует некоторых навыков ....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-6142914768585949656?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/6142914768585949656/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=6142914768585949656' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/6142914768585949656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/6142914768585949656'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/02/erlang-sinan.html' title='Этот удивительный erlang - (sinan)'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7406927564845666646.post-144303924239187861</id><published>2008-02-08T02:31:00.007+10:00</published><updated>2008-02-15T14:29:12.697+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Standalone connection pool</title><content type='html'>В одном из проектов на яве мне  понадобился connection pool, без него соединения с базой получались слишком частые.  После определенного поиска обнаружил DBCP от apache и &lt;a href="http://forum.vingrad.ru/sources/topic-157958.html"&gt;&lt;span style="text-decoration: underline;"&gt;статью на vingrad-e  &lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;DBCP  мне не очень понравился, дело вкуса, конечно, но слишком много зависимостей. Да и тяжеловат он для мелкого проекта. Vingrad-овский connection pool  - делает немного не то что хотелось кэширует statements.. И отсутствует обработка случаев, когда, к примеру база умрет (на время)..&lt;br /&gt;&lt;br /&gt;Критика без конкретных предложений - критиканство. Так что взял и написал как нравится самому. Вот что получилось:&lt;br /&gt;&lt;br /&gt;Итак. Общая идея:&lt;br /&gt;&lt;br /&gt;Программа использует connection pool по шаблону:&lt;br /&gt;&lt;br /&gt;Инициализация:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; ConnectionPool pool = ConnectionPool.getInstance();&lt;br /&gt; pool.setUsername("user1");&lt;br /&gt; pool.setPassword("bebebe");&lt;br /&gt; pool.setPath("jdbc:postgresql://hostname/main");&lt;br /&gt; pool.setClassName("org.postgresql.Driver");&lt;br /&gt; pool.setPoolsize(5); // держать 5 коннекций&lt;br /&gt; if (! pool.init() ) System.exit(100);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Тут все просто, берем экземпляр connectionpool-а (проект небольшой, так что оформим его в виде &lt;span style="font-style: italic;"&gt;singleton&lt;/span&gt;), устанавливаем параметры, и если не удалось инициализировать, то не судьба и программу выполнять...&lt;br /&gt;И дальше, в том месте где используется соединение, что-то вроде:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Connection dbconnection = ConnectionPool.getConnection();&lt;br /&gt;   try {&lt;br /&gt;       ....&lt;br /&gt;   } finaly&lt;br /&gt;   {&lt;br /&gt;       ConnectionPool.releaseConnection(dbconnection);&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Тут, если посмотреть, то connection берется не из экземпляра connection pool, а из статического метода в классе. И таким же образом отдается.  Если у нас connection pool в виде singleton - зачем переливать из пустого в порожнее, брать по очереди connection pool и затем из него connection? Взять экземпляр connection pool я могу и сам в статическом методе. Мелочь, но писать программы проще...&lt;br /&gt;&lt;br /&gt;Как это все реализлвано.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.util.Queue;&lt;br /&gt;import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class ConnectionPool {&lt;br /&gt;&lt;br /&gt;    private static ConnectionPool instance;&lt;br /&gt;&lt;br /&gt;    private ConnectionPool() {&lt;br /&gt;        connections =  new ConcurrentLinkedQueue&lt;connection&gt;();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static ConnectionPool getInstance() {&lt;br /&gt;        if (instance == null) instance = new ConnectionPool();&lt;br /&gt;        return instance;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    public static Connection getConnection() {&lt;br /&gt;        return getInstance().getInstanceConnection();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void releaseConnection(Connection c) {&lt;br /&gt;        getInstance().releaseInstanceConnection(c);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Выделить соединение из пула.&lt;br /&gt;     * логика такая:&lt;br /&gt;     * если не пустой - взять соединение из пула, проверить на валидность&lt;br /&gt;     * и вернуть. невалидные соединения сразу убиваем.&lt;br /&gt;     * если пул пустой - сделать новое соединение и вернуть его. Если не смогли&lt;br /&gt;     * сделать новое соединение (типа DB сервер умер) - просто жалуемся в лог&lt;br /&gt;     * и возвращаем null&lt;br /&gt;     */&lt;br /&gt;&lt;br /&gt;    private Connection getInstanceConnection() {&lt;br /&gt;        if (! alreadyInitialized){&lt;br /&gt;            log.severe("improper using of db pool (getConnection without init)");&lt;br /&gt;            return null;&lt;br /&gt;        };&lt;br /&gt;        Connection currentConnection;&lt;br /&gt;        do {&lt;br /&gt;                currentConnection = connections.poll();&lt;br /&gt;                if (currentConnection == null) break; //пустой пул&lt;br /&gt;                // если дохлое соединение - не будем его использовать&lt;br /&gt;                if (! validConnection(currentConnection)) {&lt;br /&gt;                    currentConnection = null;&lt;br /&gt;                }&lt;br /&gt;        } while (currentConnection == null);&lt;br /&gt;&lt;br /&gt;        try{&lt;br /&gt;            if (connections.size() == 0) {&lt;br /&gt;                log.info("DB Pool depleted, add new connection");&lt;br /&gt;                connections.add(java.sql.DriverManager&lt;br /&gt;                        .getConnection(path, userName,password));&lt;br /&gt;                currentConnection = connections.poll();&lt;br /&gt;                if (! validConnection(currentConnection)) {&lt;br /&gt;                    // не судьба. Сдаемся&lt;br /&gt;                    throw new Exception("new connection also is not valid");&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        } catch (Exception ie) {&lt;br /&gt;            log.severe("cannot provide sql connection:"+ie);&lt;br /&gt;            return null;&lt;br /&gt;        };&lt;br /&gt;        return currentConnection;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void releaseInstanceConnection(Connection c) {&lt;br /&gt;        if (! alreadyInitialized){&lt;br /&gt;            log.severe("improper using of db pool (releseConnection without init)");&lt;br /&gt;            return;&lt;br /&gt;        };&lt;br /&gt;        if (getCurrentSize() &gt;= getMaxPoolSize()) {&lt;br /&gt;            try { c.close(); } catch (Exception e) {};&lt;br /&gt;        } else if (! validConnection(c) ) {&lt;br /&gt;                // Не будем возвращать в пул дохлое соединение&lt;br /&gt;        } else {&lt;br /&gt;            connections.offer(c);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private int maxPoolSize = 5;&lt;br /&gt;&lt;br /&gt;    public int getMaxPoolSize() {&lt;br /&gt;        return maxPoolSize;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setPoolsize(int maxPoolSize) {&lt;br /&gt;        if (!alreadyInitialized) {&lt;br /&gt;            this.maxPoolSize = maxPoolSize;&lt;br /&gt;        } else {&lt;br /&gt;            log.severe("setPoolsize after init. ignoring");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getCurrentSize() {&lt;br /&gt;        return connections.size();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private String userName;&lt;br /&gt;&lt;br /&gt;    private String password;&lt;br /&gt;&lt;br /&gt;    private String path;&lt;br /&gt;&lt;br /&gt;    private String className;&lt;br /&gt;&lt;br /&gt;    public String getUserName() {&lt;br /&gt;        return userName;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setUsername(String userName) {&lt;br /&gt;        if (!alreadyInitialized) {&lt;br /&gt;            this.userName = userName;&lt;br /&gt;        } else {&lt;br /&gt;            log.severe("setUserName after init. ignoring");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getPassword() {&lt;br /&gt;        return password;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setPassword(String password) {&lt;br /&gt;        if (!alreadyInitialized) {&lt;br /&gt;            this.password = password;&lt;br /&gt;        } else {&lt;br /&gt;            log.severe("setPassword after init. ignoring");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getPath() {&lt;br /&gt;        return path;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setPath(String path) {&lt;br /&gt;        if (!alreadyInitialized) {&lt;br /&gt;            this.path = path;&lt;br /&gt;        } else {&lt;br /&gt;            log.severe("Path after init. ignoring");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getClassName() {&lt;br /&gt;        return className;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setClassName(String className) {&lt;br /&gt;        if (!alreadyInitialized) {&lt;br /&gt;            this.className = className;&lt;br /&gt;        } else {&lt;br /&gt;            log.severe("setClassName after init. ignoring");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * init - Инициализация пула сообщений&lt;br /&gt;     * @return boolean - успешно ли инициализирован пул (true - все хорошо)&lt;br /&gt;     */&lt;br /&gt;&lt;br /&gt;    public synchronized boolean init() {&lt;br /&gt;        log.entering("ConnectionPool","init");&lt;br /&gt;        try {&lt;br /&gt;            if (alreadyInitialized) {&lt;br /&gt;                throw new Exception("Double init of db pool");&lt;br /&gt;            }&lt;br /&gt;            Class.forName(this.className);&lt;br /&gt;            for (int i=1; i&lt;=5; i++){&lt;br /&gt;                connections.add(java.sql.DriverManager&lt;br /&gt;                        .getConnection(path, userName,password));&lt;br /&gt;            };&lt;br /&gt;            alreadyInitialized = true;&lt;br /&gt;            log.exiting("ConnectionPool","init");&lt;br /&gt;            return true;&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            log.severe("Cannot init db pool:"+e);&lt;br /&gt;        }&lt;br /&gt;        log.exiting("ConnectionPool","init");&lt;br /&gt;        return false;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static Logger log = Logger.getLogger("dbpool");&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Хранилище для коннекций&lt;br /&gt;     */&lt;br /&gt;&lt;br /&gt;    private ConcurrentLinkedQueue&lt;connection&gt; connections;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * переменная предотвращающая двойную инициализацию DB pool&lt;br /&gt;     */&lt;br /&gt;    private boolean alreadyInitialized = false;&lt;br /&gt;    /**&lt;br /&gt;     * Проверка что соединение до сих пор живо. Если есть проблемы, мы его&lt;br /&gt;     * просто убьем&lt;br /&gt;     *&lt;br /&gt;     *  Проверяем просто делая setAutoCommit. Если никаких exceptions&lt;br /&gt;     *  не последовало, считаем что все в порядке.&lt;br /&gt;     */&lt;br /&gt;&lt;br /&gt;    private boolean validConnection(java.sql.Connection c) {&lt;br /&gt;        try {&lt;br /&gt;            boolean status = c.getAutoCommit();&lt;br /&gt;            c.setAutoCommit(! status);&lt;br /&gt;            c.setAutoCommit(status);&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            try { c.close(); } catch (Exception notImportant) {};&lt;br /&gt;            log.info("Dead sql connection detected");&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Несколько попутных замечаний: Держится 5 соединений (по умолчанию, может быть изменено в setPoolsize() ), если программа просит &lt;span style="font-style: italic;"&gt;больше &lt;/span&gt;соединений, будут устанавливаться новые соединения с базой. Просто они будут закрываться, когда в них пропадет нужда.  Так что poolsize - это сколько соединений будет повторно использоваться.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7406927564845666646-144303924239187861?l=walrus16.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://walrus16.blogspot.com/feeds/144303924239187861/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7406927564845666646&amp;postID=144303924239187861' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/144303924239187861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7406927564845666646/posts/default/144303924239187861'/><link rel='alternate' type='text/html' href='http://walrus16.blogspot.com/2008/02/standalone-connection-pool.html' title='Standalone connection pool'/><author><name>walrus</name><uri>http://www.blogger.com/profile/08887983561015471123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_qBKy8gbHL84/R7TkQceMaFI/AAAAAAAAAcw/_fg5caGs0lw/S220/a_d2ad4a8.jpg'/></author><thr:total>1</thr:total></entry></feed>
