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




Пост N: 2792
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.03.13 17:35. Заголовок: Ascan ?


 
Есть массив вида {{},{},{}}

поиск веду в первом элементе
do while !eof()
..
if ascan(klnmas[1],{|fff| fff==nakl_r1->kod_kl})==0
skip
loop
endif
.......
skip
enddo
медленновато что то или меня уже плющит....
есть какой то другой аналог Ascan который пошустрее работает ?
Понятно что вот так быстрее будет
if ascan(klnmas[1],nakl_r1->kod_k)==0
skip
loop
endif


RDD скипает быстрее чем работает Ascan с блоком кода....


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]


Администратор




Пост N: 2764
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 18.03.13 20:10. Заголовок: Поиск в ascan выполн..


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

Если я правильно понял твою задачу, ты формируешь двумерный массив с размерностями 3*n, где в первом подмассиве хранятся ключи, а в двух следующих - соответствующие им данные.
Если "перевернуть" массив, т.е. использовать размерности не 3*n, а n*3, то можно будет использовать хэш, примерно как в примере Петра:

http://clipper.borda.ru/?1-4-0-00000784-000-0-0-1354477086

только можно вместо

_AADD(hDim,{495, 1})

вызывать

_AADD(hDim,{495, x1, x2, ...})

т.е. варьировать 2-ю размерность

Ну а свою функцию я когда-то давно выкладывал в теме:

https://groups.google.com/forum/#!topicsearchin/comp.lang.xharbour/sorted$20array/comp.lang.xharbour/b0jKrNhcNAk

в этой же теме Пшемек рассказывает, как использовать хеш


Спасибо: 0 
ПрофильЦитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 18.03.13 21:43. Заголовок: Неполный поиск сокращает время


В этой задаче можно завершать поиск , если хотя бы один элемент найден,
как делает ASCAN2() (см. ниже) в отличие от ASCAN(), который все равно проверяет весь массив.

Function ascan2(arr,bl, nstart, nqu )
Local n:=0,m,L:=len(arr),nret:=0,nend
Local lbl:= ( valtype(bl)="B")
if nstart=NIL
nstart=1
endif
if nqu=NIL
nend:=L
else
nend:=nstart-1+nqu
endif
for n=nstart to nend
if lbl
if eval(bl,arr[n])
nret :=n
EXIT
endif
else
if bl==arr[n]
nret :=n
EXIT
endif
endif//lbl
next i
return nret


Спасибо: 0 
Цитата Ответить
Администратор




Пост N: 2765
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 18.03.13 21:52. Заголовок: petr707 пишет: как ..


petr707 пишет:

 цитата:
как делает ASCAN2() (см. ниже) в отличие от ASCAN(), который все равно проверяет весь массив.



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

вот фрагмент этой функции для поиска строки в массиве:

            else if( HB_IS_STRING( pValue ) ) 
{
do
{
PHB_ITEM pItem = pBaseArray->pItems + nStart++;

/* NOTE: The order of the pItem and pValue parameters passed to
hb_itemStrCmp() is significant, please don't change it. [vszakats] */
if( HB_IS_STRING( pItem ) && hb_itemStrCmp( pItem, pValue, fExact ) == 0 )
return nStart;
}
while( --nCount > 0 );
}


Поиск в этой функции реализован самым оптимальным образом. Но это не делает оптимальным сам алгоритм полного перебора.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2793
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.03.13 22:01. Заголовок: Pasha Спасибо за по..


Pasha
Спасибо за подробный ответ !

Pasha пишет:

 цитата:
Если я правильно понял твою задачу, ты формируешь двумерный массив с размерностями 3*n, где в первом подмассиве хранятся ключи, а в двух следующих - соответствующие им данные.



Ну не совсем так.
Изначально создается массив amas:={{},{},{}} c 3 элементами
где каждый элемент массив.
Затем я обрабатываю справочник контрагентов на предмет условий
заданных юзером и заполняю первый элемент кодами контрагентов.
Остальные 2 элемента так же заполняются соответствующими
цифирками.
После этого я обрабатываю журнал накладных , предварительно
установив в нем SCOPE за интервал дат (по индексу типа DTOS(data_n))
и хожу в цикле проверяя массив (отсеивая не нужных контрагентов).
Вот и все.
Думаю сортировка массива скорости не прибавит так же как и работа с хэш.
По любому этот отчет в Harbour cтроится в разы быстрее нежели в
Clipper+SIX или Clipper+ADS.
Просто хотелось еще не много ускорить ;)


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2766
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 18.03.13 22:36. Заголовок: Dima пишет: Думаю с..


Dima пишет:

 цитата:
Думаю сортировка массива скорости не прибавит так же как и работа с хэш.



Для небольших массивов разница будет несущественной, а для больших - просто огромной. Вот к примеру такой тест:

func main
Local nSize := 10000, nI, nKey, nSec, nRes
Local aDim := {}, aDim2 := {}
Local hDim := { => }

// заполнение массива и хеша
for nI := 1 to nSize
nKey := ((nI + Int(nSize/2)) % nSize) + 1
AADD(aDim, nKey)
AADD(aDim2, nI)
_AADD(hDim, nKey, nI)
next

nRes := 0
? 'Array scan', len(aDim)
nSec := Seconds()
for nI := 1 to nSize
nRes += aDim2[ASCAN(aDim, nI)]
next
? (Seconds() - nSec)*1000, nRes

nRes := 0
? 'Hash scan', len(aDim)
nSec := Seconds()
for nI := 1 to nSize
nRes += hDim[nI]
next
? (Seconds() - nSec)*1000, nRes

return nil

PROCEDURE _AADD( aHash, nKey, nI )

aHash[nKey] := nI

retu

Размер nSize я взял 10000, чтобы время хоть как-то отличалось от нуля. Результат выводится в миллисекундах. Для массива у меня получилось 219 мс, для хеша - опять ноль.
Если nSize задать 30000, то результат для массива будет 1953 мс, для хеша - 15мс. Разница в производительности выходит на порядки.
Это все равно, что сравнивать разницу поиска с помощью skip и seek. Кстати, аналогия получается прямая, поскольку алгоритмы поиска при этом совершенно идентичны.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2795
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.03.13 23:24. Заголовок: Pasha Буду мозговат..


Pasha
Буду мозговать , спасибо.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 89
Зарегистрирован: 19.05.05
ссылка на сообщение  Отправлено: 19.03.13 09:24. Заголовок: Я может не знаю всех..


Я может не знаю всех дополнительных условий, но для приведенного выше алгоритма почему
нельзя сделать индекс <Имя контрагента>+dtos (data) в журнале накладных . Для каждого
кантрагента,попадающего под условия, отбираются данные за указанный интервал. В этом случае
отпадает перебор по ascan () и отсекаются лишние движения по базе накладных.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2796
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.03.13 10:46. Заголовок: Что то как то не при..


Что то как то не привычны эти Hash и пока что потерялся ;)
Как следующий код преобразовать к Hash массивам ?

 
ams:={{},{},{}}

for i=1 to 100
aadd(ams[1], i )
aadd(ams[2],seconds())
aadd(ams[3],time())
next

i:=ascan(ams[1],33)

? ams[1][ i ]
? ams[2][ i ]
? ams[3][ i ]



Вот так что ли .....
 
local ams:={=>}
local npos

for i=1 to 100
ams[ i ]:={seconds(),time()}
next

if HB_HHASKEY( ams, 33, @nPos )
? hb_hget(ams,npos)[1]
? hb_hget(ams,npos)[2]
endif




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




Пост N: 166
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 19.03.13 12:08. Заголовок: Dima пишет:Что то ка..


Dima пишет:
 цитата:
Что то как то не привычны эти Hash и пока что потерялся


Может поможет: Скрытый текст


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2797
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.03.13 12:31. Заголовок: SergKis Спасибо. М..


SergKis
Спасибо.

Мне вот не понятна одна штука

 
aHash := {10=>, 20=>}
? HB_HHASKEY( aHash, 5, @nPos ), nPos // .F. 0
? HB_HHASKEY( aHash, 10, @nPos ), nPos // .T. 1
? HB_HHASKEY( aHash, 15, @nPos ), nPos // .F. 1 // почему не ноль ?
? HB_HHASKEY( aHash, 20, @nPos ), nPos // .T. 2
? HB_HHASKEY( aHash, 25, @nPos ), nPos // .F. 2 // почему не ноль ?



Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2798
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 19.03.13 14:01. Заголовок: В общем в первом при..


В общем в первом приближении разобрался. Всем спасибо !

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




Пост N: 167
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 19.03.13 16:56. Заголовок: SergKis пишет:Может ..


SergKis пишет:
 цитата:
Может поможет:


Небольшой пример вдогонку:Скрытый текст


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2812
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 13:01. Заголовок: еще тест ;) proc m..


еще тест ;)

 
proc main
local nfor:=1000000
local i
local ms:={}
local hms:={=>}
local nsec

nsec:=seconds()
for i=1 to nfor
aadd(ms,i)
next
? (seconds()-nsec)*1000 //641

nsec:=seconds()
for i=1 to nfor
hms:=i
next
? (seconds()-nsec)*1000 //36937 но если предварительно сделать (до заполнения массива)
// hb_hAllocate( hms, nfor ) , тогда время 821



nsec:=seconds()
ascan(ms,nfor)
? (seconds()-nsec)*1000 //31

nsec:=seconds()
HB_HHASKEY(hms,nfor)
? (seconds()-nsec)*1000 //0


return


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2768
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 13:27. Заголовок: Конечно, при использ..


Конечно, при использовании хеша добавление в него происходит медленнее, чем при добавлении элемента в массив.
Это тоже самое, что добавлять записи в файл с индексом медленнее, чем в файл без индекса, так как в первом случае еще обновляется индекс. Выигрыш достигается затем при поиске по ключу.
Еще к тому же AADD оптимизирован по выделению памяти, т.е. элементы в него добавляются не по одному. Хеш без такой оптимизации сильно ему проиграет. То, что настолько сильно, для меня сюрприз.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2813
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 13:34. Заголовок: Есть такая функция a..


Есть такая функция
aValues := hb_hValues( aHash ) Возвращает массив всех значений массива aHash
А нет ли похожей которая возвращает массив значений с определенным ключиком ?

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2769
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 13:54. Заголовок: Dima пишет: А нет л..


Dima пишет:

 цитата:
А нет ли похожей которая возвращает массив значений с определенным ключиком ?



Так в хеш ключ может быть только в одном экземпляре. И значение может быть одно.
Или надо выбрать массив по диапазону ключей ?


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2814
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 13:56. Заголовок: Pasha пишет: Или на..


Pasha пишет:

 цитата:
Или надо выбрать массив по диапазону ключей ?


Да. Я не так выразился.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2770
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 14:04. Заголовок: Нет, увы, такой функ..


Нет, увы, такой функции нет

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2815
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 14:07. Заголовок: Еще вопросец ;) fm..


Еще вопросец ;)

 
fmas:={}
hmas:={=>}

dbeval({|| hmas[recno()]:={kod_kl,kmcod,codn}})


fmas:=xxxx()
как быстро заполнить массив fmas значениями ключей
для kmcod==3 ?



BM_DBSETFILTERARRAY(fmas)


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2816
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 14:21. Заголовок: Пока посетила только..


Пока посетила только вот такая идея
 
use klient new
hb_hAllocate( hmas, lastrec() )
dbeval({|| hmas[recno()]:={kmcod,codgr}})
// для kmcod==3

hb_hEval( hmas, {|key,sval,ind| if(sval[1]==3,aadd(fmas,key),)})
// при размере массива 700000 записей hb_hEval работает 530 мс , хочется что то побыстрее


BM_DBSETFILTERARRAY(fmas)
dbgotop()
browse()



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




Пост N: 170
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 14:23. Заголовок: Pasha пишет:Конечно,..


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


В bcc использовал вашу функцию AADDU(<aArray>, <xKey>, <nSum1>, [nSum2], ...) при переходе на msvc она не перенеслась, стал использовать Hash (class bkHash, sum method. см. выше), протестировал по скорости в bcc оба способа. Ваш на десятые доли секунды быстрее (тестировал одной на годовой базе). Поэтому очень спокойно перешел на Hash.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2817
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 16:17. Заголовок: Dima пишет: hb_hEva..


Dima пишет:

 цитата:
hb_hEval( hmas, {|key,sval,ind| if(sval[1]==3,aadd(fmas,key),)})
// при размере массива 700000 записей hb_hEval работает 530 мс , хочется что то побыстрее



 
dbeval( {|| hmas[recno()]:={kod_kl,nomer}})

? len(hmas) // 700000 ключей

fmas:={}
nsec:=seconds()
hb_hEval( hmas, {|key,sval,ind| if(sval[1]==5,aadd(fmas,key),)})
? (seconds()-nsec)*1000 // 594 mc


fmas:={}
nsec:=seconds()
for each v in hmas
if v:__enumValue()[1]==5
aadd(fmas,v:__enumKey())
endif
next
? (seconds()-nsec)*1000 // 437 mc тут побыстрее будет



А еще быстрее можно сделать выборку ? ;)

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2771
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:16. Заголовок: Dima пишет: А еще б..


Dima пишет:

 цитата:
А еще быстрее можно сделать выборку ? ;)



Можно перевернуть хеш. То есть, в качестве ключа использовать kmkod, а вместо значения - массив {{recno(), kod_kl, codn}, ...}
Если нужны только номера записей, можно добавлять только recno()

примерно так:

hmas:={=>}

// разверну для ясности dbeval
go top
while ! eof()
hmas[kmcod] := {}
AADD(hmas[kmcod], {recno(), kod_kl, codn})
// или
AADD(hmas[kmcod], recno())
skip
enddo

Тогда значением hmas[3] будет массив с номерами записей.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2821
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:29. Заголовок: Pasha Да но KMCOD н..


Pasha
Да но KMCOD на разных записях может быть одинаковый , поэтому так не годится.
Смысл затеи прост. Из заполненного hash массива быстро выбрать нужные Recno() и сложить в массив.
Например нужно выбрать всех клиентов у которых код торгового агента KMCOD равен 5 или скажем
выбрать всех клиентов у которых код группы CODGR равен 7.
Хотелось сделать универсальный хэш массив (для разного рода выборок для фильтра) и такой
массив я как бы создал но поиск по нему оставляет желать лучшего по времени. Хотя результат
500 мс для размера массива 700 000 записей тоже не плох. Имея массив с номерами записей
BM фильтр ставится в лет. Сейчас такой массив записей я заполняю иначе (юзаю нужный ордер
и заполняю массив). Думалось что с хэш массивом будет быстрее так как не надо лишний раз дергать
базу.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2772
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:35. Заголовок: Dima пишет: Да но K..


Dima пишет:

 цитата:
Да но KMCOD на разных записях может быть одинаковый , поэтому так не годится.



Как раз именно так и годится. Значением hmas[kmcod] будет не один номер записи, а массив recno(). И поиск в этом hmas по значению kmkod будет мгновенным.
А одним хеш для всех случаев не обойдешься. Если выборки нужны по нескольким параметрам, то надо и делать несколько хеш-массивов, каждый для своего случая.
Смысл использования хеш только в мгновенном поиске. Использовать хеш, чтобы затем делать цикл по нему для поиска бессмыссленно.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2773
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:40. Заголовок: Дима, если работать ..


Дима, если работать с хеш непривычно, я могу выложить свои функции для отсортированных массивов. Мне надо только причесать свой код, тот вариант, что я выкладывал раньше, не сохранился.
Суть примерно та же, что и хеш, только выглядит несколько нагляднее.
К тому же, как выяснилось, при добавлении в хеш по умолчанию не оптимизировано выделение памяти. А у AADD с этим все в порядке.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2822
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:41. Заголовок: Pasha пишет: Смысл ..


Pasha пишет:

 цитата:
Смысл использования хеш только в мгновенном поиске. Использовать хеш, чтобы затем делать цикл по нему для поиска бессмыссленно.


Это я уже понял и подумаю над твоей идеей. Спасибо

Pasha пишет:

 цитата:
Если нужны только номера записей, можно добавлять только recno()


Да я это понял. Спасибо. Обдумываю.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2823
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 19:44. Заголовок: Pasha пишет: К тому..


Pasha пишет:

 цитата:
К тому же, как выяснилось, при добавлении в хеш по умолчанию не оптимизировано выделение памяти


я пока делаю так hb_hAllocate( hms, Lastrec() ) и все нормально по скорости добавления.
Pasha пишет:

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


Было бы не плохо и это сильно и не горит , хочу еще сам поиграться с хеш массивами.

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




Пост N: 173
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 21:09. Заголовок: Pasha пишет:тот вари..


Pasha пишет:
 цитата:
тот вариант, что я выкладывал раньше, не сохранился.


Это, наверно, они. http://zalil.ru/34366220

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2824
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 21:30. Заголовок: Pasha пишет: тот ва..


Pasha пишет:

 цитата:
тот вариант, что я выкладывал раньше, не сохранился.


да он где то есть на форуме я не давно натыкался на эту тему , нужно пошукать немного.

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




Пост N: 174
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.03.13 21:38. Заголовок: Pasha пишет:А одним ..


Pasha пишет:
 цитата:
А одним хеш для всех случаев не обойдешься. Если выборки нужны по нескольким параметрам, то надо и делать несколько хеш-массивов, каждый для своего случая.


Как это будет выглядеть применительно к Leto ? "несколько хеш-массивов" надо пополнять или создавать заново ?
С предложенным способом от Dima понятно, при загрузке программы создал такой hash и работаю, на клиенте относительно него, пополняя его при LastRec > len(hmas) до потери пульса.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2826
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.03.13 22:24. Заголовок: SergKis пишет: попо..


SergKis пишет:

 цитата:
пополняя его при LastRec > len(hmas) до потери пульса


И меня та же идея посещала , но LETO пока не юзаю (поигрался малость - ПОНРАВИЛОСЬ) и перевожу прогу с Clipper на Harbour CDX а потом будет и LETO и вопросов будет видимо много.
Ты еще не забывай что такой массив еще нужно корректировать и иметь реакцию на удаление записей с учетом что все
это может происходить в сети ;)
Вообще при таком подходе либо держать нужно кучку hash массивов и юзать BM фильтра или
иметь такую же кучку дополнительных индексов (тегов) и юзать SCOPE. И там и там есть свои
и плюсы и минусы , в прочем это смотря какая задача и как все там организовано.
На вкус и цвет как говорится , товарищей нет


SergKis пишет:

 цитата:
пополняя его при LastRec > len(hmas) до потери пульса


Как славно что не нужно делать вот такой проверки , да и хэш массивов нет в clipper;)
 
if len(hmas)<4096

else

endif


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




Пост N: 175
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 08:20. Заголовок: Dima пишет:Вообще пр..


Dima пишет:
 цитата:
Вообще при таком подходе либо держать нужно кучку hash массивов


Проще работать с dbf MemIO или даже локальным dbf с полями, обеспечивающими быстрый доступ для создания нужных tag-ов и для переключения просмотров browse. С таблицей сервера relation по recno. Для обеспечения секретности можно поля обезличить (типа R_1,R_2,...) или что-то еще. Сейчас через MemIO примерно так делаем, только не весь dbf, а через запросы. Тоже пока без сервера- процесс перевода с Clipper на cdx в разгаре, потом Leto.
Dima пишет:
 цитата:
Ты еще не забывай что такой массив еще нужно корректировать и иметь реакцию на удаление записей с учетом что все это может происходить в сети ;)


В локальном dbf все записи, с учетом удаленных и только ключевые, не изменяемые поля. На сервере можно включит триггер, заполняющий поле типа TimeStamp (или символьное DtoS(Date())+StrTran(Time(), ":", "")+right(hb_ntos(bk_MilliSeconds()), 3)), для запросов по изменениям ...


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2775
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 21.03.13 10:04. Заголовок: SergKis пишет: Как ..


SergKis пишет:

 цитата:
Как это будет выглядеть применительно к Leto ?



Если использовать Leto, то надо возложить функцию формирования bm-фильтра на сервер. Зачем гонять данные с сервера на клиент, формировать на клиенте массив с номерами записей и затем гнать обратно этот массив на сервер ? Зачем тогда такой сервер нужен ?

Сейчас в BMDBF* по set filter массив с номерами записей и так формируется, но это делается без учета scope. Можно исправить этот недостаток. Я вижу 3 пути для этого:

1) Убедить харбор-сообщество сделать это прямо в харборе (пока не получилось).
2) Скопировать сырцы BMDBF* в letodb и внести в них нужные изменения.
3) Сделать в letodb rdd - наследника BMDBF* и переписать в нем метод SetFilter (это сложнее).

Ну и наконец, можно на сервере просто добавить функцию, которой вы передавались параметры:
имя тэга, scope, filter, и эта функция сама бы формировала bm-фильтр по этим данным

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2830
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 21.03.13 10:18. Заголовок: Pasha Поддерживаю в..


Pasha
Поддерживаю вариант 2 и "можно на сервере просто добавить функцию"

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




Пост N: 177
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 11:08. Заголовок: Dima пишет:Поддержив..


Dima пишет:
 цитата:
Поддерживаю вариант 2 и "можно на сервере просто добавить функцию"


Тоже

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




Пост N: 178
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.03.13 11:34. Заголовок: Pasha пишет:Ну и нак..


Pasha пишет:
 цитата:
Ну и наконец, можно на сервере просто добавить функцию, которой вы передавались параметры: имя тэга, scope, filter, и эта функция сама бы формировала bm-фильтр по этим данным


Можно было бы обойтись этим, но тогда
If rddname() == 'LETO'
leto_setBmFilter(Tag,Scopr,Filter)
Else
dbSetFilter(...)
Endif
тоже как то ...

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2778
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 21.03.13 21:59. Заголовок: Добавил на сервере l..


Добавил на сервере letodb функцию LBM_DbSetFilter

Вызов функции с клиента:
leto_ParseRec( leto_Udf('LBM_DbSetFilter', <xScope>, <xScopeBottom>, <xOrder>, <cFilter>, <lDeleted> ) )
Функция устанавливает bitmap-фильтр по условиям scope, filter, и возвращает буфер с первой записью, удовлетворяющей условию фильтра

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2858
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 22.03.13 22:02. Заголовок: Pasha пишет: LBM_D..


Pasha пишет:

 цитата:
LBM_DbSetFilter


проясни плиз.
если активным является ордер 2 , но в LBM_DbSetFilter я указал xOrder равным 5 , какой
ордер будет активным после установки LBM_DbSetFilter ?
Должен быть 2 , что то не увидел я в сырцах возврата на прежний индекс после установки
LBM_DbSetFilter.

Сейчас я ставлю простой фильтр когда SCOPETOP и SCOPEBOTTOM равны вот так.
Прежний ордер остается на месте в любом случае после выполнения XbmFilter.
 
func XbmFilter(nseaord,xsea,myblock)
local ret:=.t.
local old_ord:=indexord()
local old_rec:=recno()
local afilt:={}
default myblock to nil

dbclearfilter()

dbsetorder(nseaord)
if dbseek(xsea)
dbOrderInfo(DBOI_SCOPEBOTTOM,,, xsea)
dbeval({|| aadd(afilt,recno())},myblock,,,,.t.)
dbOrderInfo(DBOI_SCOPEBOTTOMCLEAR)
endif
dbsetorder(old_ord)

if len(afilt)>0
BM_DBSETFILTERARRAY(afilt)
go top
else
ret:=.f.
dbgoto(old_rec)
endif
return ret




Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2783
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.03.13 01:06. Заголовок: На сервере нет инфор..


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

LBM_DbSetFilter( <xScope>, <xScopeBottom>, <cFilter> )

При этом серверу автоматически передается текущий индекс.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2859
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 23.03.13 11:26. Заголовок: Pasha пишет: Чтобы ..


Pasha пишет:

 цитата:
Чтобы избежать этого, я на клиенте добавил функцию, у которой всего 3 параметра:


а тут их 5
Pasha пишет:

 цитата:
<xScope>, <xScopeBottom>, <xOrder>, <cFilter>, <lDeleted>



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2784
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.03.13 14:08. Заголовок: Это в функции на сер..


Это в функции на сервере 5 параметров, так как серверу надо знать управляющий индекс клиента и флаг set deleted.
А в клиентской функции 3 параметра: 2 для scope и фильтр.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2893
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 28.03.13 20:07. Заголовок: Pasha Элементы в хэ..


Pasha
Элементы в хэш массиве располагаются в порядке их добавления или там какой то свой принцип ?
Изначально думал что в порядке добавления............но вроде оно не так.

ЗЫ
Разобрался потестив на примерах. Там свой загадочный принцип сортировки.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 3617
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 10.10.13 15:57. Заголовок: Dima пишет: Изначал..


Dima пишет:

 цитата:
Изначально думал что в порядке добавления............но вроде оно не так


что бы было в порядке добавления юзаем hb_hSetOrder(hmas,.t.)


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 3
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет