24 июл. 2010 г.
Pascal forever
Apple has opened sources of their MacPaint and QuickDraw applications. Naturally, it had been done in Pascal with some assembler insertions. The sources are available from this Computer History Museum page.
22 июл. 2010 г.
14 июл. 2010 г.
Посадили дерево
В наших интервальных деревьях всю жизнь была ошибка. Интервалы перекрывались в следующем случае: есть два элемента A и B, имеющих одного родителя. A расположен левее B. Пусть B имеет два дочерних элемента C и D, примыкающих друг к другу, причем C расположен левее D и интервал C уже D. Тогда, при перемещении D в A, в процессе расширения интервалов вправо, интервал C будет перекрываться с A и B.
Labels:
SQL
KISS
Компоненты IBX имеют жутко навороченный механизм трассировки SQL команд: монитор, хук к нему, интерфейс к хуку и две нити, для чтения и записи лога. Вероятно была попытка сделать монитор, который бы минимально тормозил текущие операции (отсюда раздельная запись и чтение в обособленных нитях), и позволял бы менять движки как перчатки (отсюда хук и интерфейс, кстати достаточно бесполезный, так как объявляется в самом модуле монитора и завязан на объявления прочих объектов из этого модуля).
Некоторое время в Гедымине присутствовал механизм трассировки запросов, основанный на стандартном мониторе. Позже он был выкинут, так как отловить все ошибки во взаимодействии читающих и пишущих нитей не удалось и монитор хоть и изредка, но кидал AV.
Новый механизм был создан за два дня, буквально следуя принципу KISS — Keep It Simple Stupid. В его основе объект истории SQL запросов (TgdcSQLHistory) и копия интерфейса борландовского SQL монитора. Везде, где надо, через условную компиляцию мы подменили обращение к модулю IBSQLMonitor.pas на IBSQLMonitor_Gedemin.pas.
Лог трассировки находится в SQL редакторе на соответствующей вкладке. Там же — чек-бокс для включения/выключения и кнопка очистки. Трассировку можно также активировать параметром командной строки /trace.
Некоторое время в Гедымине присутствовал механизм трассировки запросов, основанный на стандартном мониторе. Позже он был выкинут, так как отловить все ошибки во взаимодействии читающих и пишущих нитей не удалось и монитор хоть и изредка, но кидал AV.
Новый механизм был создан за два дня, буквально следуя принципу KISS — Keep It Simple Stupid. В его основе объект истории SQL запросов (TgdcSQLHistory) и копия интерфейса борландовского SQL монитора. Везде, где надо, через условную компиляцию мы подменили обращение к модулю IBSQLMonitor.pas на IBSQLMonitor_Gedemin.pas.
Лог трассировки находится в SQL редакторе на соответствующей вкладке. Там же — чек-бокс для включения/выключения и кнопка очистки. Трассировку можно также активировать параметром командной строки /trace.
Labels:
SQL
7 июл. 2010 г.
Жорсткая праўда беларускага інтэрнэту
Адзін з найбуйнейшых айчынных правайдэраў, Деловая Сеть, мае канал у 750 Мбіт/с на... 6 000 кліентаў. Які тут анлім. Калі ўсе разам пойдуць у сеціва атрымаецца па 125 Кбіт/с на брата. У іншых "незалежных" правайдэраў каналы яшчэ вузейшыя. І ўсе разам яны ўпіраюцца ў ліміт знешнега каналу нашага горача любімага манапаліста Белтэлекома, які ў заходнім накірунку складае менш за 16 Гбіт/c. Калі падзяліць на колькасць карыстальнікаў сеціва (4 млн), дык кожнаму дастанецца ажно па 4 (Чатыры!) Кбіт/с.
Labels:
інтэрнэт
1 июл. 2010 г.
Дело было не в бобине
Десять лет мы наблюдали редкие-редкие нарушения вложенности по LB, RB на базах наших клиентов. До сих пор считалось, что проблема в незащищенности полей со значениями границ от случайной записи. Однако, тесты выявляют нарушение вложенности и в стерильных лабораторных условиях, когда поля LB, RB уж точно никем сторонним не заполняются.
Либо сбой в алгоритме (тронуться можно, если пытаться проследить его работу в уме), либо (что гораздо хуже) сбой в сервере при многократных рекурсивных вызовах процедур и триггеров.
Будем искать.
Либо сбой в алгоритме (тронуться можно, если пытаться проследить его работу в уме), либо (что гораздо хуже) сбой в сервере при многократных рекурсивных вызовах процедур и триггеров.
Будем искать.
Первый самостоятельно написанный EXECUTE BLOCK
EXECUTE BLOCK (id INTEGER = :id)
RETURNS (companykey INTEGER)
AS
DECLARE VARIABLE ct INTEGER;
BEGIN
ct = 4;
companykey = 0;
WHILE (:ct = 4 AND NOT :companykey IS NULL) DO
BEGIN
companykey = NULL;
SELECT id, parent, contacttype
FROM gd_contact
WHERE id = :id
INTO :companykey, :id, :ct;
END
SUSPEND;
END
Возвращает организацию для заданного подразделения. Хотя, конечно, все можно было сделать простым запросом:SELECT c.id FROM gd_contact c JOIN gd_contact d ON c.lb < d.lb AND c.rb >= d.rb WHERE d.id = :ID AND c.contacttype = 3
Labels:
SQL
16 июн. 2010 г.
Неявные JOIN-ы
Такие вот запросы практиковались в раннем Гедымине:
SELECT
isg2.RDB$FIELD_NAME FirstField
, rc2.RDB$RELATION_NAME NetTable
, isg4.RDB$FIELD_NAME SecondField
, rc5.RDB$RELATION_NAME TargetTable
, isg6.RDB$FIELD_NAME TargetField
, (SELECT 1
FROM RDB$DATABASE
WHERE
EXISTS(SELECT *
FROM RDB$RELATION_FIELDS rf
WHERE rc5.RDB$RELATION_NAME = rf.RDB$RELATION_NAME
AND rf.RDB$FIELD_NAME = 'LB')
AND EXISTS(SELECT *
FROM RDB$RELATION_FIELDS rf
WHERE rc5.RDB$RELATION_NAME = rf.RDB$RELATION_NAME
AND rf.RDB$FIELD_NAME = 'RB')) IsTree
FROM
RDB$INDEX_SEGMENTS isg1
, RDB$RELATION_CONSTRAINTS rc1
, RDB$REF_CONSTRAINTS rfc1
, RDB$RELATION_CONSTRAINTS rc2
, RDB$INDEX_SEGMENTS isg2
, RDB$INDEX_SEGMENTS isg3
, RDB$RELATION_CONSTRAINTS rc3
, RDB$INDEX_SEGMENTS isg4
, RDB$INDEX_SEGMENTS isg5
, RDB$RELATION_CONSTRAINTS rc4
, RDB$REF_CONSTRAINTS rfc2
, RDB$RELATION_CONSTRAINTS rc5
, RDB$INDEX_SEGMENTS isg6
WHERE
rc1.RDB$RELATION_NAME = :tablename
AND rc1.RDB$INDEX_NAME = isg1.RDB$INDEX_NAME
AND rc1.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
AND rfc1.RDB$CONSTRAINT_NAME = rc2.RDB$CONSTRAINT_NAME
AND rfc1.RDB$CONST_NAME_UQ = rc1.RDB$CONSTRAINT_NAME
AND rc2.RDB$INDEX_NAME = isg2.RDB$INDEX_NAME
AND rc1.RDB$RELATION_NAME <> rc2.RDB$RELATION_NAME
AND isg3.RDB$FIELD_NAME = isg2.RDB$FIELD_NAME
AND rc3.RDB$RELATION_NAME = rc2.RDB$RELATION_NAME
AND rc3.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
AND rc3.RDB$INDEX_NAME = isg3.RDB$INDEX_NAME
AND isg4.RDB$INDEX_NAME = isg3.RDB$INDEX_NAME
AND isg2.RDB$FIELD_NAME <> isg4.RDB$FIELD_NAME
AND isg5.RDB$FIELD_NAME = isg4.RDB$FIELD_NAME
AND rc4.RDB$INDEX_NAME = isg5.RDB$INDEX_NAME
AND rc4.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
AND rc4.RDB$RELATION_NAME = rc2.RDB$RELATION_NAME
AND rfc2.RDB$CONSTRAINT_NAME = rc4.RDB$CONSTRAINT_NAME
AND rfc2.RDB$CONST_NAME_UQ = rc5.RDB$CONSTRAINT_NAME
AND rc5.RDB$INDEX_NAME = isg6.RDB$INDEX_NAME
Возвращает список атрибутов типа множество для заданной таблицы.
Labels:
SQL
8 июн. 2010 г.
Предварительные результаты по внешним ключам
Для тестирования была использована действующая база ВМК размером 29,912,520 Кб. Были конвертированы все внешние целочисленные ключи, удовлетворяющие следующим условиям:
После этого мы проверили скорость выполнения запроса на изменение данных на таблице AC_ENTRY, которая содержит более 9 млн. записей. Текст команды приводится ниже:
- В таблице более 10 000 записей.
- Уникальных значений в ключе не более 200.
- Ключ не ссылается на эту же таблицу.
После этого мы проверили скорость выполнения запроса на изменение данных на таблице AC_ENTRY, которая содержит более 9 млн. записей. Текст команды приводится ниже:
update ac_entry set companykey = 147048034, usr$gs_department = 147048036, currkey = 147021255, usr$gs_service = 147089059Четыре изменяемых поля — это сконвертированные ссылки. Проверка целостности осуществляется с помощью триггера следующего вида:
CREATE TRIGGER xxx ON AC_ENTRY
AFTER UPDATE
POSITION 32000
BEGIN
IF (NEW.USR$GS_SERVICE IS NOT DISTINCT FROM
OLD.USR$GS_SERVICE) THEN EXIT;
IF (NEW.USR$GS_SERVICE IS NOT NULL) THEN
BEGIN
IF (NOT EXISTS (SELECT id FROM gd_ref_constraint_data
WHERE value_data = NEW.USR$GS_SERVICE
AND constraintkey = 388626603)) THEN
BEGIN
IF (NOT EXISTS (SELECT ID FROM GD_GOOD
WHERE ID = NEW.USR$GS_SERVICE)) THEN
EXCEPTION gd_e_fkmanager 'message';
RDB$SET_CONTEXT('USER_TRANSACTION',
'REF_CONSTRAINT_UNLOCK', '1');
INSERT INTO gd_ref_constraint_data
(constraintkey, value_data, value_count)
VALUES
(388626603, NEW.USR$GS_SERVICE, 1);
RDB$SET_CONTEXT('USER_TRANSACTION',
'REF_CONSTRAINT_UNLOCK', '0');
END
END
END
Время выполнения запроса:- На новой базе — 1945 сек.
- На старой базе — 2642 сек.
7 июн. 2010 г.
Тестирование подсистемы отчетов
При тестировании изменений в подсистеме отчетов мы постарались исключить фактор пропускной способности сети и производительности дисковой подсистемы. Использовался встроенный сервер Firebird 2.5. Данные генерировались с помощью хранимых процедур. Пример такой процедуры можно видеть ниже:
Таблица с результатами находится здесь.
Вывод:
CREATE PROCEDURE tst_p_gen_str_data (i INTEGER)
RETURNS (id INTEGER,
s1 VARCHAR(60),
s2 VARCHAR(60),
s3 VARCHAR(60),
s4 VARCHAR(60))
AS
BEGIN
s1 = 'ABC dfg';
s2 = '123 567 9874 10';
s3 = 'qwertyuiop asdfghjl; xzcvnbvmn,m.';
s4 = '';
WHILE (i > 0) DO
BEGIN
id = :i;
i = :i - 1;
END
END
Тестировались следующие отчеты:- Отчет по одному набору данных со строковыми полями.
- Отчет по одному набору данных с целочисленными полями.
- Отчет по двум наборам данных, связанных связью мастер-дитэйл. Наборы данных со строковыми полями.
Таблица с результатами находится здесь.
Вывод:
- для отчетов мастер-дитэйл на двух датасетах разница незначительна — увеличение потребления памяти на 2% и ускорение на 6%.
- для отчетов, основанных на одном наборе данных, достигается существенное ускорение в 35% при умеренном росте потребления памяти — от 9 до 16%.
Labels:
отчеты,
тестирование
1 июн. 2010 г.
Проблема 1 июня 2010 года
В нашей истории случались забавные и не очень случаи, когда программа начинала работать неверно с определенной даты. Как выяснилось, мы не одиноки и проколы случаются с куда более крупными компаниями. Так с 1 июня 2010 г. перестал запускаться Corel X4. На официальном форуме техподдержки дается решение проблемы: "set back the clock 1-2 months".
Labels:
цікава
Отстоим свой интернет!
Создан сайт ukaz60.net для сбора подписей за отмену Указа 60, фактически уничтожающего свободный интернет в Беларуси. Просьба всем небезразличным поддержать!
Labels:
интернет
Подписаться на:
Сообщения (Atom)
