Форум » LetoDB, HbNetio. » Leto DB Server (продолжение 9) » Ответить

Leto DB Server (продолжение 9)

Dima: Продолжаем тут

Ответов - 301, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 All

Pasha: Srdjan пишет: Есть ли это программный код: #xtranslate Sx_SetScope(<a>,<b>) => ordScope( <a>,<b> ) #xtranslate Sx_SetScope(<a>,) => ordScope( <a>, ) #xtranslate Sx_ClrScope() => (ordScope(0,),ordScope(1,)) n := Sifre->( LastRec() ) a1 := Array( n ) a2 := Array( n ) aFill( a1, 0 ) aFill( a2, 0 ) RobMat->( OrdSetFocus( 'Datum' ) ) RobMat->( Sx_SetScope( 0, dOd ), Sx_SetScope( 1, dDo ), dbGoTop() ) WHILE !RobMat->( EOF() ) IF LEFT(RobMat->Dokument,1)=='H' .AND. RobMat->Sifra<>0 .AND. RobMat->Radnik==nVoz .AND. RobMat->Magacin == 1 a2[ RobMat->Sifra ] += RobMat->Ulaz a1[ RobMat->Sifra ] += RobMat->Izlaz END RobMat->( dbSkip() ) END с следующий код программы: RobMat->( OrdSetFocus( 'Datum' ) ) a:=RobMat->( LETO_GROUPBY("Sifra", "Ulaz, Izlaz", "LEFT(Dokument,1)=='H' .AND. Sifra<>0 .AND. Radnik=="+ALLTRIM(STR(nVoz,5,0))+" .AND. Magacin == 1", dOd, dDo) ) Результат leto_GroupBy будет немного другой: не 2 одномерных массива a1 и a2, а один двумерный массив вида: { {Sifra1, Ulaz1, Izlaz1}, {Sifra2, Ulaz2, Izlaz2}, ...}

nbatocanin: Здравствуйте! Какие факторы определяют скорость Letodb? Я пробовал различные комбинации (Windows 7, XP, Windows Server) - измерил время некоторых обработки. Обычно Letodb работает в 4-5 раз быстрее, чем обычный доступ к файловой-сервере (LAN). Но Letodb иногда до 2-3 раз становится медленнее. Я использую NTX RDD. Есть ли CDX быстрее, чем NTX? Спасибо, Ненад

Srdjan: Спасибо Паша, Я вас понимаю. Результат leto_GroupBy будет немного другой: не 2 одномерных массива a1 и a2, а один двумерный массив вида: { {Sifra1, Ulaz1, Izlaz1}, {Sifra2, Ulaz2, Izlaz2}, ... Вместо двух строк, то функция возвращает матрицу. Я проверил, вместо 10 минут, результат получается за 30 секунд на клиентском компьютере.


Pasha: Здравствуйте! Какие факторы определяют скорость Letodb? Я пробовал различные комбинации (Windows 7, XP, Windows Server) - измерил время некоторых обработки. Обычно Letodb работает в 4-5 раз быстрее, чем обычный доступ к файловой-сервере (LAN). Но Letodb иногда до 2-3 раз становится медленнее. Я использую NTX RDD. Есть ли CDX быстрее, чем NTX? Спасибо, Ненад Вопрос многоплановый. Основной фактор, определяющий производительность - это открытие БД на сервере в монопольном режиме, в отличие от CDX/NTX. Поэтому режим Share_Tables рекомендуеся использовать только на этапе отладки. Другой фактор - буферизация операций skip. Этим можно управлять: с помошью функции leto_SetSkipBuffer можно задать размер skip-буфера, размер которого по умолчанию равен 10 записям. Можно также использовать seek буфер (по умолчанию он выключен). Для увеличения производительности рекомендуется использовать scope и серверные фильтры. LetoDB конечно лучше сравнивать не с dbfcdx/dbfntx, а с Ads. Узкие места letodb - это relations и обновление данных. Туь он уступает ads Если задействовать функции leto_sum, leto_groupby, и udf-функции (это полноценное программирование на сервере, примерный аналог stored proc), можно добиться намного более значительного результата.

nbatocanin: Я попробую этих параметров, спасибо большое! Ненад

nbatocanin: Я сделал несколько тестов различных RDD (LAN - прямой доступ к серверу, LetoDB, HBNetIO, ADS). Результаты и тестовая программа: https://www.dropbox.com/s/u3g9cpa4cpuiwsl/test3.xls https://www.dropbox.com/s/g4uvhu1f6wwjiqy/TEST3.TXT Я заметил, что на некоторых машинах результаты были очень плохые для LetoDB. Тест я работал на нескольких серверах: Win Server 2003 и Server 2008 (новый и лучший компьютер.). Тест состоит из простых операций (APPEND, SKIP, SEEK, REPLACE) . Результаты очень интересны:  - XP работать быстрее, чем Win7, даже когда Win 7 компьютер является более мощным (например, строка 4 и 9). - прямой доступ к серверу иногда намного быстрее, чем клиент-сервер! Например, линия 14/19. Интересно, что результаты ADS/Leto такие же, независимо от того что сервер работает быстрее. - APPEND: Leto/ADS работает медленнее, чем LAN/HBNetIO.  - Leto/ADS/HBNetIO дают сходные результаты во всех случаях , независимо от изменений окружающей среды. Очевидно, что прямой подход LAN использует некоторый тип кэша, что не влияет на Leto/ADS/HBNetIO. Я попробовал тоже параметры, которы дал Паша, но я не заметил разницы, за исключением Leto_SetFastAppend. С уважением, Ненад (Извините за ошибки)

Srdjan: Почему я вижу эту ошибку при использовании команды Use (cPath+"Users") New ALIAS USERS -------------------- Internal Error Handling Information --------------------- Subsystem Call ....: LETO System Code .......: 1021 Default Status ....: .F. Description .......: Data type error Operation .........: Arguments .........: Involved File .....: //127.0.0.1:2812\hz\Users Dos Error Code ....: 0 Trace Through: ---------------- DBUSEAREA : 0 in Module: users.dbf

Pasha: Почему я вижу эту ошибку при использовании команды Use Что-то users.dbf не скачивается. Поставьте еще в letodb.ini параметр Debug=10 Перезапустите службу letodb, и посмотрите, какие команды появятся в letodb.log. Так будет понятнее ситуация.

dimao: Как собрать LETO ночной сборкой харбора? Что-то ничего не получается. [pre2]C:\hb-old\letodb>..\bin\hbmk2 -info -trace rddleto.hbp letodb.hbp hbmk2: Autodetected platform: win hbmk2: Autodetected C compiler: mingw hbmk2: Using Harbour: C:\hb-old\bin C:\hb-old\include C:\hb-old\lib\win\mingw C:\hb-old\bin C:\hb-old\contrib C:\hb-old\addons hbmk2: Using C compiler: c:\hb-old\comp\mingw\bin\gcc.exe hbmk2: Compiling... hbmk2: 'cd' to: lib\.hbmk\win\mingw hbmk2: C/C++ compiler command: gcc.exe -c -O3 -march=i586 -mtune=pentiumpro -fomit-frame-pointer -W -Wall -pipe -I"C:/hb-old/include" -I../../../../include ../../../../source/common/net.c ../../../../source/common/net.c: In function 'leto_NetName': ../../../../source/common/net.c:144:18: error: 'MAX_COMPUTERNAME_LENGTH' undeclared (first use in this function) ../../../../source/common/net.c:144:18: note: each undeclared identifier is reported only once for each function it appears in ../../../../source/common/net.c:148:4: warning: implicit declaration of function 'GetComputerName' [-Wimplicit-function-declar ation] ../../../../source/common/net.c:145:9: warning: unused variable 'szValue' [-Wunused-variable] hbmk2[rddleto]: Error: Running C/C++ compiler. 1 gcc.exe -c -O3 -march=i586 -mtune=pentiumpro -fomit-frame-pointer -W -Wall -pipe -I"C:/hb-old/include" -I../../../../include ../../../../source/common/net.c hbmk2: 'cd' back.[/pre2] PPS:и вот еще, когда описал явно константу #define MAX_COMPUTERNAME_LENGTH 15 получаю ошибки вида: ../../../../source/server/letofunc.c:339:13: error: expected '(' before 'ISBYREF' ../../../../source/server/letofunc.c:374:10: error: expected '(' before 'ISBYREF' Это в С коде ошибки? или как-то можно это обработать?

nbatocanin: Паша, Можете ли вы исправить эти ошибки, пожалуйста? http://sourceforge.net/apps/phpbb/letodb/viewtopic.php?f=1&t=10 http://sourceforge.net/apps/phpbb/letodb/viewtopic.php?f=1&t=25 С уважением, Ненад

Pasha: dimao пишет Как собрать LETO ночной сборкой харбора? Что-то ничего не получается. source/common/net.c для сборки теперь не нужен. Его надо удалить из скрипта для hbp

Pasha: nbatocanin пишет: Паша, Можете ли вы исправить эти ошибки, пожалуйста? http://sourceforge.net/apps/phpbb/letodb/viewtopic.php?f=1&t=10 http://sourceforge.net/apps/phpbb/letodb/viewtopic.php?f=1&t=25 С уважением, Ненад По второму вопросу - исправил. А по первому - разве не помог патч ? Вопрос еще остался ?

nbatocanin: Я попробовал его, и кажется, что он делает хорошо. Спасибо! Ненад

Pasha: Александр, я обнаружил, что ordBagExt() aka IndexExt() с конца прошлого года стал выдавать результат на верхнем регистре, а раньше выдавал на нижнем. Это сделано намеренно ?

SergKis: Pasha как правильно включить в версию v 1.350.2.199 2014/08/05 работу с AutoIncrement: RddInfo( RDDI_TABLETYPE, DB_DBF_VFP ) ? раньше делал так:[pre2] FUNCTION hs_InitSet() rddSetDefault( "DBFCDX" ) RddInfo( RDDI_TABLETYPE, DB_DBF_VFP ) // New SET AUTOPEN ON SET DELETE OFF RETURN Nil [/pre2]

Pasha: Это и не обязательно. Достаточно просто создать таблицу с полем AUTOINC - "+" для dbCreate

SergKis: Pasha СПАСИБО

SergKis: Pasha начали пробовать LetoDb (v.m. 1.350.2.199 2014/08/05) и кое что поковыряли, может будет полезным 1. letomgmn.c: line 901: char ** pRetValue; она объявлена, но не инициализирована, а в line 927 используется: ((cType=='3')? (char*)hb_parc(3) : szValue), uiFlags, ((bPrev)? pRetValue : NULL) ); а в line 949: free( *pRetValue ); т.е. освободить память, которую не выделяли, что, наверное, не есть хорошо ? 2. несколько сервисов (от имени exe) на pc (с разных каталогов, переименовав letodb.exe в др. имя). leto_win.c изменения помечены // BAA [pre2] #ifdef __WIN_SERVICE__ #include "hbapi.h" #include "hbapiitm.h" #include "hbvm.h" //#include "hbxvm.h" //#include "hbset.h" //#include "hbthread.h" #include "srvleto.h" #define _SERVICE_NAME "LetoDB_Service" #define _SERVICE_DISPLAY_NAME "LetoDB Service" #define _SERVICE_DESCRIPTION "Leto DB Server is a multiplatform database server or a database management system, chiefly intended for client programs, written on Harbour." // BAA static SERVICE_STATUS_HANDLE hServiceHandle = 0; static char ServiceEntryFunc[ HB_SYMBOL_NAME_LEN + 1 ]; // BAA static TCHAR ServiceName[] = _SERVICE_NAME; // BAA static TCHAR ServiceDisplayName[] = _SERVICE_DISPLAY_NAME; // BAA static TCHAR ServiceName[64]; static TCHAR ServiceDisplayName[64]; static TCHAR ServiceDescription[] = _SERVICE_DESCRIPTION; // BAA extern int leto_GlobalExit; static ULONG ulSvcError = 0; void leto_SetServiceStatus( DWORD State ) { SERVICE_STATUS SrvStatus; SrvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; SrvStatus.dwCurrentState = State; SrvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; SrvStatus.dwWin32ExitCode = 0; SrvStatus.dwServiceSpecificExitCode = 0; SrvStatus.dwCheckPoint = 0; SrvStatus.dwWaitHint = 0; if( hServiceHandle ) SetServiceStatus( hServiceHandle, &SrvStatus ); } void WINAPI leto_ServiceControlHandler( DWORD dwCtrlCode ) { DWORD State = SERVICE_RUNNING; switch( dwCtrlCode ) { case SERVICE_CONTROL_STOP: State = SERVICE_STOPPED; leto_GlobalExit = 1; return; // BAA - ??? Probably break; case SERVICE_CONTROL_SHUTDOWN: State = SERVICE_STOPPED; leto_GlobalExit = 1; return; // BAA - ??? Probably break; } leto_SetServiceStatus( State ); } void WINAPI leto_ServiceMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) { HB_SYMBOL_UNUSED( dwArgc ); HB_SYMBOL_UNUSED( lpszArgv ); hServiceHandle = RegisterServiceCtrlHandler( ServiceName, ( LPHANDLER_FUNCTION ) leto_ServiceControlHandler ); if( hServiceHandle != (SERVICE_STATUS_HANDLE) 0 ) { PHB_DYNS pDynSym; leto_SetServiceStatus( SERVICE_RUNNING ); hb_vmThreadInit( NULL ); pDynSym = hb_dynsymFindName( ServiceEntryFunc ); if( pDynSym ) { if( hb_vmRequestReenter() ) { hb_vmPushSymbol( hb_dynsymSymbol( pDynSym ) ); hb_vmPushNil(); hb_vmProc( 0 ); hb_vmRequestRestore(); } } leto_SetServiceStatus( SERVICE_STOPPED ); hb_vmThreadQuit(); } } // BAA - New function static DWORD leto_GetNameService( TCHAR *szBuf) { DWORD sz, i; TCHAR *ptr; sz = GetModuleFileName( NULL, szBuf, MAX_PATH ); if( sz > 0) { // BAA : ServiceName == ExecName without Extendet. ptr = &szBuf[sz]; while( *ptr != 0x5C ) ptr--; // BAA 0x5C == '\' ptr++; i = 0; while( *ptr != '.' ) { ServiceDisplayName[ i ] = *ptr; ServiceName[ i++ ] = *ptr++; } ServiceName[ i ] = 0; ServiceDisplayName[ i++ ] = ' '; strcpy( &ServiceDisplayName[ i ], "Service" ); } return sz; } HB_FUNC( LETO_SERVICESTART ) { DWORD n; TCHAR szPath[ MAX_PATH ]; HB_BOOL bRetVal = HB_FALSE; SERVICE_TABLE_ENTRY lpServiceTable[ 2 ] = { { ServiceName, ( LPSERVICE_MAIN_FUNCTION ) leto_ServiceMainFunction }, { NULL, NULL } }; leto_GetNameService( szPath ); // BAA - define ServiceName, ... // hb_strncpy( ServiceEntryFunc, hb_parcx( 1 ), HB_SIZEOFARRAY( ServiceEntryFunc ) - 1 ); // BAA n = hb_parclen(1); memcpy( ServiceEntryFunc, hb_parc(1), n); ServiceEntryFunc[n] = 0; if( StartServiceCtrlDispatcher( lpServiceTable ) ) bRetVal = HB_TRUE; else ulSvcError = ( ULONG ) GetLastError(); hb_retl( bRetVal ); } HB_FUNC( LETO_SERVICEINSTALL ) { HB_BOOL bRetVal = HB_FALSE; TCHAR szPath[ MAX_PATH ]; SC_HANDLE schSrv, schSCM; DWORD sz; // BAA SERVICE_DESCRIPTION sd; // BAA sz = leto_GetNameService( szPath ); // BAA if( sz ) { schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( schSCM ) { schSrv = CreateService( schSCM, ServiceName, ServiceDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, //SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL ); if( schSrv ) { // BAA - Set Description sd.lpDescription = ServiceDescription; ChangeServiceConfig2( schSrv, SERVICE_CONFIG_DESCRIPTION, &sd); // BAA CloseServiceHandle( schSrv ); bRetVal = HB_TRUE; } else { ulSvcError = ( ULONG ) GetLastError(); } CloseServiceHandle( schSCM ); } else ulSvcError = ( ULONG ) GetLastError(); } hb_retl( bRetVal ); } HB_FUNC( LETO_SERVICEDELETE ) { TCHAR szPath[ MAX_PATH ]; HB_BOOL bRetVal = HB_FALSE; SC_HANDLE schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( schSCM ) { SC_HANDLE schService; SERVICE_STATUS_PROCESS ssp; DWORD dwStartTime, dwTimeout, dwWaitTime; DWORD dwBytesNeeded; leto_GetNameService( szPath ); // BAA - define ServiceName, ... // check and stop schService = OpenService( schSCM, ServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS ); if( schService ) { dwStartTime = GetTickCount(); dwTimeout = 30000; // BAA moved, 30-seconds time-out // Make sure the service is not already stopped. if( QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { // If a stop is pending, wait for it. while( ssp.dwCurrentState == SERVICE_STOP_PENDING ) { dwWaitTime = ssp.dwWaitHint / 10; if( dwWaitTime < 1000 ) dwWaitTime = 1000; else if( dwWaitTime > 10000 ) dwWaitTime = 10000; Sleep( dwWaitTime ); if( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { break; } if( ssp.dwCurrentState == SERVICE_STOPPED ) break; if( GetTickCount() - dwStartTime > dwTimeout ) break; } } // Send a stop code to the service. if( ControlService( schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &ssp ) ) { // Wait for the service to stop. while( ssp.dwCurrentState != SERVICE_STOPPED ) { dwWaitTime = ssp.dwWaitHint / 10; if( dwWaitTime < 1000 ) dwWaitTime = 1000; else if( dwWaitTime > 10000 ) dwWaitTime = 10000; // Sleep( ssp.dwWaitHint ); Sleep( dwWaitTime ); // BAA - define checked WaitTime if( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { break; } if( ssp.dwCurrentState == SERVICE_STOPPED ) break; if( GetTickCount() - dwStartTime > dwTimeout ) break; } } CloseServiceHandle( schService ); } // delete schService = OpenService( schSCM, ServiceName, DELETE ); if( schService ) { bRetVal = ( HB_BOOL ) DeleteService( schService ); CloseServiceHandle( schService ); if( ! bRetVal ) { ulSvcError = ( ULONG ) GetLastError(); } } else ulSvcError = ( ULONG ) GetLastError(); CloseServiceHandle( schSCM ); } hb_retl( bRetVal ); } HB_FUNC( LETOWIN_GETLASTERROR ) { hb_retnl( ulSvcError ); } #endif /* extern char carr1[40][40]; extern USHORT uiarr1len; extern char carr2[100][40]; extern USHORT uiarr2len; typedef struct { HANDLE hMem; LPVOID lpView; BOOL bNewArea; } MEMAREA; static MEMAREA s_MemArea = { 0,0,0 }; HB_FUNC( LETO_MSG ) { LPTSTR lpMsg = HB_TCHAR_CONVTO( hb_parcx( 1 ) ); MessageBox( GetActiveWindow(), lpMsg, TEXT( "Leto db server" ), MB_OK ); HB_TCHAR_FREE( lpMsg ); } HB_FUNC( LETO_CREATEMEMAREA ) { char szId[16]; sprintf( szId, "%s%d", "Leto_DB_", hb_parni(1) ); s_MemArea.hMem = CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 1024, (LPCTSTR)szId ); if( s_MemArea.hMem ) { s_MemArea.bNewArea = !( GetLastError() == ERROR_ALREADY_EXISTS ); s_MemArea.lpView = MapViewOfFile( s_MemArea.hMem, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 ); if( s_MemArea.bNewArea ) ((char*)s_MemArea.lpView)[0] = 'L'; } hb_retni( (s_MemArea.hMem)? s_MemArea.bNewArea : -1 ); } void leto_CloseMemArea( void ) { if( s_MemArea.lpView ) UnmapViewOfFile( s_MemArea.lpView ); if( s_MemArea.hMem ) CloseHandle( s_MemArea.hMem ); } HB_FUNC( LETO_CLOSEMEMAREA ) { leto_CloseMemArea(); } BOOL leto_ReadMemArea( char * szBuffer, int iAddr, int iLength ) { if( !s_MemArea.lpView ) return FALSE; memcpy( szBuffer, ((char*)s_MemArea.lpView)+iAddr, iLength ); szBuffer[iLength] = '\0'; return TRUE; } BOOL leto_WriteMemArea( const char * szBuffer, int iAddr, int iLength ) { if( !s_MemArea.lpView ) return FALSE; memcpy( ((char*)s_MemArea.lpView)+iAddr, szBuffer, iLength ); return TRUE; } BOOL leto_ThreadCreate( unsigned int (__stdcall *ThreadFunc)(void*) ) { unsigned int uiThreadID; if( _beginthreadex( NULL, 0, ThreadFunc, (void *) NULL, 0, &uiThreadID ) ) { return TRUE; } else return FALSE; } BOOL leto_ThreadMutexInit( LETO_MUTEX * pMutex ) { InitializeCriticalSection( pMutex ); return TRUE; } void leto_ThreadMutexDestroy( LETO_MUTEX * pMutex ) { DeleteCriticalSection( pMutex ); } BOOL leto_ThreadMutexLock( LETO_MUTEX * pMutex ) { EnterCriticalSection( pMutex ); return TRUE; } BOOL leto_ThreadMutexUnlock( LETO_MUTEX * pMutex ) { LeaveCriticalSection( pMutex ); return TRUE; } BOOL leto_ThreadCondInit( LETO_COND * pCond ) { if( ( pCond->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ) ) == 0 ) return FALSE; else return TRUE; } void leto_ThreadCondDestroy( LETO_COND * pCond ) { CloseHandle( pCond->hEvent ); } int leto_ThreadCondWait( LETO_COND * pCond, int iMilliseconds ) { DWORD dw; InterlockedExchange( &(pCond->ulLocked), 1 ); dw = WaitForSingleObject( pCond->hEvent, (iMilliseconds<0)? INFINITE : (DWORD)iMilliseconds ); switch( dw ) { case WAIT_OBJECT_0: { InterlockedExchange( &(pCond->ulLocked), 0 ); return 1; } case WAIT_TIMEOUT: return 0; } return -1; } BOOL leto_ThreadCondUnlock( LETO_COND * pCond ) { BOOL bRes; if( pCond->ulLocked ) { bRes = SetEvent( pCond->hEvent ); if (!bRes) InterlockedExchange( &(pCond->ulLocked), 0 ); return bRes; } return FALSE; } */ [/pre2]

Pasha: pRetValue - это ссылка на ссылку. Память в *pRetValue выделяется в функции LetoVarSet, и ее надо освободить. Так что здесь все нормально.

SergKis: Pasha пишет:Так что здесь все нормально. Это да, но лезет WARNING, а без него лучше.



полная версия страницы