On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение
Pasha
Администратор




Пост N: 1937
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 18.05.11 19:04. Заголовок: Leto DB Server


Добавил функцию:

LETO_GROUPBY(cGroup, cFields, [cFilter], [xScopeTop], [xScopeBottom])

cGroup - имя поля, по которому группируются данные;
cFields - список числовых полей через запятую, которые суммируются. Символ # обозначает к-во записей в группе

Функция возвращает двумерный массив строк.
1-й элемент каждой строки - значение поля cGroup, следующие элементы суммы полей, заданных в cFields, или к-во записей в группе


Спасибо: 0 
Профиль
Ответов - 232 , стр: 1 2 3 4 5 6 7 8 9 10 11 12 All [только новые]


AlexMyr



Пост N: 188
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 31.05.11 13:53. Заголовок: alx_on пишет: AlexM..


alx_on пишет:

 цитата:
AlexMyr
Странно...
Перевыложил



Теперь нормально собралось.

Спасибо: 0 
Профиль
AlexMyr



Пост N: 189
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 31.05.11 14:00. Заголовок: Останавливаю сервер,..


Останавливаю сервер, в логе запись
05/31/11 13:57:23: Send STOP to server...

может быть так
05/31/11 13:57:23: Send STOP to server... Done.

а то послали stop а результата в логе нет.

Спасибо: 0 
Профиль
AlexMyr



Пост N: 190
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 31.05.11 14:10. Заголовок: О, увидел, оказывает..


О, увидел, оказывается задержка есть 3 сек.

05/31/11 14:08:22: Send STOP to server...
05/31/11 14:08:25: Server has been closed.

Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 113
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 31.05.11 15:47. Заголовок: Pasha пишет: Версия..


Pasha пишет:

 цитата:
Версия с потоками куда перспективнее, и она просто должна стать основной


