вторник, 12 апреля 2016 г.

Cache': zobj команды и $zobj функции

Далее по тексту используется сленг, слово oref означает Object REFerence, ссылка на объект. В приведенном списке те функции и команды которые не указаны в документации на Вашу версию Каше, являются недокументированными. В различных версиях Каше поведение недокументированных функций и команд может отличаться, или некоторые команды и функции могут отсутствовать. Кроме того крайне рекомендуется трижды проверить необходимость использовать нижеприведенные функции и команды и тщательно изучить документацию на используемую Вами версию Каше, при возможности обратиться к консультантам Intersystems и детально проверить поведение команд и функций в ошибочных ситуациях. При нормальном течении разработки приложений нижеприведенные материалы скорее всего не должны понадобиться.
Хранение объектов и счетчик ссылок

В различных версиях Каше открытые объекты могут храниться различным образом. В более младших - в обычных локальных переменных, в более старших - в скрытых локальных переменных, которые не видны через команды write, kill, и другие. Для хранения объектов и служебной для них информации используются локальные переменные с префиксом %obj. Несмотря на отсутствие явных рекомендаций Intersystems по использованию (неиспользованию) такого префикса этот факт следует иметь ввиду. Кроме того имеет смысл обратить внимание на INT рутины генерируемые компилятором классов и просмотреть имена локальных переменных используемых для блокировок объектным движком, например реализация некоторых уровней concurrency через использование локальных переменных вида %0CacheLock на чтение и запись.

У объекта ведется счетчик ссылок. Их два - пользовательский и системный. Если оба счетчика обнуляются, то объект закрывается и удаляется. Удаление объекта необязательно означает удаление переменной которая содержит ссылку на него и наоборот, это поведение младших версий Каше. В более старших версиях Каше, имеющих System OREF Support, удаление переменной, ссылающейся на объект, приводит к уменьшению на единицу как пользовательского так и системного счетчика независимо друг от друга. Есть возможность увеличить или уменьшить системный счетчик ссылок независимо от пользовательского счетчика, что позволяет реализовать оригинальные способы хранения данных.

Например, создав объект, мы имеем оба счетчика по 1. Увеличим системный счетчик (станет 2) и удалим ссылку на объект (системный станет 1, а пользовательский 0). В результате получим живой объект, не видимый командам kill, write, и другим. Если мы знаем его id, то можем получить по нему oref как объектную ссылку. Если ссылку запомним в локальной переменной то увеличим счетчики ссылок (оба) на единицу. После этого можем по oref обратиться к свойствам и методам этого объекта.

Идентификатор объекта

У объекта имеется два идентификатора. Один - это идентификатор его хранения в базе данных. Обычно это автоматически генерируемое число. Имея класс объекта и его идентификатор можно открыть объект, то есть переместить его в локальные переменные, проведя чтение. Основное требование к идентификаторам такого рода - их уникальность в рамках класса. Второй идентификатор - это номер объекта среди загруженных в память. Этот номер поддерживается автоматически и уникален среди объектов всех классов среди открытых объектов процесса. Способ поддержки уникальности может различаться в разных версиях Каше. Исключение - это объекты классов datatype, используемые как атрибуты другого объекта. Для них не заводится ни хранимого идентификатора ни идентификатора в памяти. Но если завести такой объект автономно то идентификатор в памяти создается, например:
USER>s obj=##class(%String).%New()
S obj=##CLASS(%String).%New()
^
<METHOD DOES NOT EXIST>
USER>s obj=$zobjnew("%String")
USER>w
obj=<OBJECT REFERENCE>[1@%Library.String]
Это показывает что объектный движок пытается сопротивляться заведению объектов datatype классов в автономном виде, но тем не менее такая возможность существует.

$zobjclass(oref)

Функция возвращает имя класса объекта, ассоциированного с заданным oref если этот oref указывает на корректный объект или пустую строку если на некорректный или несуществующий. Например:
SAMPLES>s oref=##class(User.NewClass1).%New()
SAMPLES>w $zobjclass(oref)
User.NewClass1
В некоторых версиях Каше при обращении к oref указывающему на неправильный объект эта функция может как возвращать пустую строку так и генерировать ошибку <INVALID OREF>

$zobjclassmethod(ClassName,MethodName,arglist)

Альтернативный способ вызова метода класса. Позволяет использовать имя класса и имя метода заданные строковыми значениями. arglist - переменное число параметров. Например:
SAMPLES>w $zobjclassmethod("User.NewClass1","NewMethod1","user")
USER
Функция может использоваться как возвращающая и как не возвращающая значение (вызов через do).

$zobjid(OREF)

Возвращает идентификатор объекта в памяти. В старших версиях при формировании строки из oref используется соглашение "идентификатор в памяти @ полное имя класса". Вот эта первая часть и возвращается. Не следует путать приведение oref к строке и результат команды write в безаргументной форме. В большинстве случаев результат $zobjid для валидного объекта совпадает с +oref.

$zobjmethod(OREF,MethodName,arglist)

Альтернативный способ вызова метода объекта. Позволяет использовать имя метода в виде строки. arglist - переменное число параметров. Функция может использоваться как возвращающая и как не возвращающая значение (вызов через do).

$zobjmod(OREF,modbit)

Обращается к внутренней C-функции get_obj_mod и возвращает 0 или 1 в зависимости от текущего состояния бита модификации для объекта заданного oref. modbit задает позицию бита модификация которого проверяется.

$zobjnew(ClassName)

Создает новый объект в памяти по имени класса заданного строкой. Я пока не знаю как выполнить то же самое но с передачей параметров. Например:
SAMPLES>s obj=$zobjnew("User.NewClass1")
SAMPLES>w
obj=<OBJECT REFERENCE>[1@User.NewClass1]
Вероятно, ближайший вариант - это
s obj=$zobjclassmethod(ClassName,"%New",args...)
Но этот способ требует чтобы у класса существовал метод %New().

$zobjnext(OREF)

Функция выполняет перечисление всех имеющихся в памяти экземпляров объектов всех классов, в том числе тех у которых счетчик пользовательских ссылок нулевой. Перечисление работает аналогично функции $o, и работает только в одном направлении, по возрастанию.

$zobjproperty(OREF,PropertyName,arglist)

Альтернативный способ обращения к свойству объекта. Функция допускает как правостороннее так и левостороннее использование. В качестве PropertyName указывается строка с именем свойства, arglist - переменное число параметров если свойство индексированное. Во избежание проблем в некоторых версиях Каше если требуется цепочечное обращение к объектным свойствам, например oref.Prop1.Prop2.Prop3, рекомендуется взять промежуточные oref в самостоятельные переменные или обратиться к документации на Вашу версию Каше.

$zobjstate(OREF)

Возвращает код состояния объекта на который указывает oref. Коды возврата означают:
-1 - это был объект, но сейчас он невалидный по каким-либо причинам
0 - это не объект и никогда им не был
1 - это объект и сейчас в корректном состоянии

$zobjval([oref],slot[,[ele][,[modflg][,[modbit][,subs]]]])

Думаю, что тут переводить на русский неоправданно, вот оригинальный текст:
Direct reference to the %obj local array and its private successor in Cache' 3.2.
For cache >=4.0 this storage is private.
For understanding (3.x obj implementation)
$li(%obj(oref,slot))=$zobjval(oref,slot)
$li(%obj(oref,slot),ele)=$zobjval(oref,slot,ele)
$li(%obj(oref,slot,s1,s2,s3),ele)=$zobjval(oref,slot,ele,,,s1,s2,s3)
oref - reference to object
slot - slot of property storage in memory
ele - list item in propetry slot (node)
if it is not present property occupies entire slot (node)

modflg modification strategy
0 - ignore modbit
1 - if modbit is non-zero, set modified bit 1 on any set
2 - if modbit is non-zero, set it on any set
3 - if modbit is non-zero, set it if the new value is not the same as the old value

modbit Modified bit (0-32767)

zobjclose oref

Я не знаю как точно перевести на русский, вот оригинальный текст:
Decrements the usage counter in the Process Class Table for the OREF's class. If this counter becomes zero, then the system-wide reference count in the corresponding CCB is also decremented. Команда есть далеко не во всех версиях Каше и специфична для версии реализации объектов.

zobjpurge

Команда закрывает все объекты открытые текущим процессом, которые в настоящий момент некорректны (invalid), то есть те для которых функция $zobjstate, будучи примененной, возвращает -1. Команда имеет только безаргументную форму.

$zobjincref(oref)

Увеличивает системный счетчик ссылок объекта на единицу. Возвращает, видимо, предыдущее значение.

$zobjdecref(oref)

Уменьшает системный счетчик ссылок объекта на единицу. Возвращает, видимо, предыдущее значение.

Функции $zobjincref и $zobjdecref следует использовать только в случае крайней необходимости и проведя всесторонние проверки такой необходимости, поскольку их неожиданное применение может привести к сбоям в работе объектов.

$zobjref(intvalue)

Преобразует целочисленный идентификатор объекта в памяти в объектную ссылку, возвращает oref. Для манипуляций с полученной объектной ссылкой рекомендуется взять ее в локальную переменную, одновременно это приводит к увеличению на единицу обоих счетчиков ссылок, пользовательского и системного.

Комментариев нет:

Отправить комментарий