12.10.2004, 18:53 | #1 |
Участник
|
Что хранит map ? ссылки на Record или сам рекорд в упакованном виде ?
Подскажите как реально работает map
при исполнении примерно такого кода : MapIterator mi; InventTrans inventTransCopy; InventTrans inventTransCopy2; map mapInventTrans; mapInventTrans = new map(types::INTEGER,types::RECORD); ... mapInventTrans.insert(inventTransCopy.RecId,inventTransCopy); ... mi = new mapIterator(mapInventTrans); mi.begin(); while (mi.more()) { inventTrans = mapInventTrans.lookup(mi.key()); /* Что реально происходит при вызове методов insert и lookup ? Упаковка переменной типа RECORD в некую бинарную структуру и копирование, либо просто копирование ссылки на экземпляр RECORD ? Кстати, а если мы перебирали эти рекорд в цикле типа while select forupdate то что будет с элементами mapa которые мы заполнили в процессе цикла после того как цикл завершится ? */ ... } |
|
12.10.2004, 21:27 | #2 |
Участник
|
посмотрите сюда
http://www.axforum.info/forums/showt...&threadid=3209 Цитата:
Часто некоторые на форумах повторяют миф:
Миф: Объекты передаются по ссылке, а примитивы по значению. ... Истина же...: Истина 1: Всё в Java передается по значению. Объекты, же, вообще никогда не передаются Истина 2: Значениями переменных могут быть только примитивы или ссылки, но не объекты. |
|
12.10.2004, 21:48 | #3 |
Участник
|
2 Muzzy
Спасибо за ответ. Хотелось бы узнать еще вот что. Получается что если я перебираю в цикле (while select) записи таблицы и нужные мне кладу в map, то получается что по выходе из цикла все элементы map-a будут ссылаться на одну запись которая была в цикле последней... А хотелось бы иметь набор отобранных экземпляров записей ... Т.е. неясно как ведет себя цикл при итерациях. - 1. Создает заново новый экземпляр табличной переменной, а старая освобождается (если, естественно, на неё больше нет ссылок) 2. либо просто грузит новые значения в один и тот же экземпляр. Подозреваю, что скорее всего второе. Но в таком случае - есть ли способ гарантированно создать копию, чтобы положить её в map ? (Это нужно для создания некоего подобия кеша из записей, с возможностью быстрого доступа и обработки) Я смотрел код в аксапте (3.0 SP 2 ) и, например, в классе InventCostItemDim нашел такой пример, но там для каждой строки создается отдельный экземпляр путем нового (!!!) запроса к базе данных : /*для каждой выбранной строки вызывается этот метод */ protected void loadTrans(InventTrans _inventTrans) { InventTrans inventTransCopy; ; InventTransCopy = inventTrans::findRecId(_inventTrans.RecId,true); if (inventTransCopy.RecId) { mapInventTrans.insert(inventTransCopy.RecId,inventTransCopy); ... } но мне кажется это неоптимально - для каждой записи делать отдельный запрос к базе. Гораздо быстрее (что как раз от меня и требуется !) было бы отбирать группу записей и потом обрабатывать, а не дергать их по одной заводя кучу табличных переменных. Хотя возможно движок аксапты использует кеширование, так что вызов приведенного метода уже не приводит к новому обращению к базе. Но это надо уточнять. |
|
12.10.2004, 22:56 | #4 |
Участник
|
Цитата:
Изначально опубликовано Logger
Хотелось бы узнать еще вот что. Получается что если я перебираю в цикле (while select) записи таблицы и нужные мне кладу в map, то получается что по выходе из цикла все элементы map-a будут ссылаться на одну запись которая была в цикле последней... элементы будут ссылаться на объекты в памяти. Этих объектов будет столько, сколько было обработано записей в цикле. Аксапта, как и java сама управляет памятью. Не мучайтесь этим вопросом. Или разберитесь досконально. Читайте в документации по java. Про хранение записей. Не понимаю, зачем вы используете map, а не RecordSortedList. Это так задумано или вы про RecordSortedList еще не прочитали?... Обратите внимание, что есть еще и recordLinkList. Но RecordSortedList ищет быстрее... |
|
12.10.2004, 23:00 | #5 |
Участник
|
Цитата:
Изначально опубликовано Logger
но мне кажется это неоптимально - для каждой записи делать отдельный запрос к базе. Гораздо быстрее (что как раз от меня и требуется !) было бы отбирать группу записей и потом обрабатывать, а не дергать их по одной заводя кучу табличных переменных. С тех пор... "работает - не трожь" Цитата:
Изначально опубликовано Logger
Хотя возможно движок аксапты использует кеширование, так что вызов приведенного метода уже не приводит к новому обращению к базе. Но это надо уточнять. |
|
13.10.2004, 09:11 | #6 |
Участник
|
2 Muzzy
Цитата: -------------------------------------------------------------------------------- Изначально опубликовано Logger Хотелось бы узнать еще вот что. Получается что если я перебираю в цикле (while select) записи таблицы и нужные мне кладу в map, то получается что по выходе из цикла все элементы map-a будут ссылаться на одну запись которая была в цикле последней... Изначально опубликовано Muzzy Почему? Нет, конечно. элементы будут ссылаться на объекты в памяти. Этих объектов будет столько, сколько было обработано записей в цикле. --------------------------------------------------------------------------------- Так ведь в том то и дело, что если на каждом шаге цикла не создается отдельного экземпляра записи, то в map мы фактически будем класть ссылку на один и тот же экземпляр класса, только ключи в map-е на эту ссылку будут отличаться. А про RecordSortedList и recordLinkList я не знал. Буду разбираться. В любом случае, огромное спасибо за ответы. |
|
13.10.2004, 09:38 | #7 |
Участник
|
Интересно.
Проверка показала, что все-таки на каждом шаге создается новый экземпляр, так что все в порядке. в map-е будут ссылки на разные экземпляры. |
|
13.10.2004, 11:42 | #8 |
Administrator
|
Записи (Types::Record) не являются объектами Axapta в общем смысле. Скорее они похожи на статические структуры.
__________________
Not registered yet? Register here! Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me |
|
15.10.2004, 10:22 | #9 |
Участник
|
Цитата:
Изначально опубликовано Maxim Gorbunov
Записи (Types::Record) не являются объектами Axapta в общем смысле. Скорее они похожи на статические структуры. PHP код:
В обычную ф-ю таблицы передаются по ссылке. Тут скорее всё таки приколы в методе Map.insert, который как то по особенному обрабатывает таблицы. |
|
15.10.2004, 10:45 | #10 |
Участник
|
Цитата:
Изначально опубликовано Maxim Gorbunov
Записи (Types::Record) не являются объектами Axapta в общем смысле. Скорее они похожи на статические структуры. В общем ответ на вопрос именно "хранит в упакованном виде". Несмотря на то что таблицы в аксапте ведут себя как обычные объекты, но в методе Map::insert для типа types::record происходит неявное создание некоего промежуточного хранилища полей таблицы и копирование их значений туда, хранится в map-е именно эта переменная. В методе lookup видимо происходит "обратная расшифровка" таблицы (видимо по TableId) - создаётся новая (!) табличная переменная такого типа, в неё распаковываются значения полей и она возвращается пользователю. Замечу что: Unit unit1, unit2; Map map = new Map( types::integer, types::Record ); ; select unit1; map.insert( unit1.RecId, unit1 ); unit2 = map.lookup( unit1.RecId ); next unit2; // Выдаст ошибку, т.к. unit2 - совершенно новый экземпляр таблицы unit, с неоткрытым еще запросом (select-ом) |
|
|
|