Я считаю, что текущая реализация хороша, но до определенных пределов
Какие есть недостатки:
1. Запуск отдельного потока для каждого подключения накладно. Как по времени запуска, так и по ресурсам.
На машинке (win) с 2Гб у меня запустилось около 800 потоков (вроде много, но если клиентов около 100 и каждый создал по 10
соединений, например, это многопоточное клиентское приложение, то к пределу мы уже подошли)
2. Неэффективное использование ядер (больше времени уходит на переключение между ядрами, чем на работу

Хочется переделать на использование ограниченного кол-ва рабочих потоков (в идеале, примерно, равное кол-ву ядер)
Плюс оптимизация сетевой подсистемы (с учетом реализации стека TCP/IP конкретной ОС)

Но! То что поточная реализация точно лучше старой - это факт.

Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 114
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 01.06.11 13:16. Заголовок: Pasha пишет: надо д..


Pasha пишет:

 цитата:
надо добавить функцию leto_areaid()


Я (пока?) не использую UDF
Поэтому добавить то могу, но тестировать не на чем. Да и времени сейчас на это нет, честно говоря.
Исправляю и добавляю только по мере необходимости, как это не грустно

PS leto_ClearAreaEnv() вызывается каждый раз перед завершением операции
Так ли это необходимо?
Вызова leto_SetAreaEnv() перед операцией вполне достаточно
Какие есть мнения?

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1960
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 01.06.11 14:32. Заголовок: Да функцию я и сам д..


Да функцию я и сам добавлю
А leto_ClearAreaEnv() для версии с двумя потоками был просто необходим, так как рабочая область таблицы для всех пользователей была общая, и ее обязательно надо было сбрасывать
Для mt-версии наверное это и не надо.

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1962
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.06.11 09:56. Заголовок: Странно, функция let..


Странно, функция leto_areaid() и не понадобилась

Сделал udf-функцию для каскадного обновления (вечером выложу):

/* 
* UDF_UpdCascade - cascade update key fields in main and relation table
* Parameters:
* nRecNo - record number in the main table
* cKeyField - field name in the main table (primary key)
* xKeyNew - new value of key field
* cClientAlias - client alias of the relation table
* cKeyField2 - field name in the relation table (foreign key)
* xOrder - order name or order number in the relation table
*
* This function return array of record buffer in two tables
* Call from client:
*
* aRecBuf := Leto_Udf("UDF_UpdCascade", ... )
* (table1)->( leto_ParseRec( aRecBuf[1] ) )
* (table2)->( leto_ParseRec( aRecBuf[2] ) )
*/
FUNCTION UDF_UpdCascade( nUserStru, nRecNo, cKeyField, xKeyNew, cClientAlias, cKeyField2, xOrder )
LOCAL xKeyOld, cLetoAlias, cArea := Alias()
LOCAL nPos := FieldPos( cKeyField ), nPos2

dbGoto( nRecNo )
xKeyOld := FieldGet( nPos )
IF xKeyOld != xKeyNew .and. leto_RecLock( nUserStru, nRecNo )
FieldPut( nPos, xKeyNew )
leto_RecUnlock( nUserStru, nRecNo )

cLetoAlias := leto_Alias( nUserStru, cClientAlias )
dbSelectArea( cLetoAlias )
IF Empty( cKeyField2 )
cKeyField2 := cKeyField
ENDIF
nPos2 := FieldPos( cKeyField2 )
IF ! Empty( xOrder )
ordSetFocus( xOrder )
ENDIF
WHILE dbSeek( xKeyOld )
IF leto_RecLock( nUserStru, RecNo() )
FieldPut( nPos2, xKeyNew )
leto_RecUnlock( nUserStru, RecNo() )
ELSE
EXIT
ENDIF
ENDDO
dbSeek( xKeyNew )

dbSelectArea( cArea )

ENDIF
RETURN { leto_rec( nUserStru ), (cLetoAlias)->(leto_rec( nUserStru)) }


И оказалось, что при выборе текущей раб.области pUStru->pCurAStru сам присваивается, только мне непонятно как


Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 115
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 02.06.11 10:32. Заголовок: Pasha пишет: pUStru..


Pasha пишет:

 цитата:
pUStru->pCurAStru сам присваивается, только мне непонятно как


leto_Alias() - вызывает leto_SelectArea(), там все делается

 цитата:
IF ! Empty( xOrder )
ordSetFocus( xOrder )
ENDIF
WHILE dbSeek( xKeyOld )


Вот здесь я был бы осторожнее, т.к. не факт, что от другого UDF не остались установленные фильтры и скопы
Лучше все сбрасывать перед операциями поиска и прохода по записям


Кстати, недостатки текущей реализации UDF:
1 неудобно каждый раз вручную обновлять файл UDF на сервере
2 требуется рестарт сервера
3 непонятно какая именно версия UDF на сервере

Как такая идея работы с UDF:
1. Написать функцию отдачи версии UDF-файла (или каждая UDF-функция должна уметь вернуть свою версию)
2. Написать функцию обновления версии UDF-файла (соответственно сервер должен уметь перечитать его)
3. удаление UDF-файла

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1963
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.06.11 11:09. Заголовок: По поводу areaid - н..


По поводу areaid - не все так просто. leto_rec использует текущий алиас - pArea, и текущую pUStru->pCurAStru.
А они в UDF_UpdCascade оказываются разные: AREASTRU для обоих вызовов одинаковая.
Так что запрос areaid и ее установка через leto_selectarea() все-таки нужна. Может лучше передавать ее параметром (необязательным) в leto_rec, leto_reclock, leto_recunlock ?

Насчет фильтров - ведь каждая udf-функция вызывается по отдельному запросу с клиента, и после ее работы отрабатывается FreeArea, которая должна все сбросить. Это получается как для leto_ClearAreaEnv(). Установленный фильтр надо проверять разве что если одна UDF-функция вызывается из другой.

Reload/Unload для UDF сделаю, по аналогии с отработки команды stop - LETO_STOPSERVER. Там надо вызывать hb_hrbunload/hb_hrbload

По поводу версии UDF. Может в hrb-модуль добавить функцию UDF_Version, которая возвращала бы строку версии, и с клиента ее можно опросить обычным вызовом leto_Udf('UDF_Version') ?
Кстати, можно еще определить функию UDF_INIT, которую сервер вызывал бы при загрузке UDF (если она есть в модуле, конечно)

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1964
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 02.06.11 11:14. Заголовок: alx_on пишет: 2. На..


alx_on пишет:

 цитата:
2. Написать функцию обновления версии UDF-файла (соответственно сервер должен уметь перечитать его)



А, это запросом с клиента обновлять UDF ? Можно и так, добавить команду, и с ней передавать hrb-файл, который сервер бы загружал

Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 116
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 02.06.11 11:39. Заголовок: Pasha пишет: leto_r..


Pasha пишет:

 цитата:
leto_rec использует текущий алиас - pArea, и текущую pUStru->pCurAStru.


Вот именно. Т.е. использование UDF требует аккуратности (мало ли где еще неявно что то используется)
Например можно вместо:

dbSelectArea( cArea )
ENDIF
RETURN { leto_rec( nUserStru ), (cLetoAlias)->(leto_rec( nUserStru)) }

написать так:
LOCAL aRet := {,}
.......
.......
aRet[2] := leto_rec( nUserStru )
dbSelectArea( cArea )
aRet[1] := leto_rec( nUserStru )
ENDIF
RETURN aRet

Плюс правильно отработать условие "IF xKeyOld != xKeyNew .and. leto_RecLock( nUserStru, nRecNo )" -
(пустой массив)
Сейчас просто будет падать (cLetoAlias == NIL)


 цитата:
после ее работы отрабатывается FreeArea, которая должна все сбросить. Это получается как для leto_ClearAreaEnv()


leto_FreeArea() не сбрасывает ничего (явно, по крайней мере), она только передает таблицу в общее пользование потокам

 цитата:
Может в hrb-модуль добавить функцию UDF_Version


Как вариант, да согласен

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1970
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.06.11 21:23. Заголовок: Обновление обьекта t..


Обновление обьекта tbrowse происходит так:
go top
перемещение в начало, вывод строки
skip 1
вывод строки
skip 1
...
skip -n
возврат на первую строку

Применительно к letodb это будет выглядеть так:
go top
выборка записи с сервера
skip 1
n записей со 2-й выбираются с сеовера
skip 1
запись берется из буфера без обращения к серверу
...
skip -n
записи с n до 2 беоутся из буфера, а 1-я вновь запрашивается с сервера

Чтобы избежать лишнего запроса, я сделал буферизацию записи, которая получена при gotop/gobottom/goto/seek
Таким образом, теперь при стабилизации tbrowse к letodb клиент посылает всего 2 запроса:
gotop
skip

Конечно, при этом буфер для skip должен быть не меньше, чем количество строк в tbrowse
Для этого можно вызвать:
leto_SetSkipBuffer( oB:rowCount() )

Заодно добавил оптимизацию dbGoto: если запрашиваемая запись есть в буфере, она не считывается с сервера.


Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1971
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 10.06.11 16:15. Заголовок: Помимо буферизации s..


Помимо буферизации skip хочется добавить в letodb буферизацию seek.
Предполагается делать буферизацию исключительно на клиенте, сервер при этом задействован не будет. После выполнения seek, если это не поиск по частичному ключу и не поиск последнего ключа, результат поиска добавляется в буфер.
Время актуальности буфера - BUFF_REFRESH_TIME (1 сек)
Если ключ для seek найден в буфере, то запрос к серверу не выполняется, а запись берется из буфера. Буфер хранится в LETOTAGINFO. При записи в таблице буфер очищается.
Использование seek buffer будет целесообразно для небольших справочников, для которых постоянно вызывается seek, а также при задании set relation.
Для р/о, в которой задано использование seek buffer, количество мелких запросов к серверу (seek) может быть сокращено в десятки раз.
В Ads, насколько я знаю, подобного механизма нет.
Какие будут мысли, идеи, сомнения ? Стоит ли использовать такой механизм по умолчанию для всех р/о, или только для заданных ? Как ограничивать размер такого буфера ?


Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1972
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 12.06.11 17:52. Заголовок: Добавил поддержку se..


Добавил поддержку seek-буфера. По умолчанию он выключен. Чтобы его включить, надо вызвать leto_setseekbuffer( nRecs ) для соответствующего индекса. Параметр - максимальное количество записей в буфере.
Использование такого буфера для таблиц, в которых используется преимущественно индексный метод доступа, позволяет существенно сократить количество запросов к серверу. В моем тесте для не очень большой выборки число "попаданий" в буфер достигало тысяч.

Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 117
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 14.06.11 09:24. Заголовок: Pasha пишет: Добави..


Pasha пишет:

 цитата:
Добавил поддержку seek-буфера


1. поменялся фильтр (выполняемый на сервере)
2. поменялся scope
3. поменяли видимость удаленных записей
в этих случаях буфер поиска необходимо сбрасывать (или не учитывать)

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1973
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 14.06.11 12:57. Заголовок: alx_on пишет: 1. по..


alx_on пишет:

 цитата:
1. поменялся фильтр (выполняемый на сервере)
2. поменялся scope
3. поменяли видимость удаленных записей
в этих случаях буфер поиска необходимо сбрасывать (или не учитывать)



Сделаю. Заодно и для skipbuf, там тоже этого нет. set deleted перехватывать не получится, так что прийдется добавить этот флаг в буфер, и проверять его при использовании буфера. Сделаю отдельную структуру для буфера. Зодно хочется добавить статистику запросов для р.о на клиенте - количество запросов, количество попаданий в буфер

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1975
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 14.06.11 19:10. Заголовок: Сделал Вызов leto_Se..


Сделал
Вызов leto_SetSkipBuffer() и leto_SetSeekBuffer теперь возвращает статистику использования буфера для текущей р/о или индекса: сколько раз записи выбирались из буфера, а не запрашивались с сервера.

Спасибо: 0 
Профиль
Pasha
Администратор




Пост N: 1978
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 04.07.11 18:02. Заголовок: Собрал letodb под wi..


Собрал letodb под win64 с помощью mingw64. Работает.

Спасибо: 0 
Профиль
alx_on
постоянный участник


Пост N: 118
Зарегистрирован: 07.07.09
ссылка на сообщение  Отправлено: 04.07.11 23:30. Заголовок: Pasha пишет: Собрал..


Pasha пишет:

 цитата:
Собрал letodb под win64 с помощью mingw64. Работает


у меня и раньше работало (правда MAC OS X 64-бита и gcc)
есть какая то разница между mingw64 и gcc?

Спасибо: 0 
Профиль
Sergey Spirin
постоянный участник


Пост N: 520
Зарегистрирован: 25.12.07
ссылка на сообщение  Отправлено: 05.07.11 01:11. Заголовок: Pasha пишет: Собрал..


Pasha пишет:

 цитата:
Собрал letodb под win64 с помощью mingw64. Работает.




Паш, и чего, ни разу приведения pointer к int по всему коду не было? Абалдеть!

P.S. Не советую тешиться

Спасибо: 0 
Профиль
Ответов - 232 , стр: 1 2 3 4 5 6 7 8 9 10 11 12 All [только новые]
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 17
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет