3os

Объектная система 3OS

(версия от 29.12.2003)

Содержание

Основы

Способ хранить информацию на файловой системе (любой – не важно какой) в виде отдельных, сгруппированных файлов уже так давно используется в операционных системах, что стал совершенно естественным и очевидным. Но, так как в 3OS мы манипулируем объектами, а между свойствами объекта и файла лежит огромная пропасть, то совершенно очевидно, что стандартные файловые системы нам не подходят, и мы решили выработать свою собственную файловую систему наподобие объектной базы данных.

Итак, основой операционной системы 3OS является объект. Все что мы можем адресовать в системе (т.е. определить уникальным именем) является объектом. Объектами могут быть данные (или их отдельные составляющие), процессы (исполняемый код), указатели, устройства, пользователи, приложения и многие другие сущности. С точки зрения самой операционной системы объект – это любая сущность, имеющая в системе 3OS свое уникальное имя. Объекты не находятся в системе в неупорядоченном виде, они могут быть сгруппированы по классам (видам), связям, местоположению и любым описанным в объекте признакам. Замете, что возможностей для группировки объектов стало намного больше, чем для файлов в предметно-иерархических файловых системах, где мы могли группировать файлы только по каталогам и именам (в таких системах некоторые программы имеют дополнительные способы группировки, например FAR на временных панелях, но это уже идет как “навесок” к основной ФС).

Отдельным видом объектов являются контейнеры. Контейнер - это объект, который может содержать в себе любые другие объекты. Наиболее близкими к контейнеру понятиями в предметно-иерархических файловых системах являются архивы и каталоги (при этом заметим, что архив не является частью такой ФС, а формируется и обрабатывается сторонними приложениями). Доступ к объекту внутри контейнера осуществляется просто указанием имени требуемого объекта. Для пользователя работа с объектами внутри контейнера совершенно прозрачна, при этом контейнер сам являться самостоятельным объектом, с которым можно делать все, что душе угодно. Так же совершенно естественно наличие внутри контейнеров других объектов-контейнеров, т.е. можно говорить об уровнях вложенности расположения объекта. Уровень вложенности может быть выражен в виде целого числа и показывает насколько глубоко расположен адресуемый объект в цепочке контейнеров относительно текущего положения, либо относительно корня именования объектов в системе 3OS. Уровень вложенности число не всегда положительное и может указывать не только в прямом (“в глубь”) направлении, но и в отрицательном состоянии – обратно (“наружу”). Если мы используем уровень вложенности для определения положения относительно другого объекта, то нужно обратить внимание на то, что уровень вложенности применим только для объектов, находящихся на одной ветви дерева контейнеров. Для ясности мы можем рассмотреть следующий рисунок:

Относительно корня объектной системы: Сам корень - 0-й уровень вложенности; Объекты OBJ1 и OBJ2 – 1-й уровень; Остальные объекты находятся на 2-ом уровне вложенности.

Мы не можем с помощью уровня вложенности, например, определить положение object_2 относительно OBJ2, т.к. они находятся на разных ветвях и указав уровень (+1) мы попадем на объекты object_3 и object_4. Отсюда следует, что уровень вложенности может служить указателем только в пределах области видимости имен для данной ветви контейнеров.

Область видимости имен, определенная для корня объектно-информационной системы, включает в себя имена всех адресуемых в 3OS объектов.

Мы уже несколько раз употребили в тексте понятие корня именования объектов или по другому - корня объектной системы – точки от которой ведется именование (адресация) всех объектов. В именах объектов корень обозначен символом “/” (прямой слеш) в первой позиции имени объекта (Очень похоже на корень ФС в Unix).

Кроме стандартных или назначенных пользователем свойств, объектам присуща такая вещь как логические связи. Связи бывают различных типов с совершенно разными свойствами, кроме того, пользователь волен сам определять новые свойства для связей. В 3OS применяются следующие виды связей: “простой указатель”, “часть целого”, “прямое взаимодействие”. Связи, определенные для объекта, могут указывать сразу на несколько объектов (модель “один ко многому”).

Связь “часть целого”, указывает, что данный объект является одной из составляющих частей другого глобального объекта. “Часть целого” указывает на некий виртуальный объект, который присутствует в системе лишь как описание совокупности нескольких малых объектов, и описан лишь своим именем. Например: объекты A и B имеют зарегистрированные связи “часть целого” на объект C. Кроме того, что мы можем обращаться к отдельным объектам A и B, мы можем производить манипуляции сразу с объектом C или с объектами C/A и C/B. Отметим, что контейнеры не используют таких связей, т.к. нахождение объекта в контейнере очевидно и не нуждается в подобном описании.

Зачем вообще нужны связи? Дело в том, что самой 3OS “связи” как таковые не нужны, но я считаю, что мы должны иметь возможность с помощью нашей объектной системы описать полноценную объектную БД, с возможностями динамического моделирования (что бы не использовать в системе «навески» в виде сторонних баз данных), и взаимодействия объектов, а это без объявлений связей попросту невозможно.

Рассмотрим еще один тип связей – “прямое взаимодействие”. Описав такую связь, мы можем задать зависимость параметров одного объекта относительно другого. Например, мы можем описать такую связь как условие: “если object1.a > 10, то object2.s = (object1.b * 10)”.

Пользователь может сам создавать новые классы связей. Например, при описании некоторой инженерной конструкции, он может задать всем объектам связи (указывающие на последовательность крепления объектов), а в качестве параметров связей указать координаты мест и способ крепления. При этом взаимодействие объектов (давление, внутренние напряжения и т.д.) можно так же описать с помощью связей. Поместим все это в отдельный объект–контейнер и получим готовый проект, выраженный отдельным объектом, который можно копировать, отправить по сети, и вообще делать с ним все что угодно.

Работа со связями очень проста и чем-то напоминает работу с объектами. Кстати, пора бы нам вернуться и к самим объектам, мы ведь еще не узнали, как именуются и адресуются объекты в системе.

Область имен объектной системы 3OS. Именование объектов

Область имен операционной системы 3OS полностью совпадает с областью видимости имен для корня объектной системы. Т.е. в область имен попадают все без исключения доступные объекты.

Каждый объект в 3OS имеет свое собственное имя. На физическом уровне имя объекта представляет из себя unicode-строку, которая может содержать в себе любые символы, кроме стандартных управляющих (перевод строки, табуляция, возврат каретки и т.д), а так же символа “слэш”. Для совместимости с именованием в иерархических ФС, имена объектов допускают наличие символов точки, а для разделения имени объекта и его свойств и методов используется двойной слэш “//”.

Длина имени объекта не может превышать 1000 символов. На физическом уровне имя объекта терминируется 32-х битным символом “0” (0x00000000).

Символ “/” является разделителем между именами контейнеров и объектов. Пример именования объекта: /OBJECTS/OBJ5

Из примера видно, что имя объекта очень похоже на имя файла в стандартной ФС, но для нас оно не типично, т.к. мы по возможности избегаем использования контейнеров, стараясь обходиться безо всякой иерархии.

Ведь действительно, для того, что бы адресовать объекты, имеющие отношение к сети, совершенно не обязательно предварительно запихивать их в контейнер “/NET/”, они и так имеют все необходимые признаки. Из этого следует очень важный вывод, мы сделали шаг от иерархической модели хранения информации к реляционной, точно так же как в свое время это сделали все базы данных.

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

Типы объектов

С точки зрения пользователя все объекты делятся на исполняемые (программы), объекты-данные и объекты-идентификаторы. Все объекты жестко подчиняются стандартам, выработанным для каждого отдельного типа.

Исполняемые объекты – не обязательно несущее в себе скомпилированный код, мы можем исполнять любые скрипты и макросы, на любом из установленных в системе интерпретируемых языков программирования. Отличаются от остальных объектов наличием:

Объекты-данные – имеют всего лишь один обязательный признак данных. Структура объекта данных описана классом объекта. Под данные так же попадают и контейнеры.

Объекты-идентификаторы – объекты, которые обозначают некоторые сущности, отраженные на файловую систему в виде имени, так же имеют свойства и вызываемые методы, описываемые их классом. К объектам идентификаторам относятся: процессы, устройства, именованные каналы, пользователи, а так же все внешние (по отношению к локальной ОС) объекты (компьютеры в сети, службы сервисов и т.д.)

Работа с данными. Кодеки. Методы контейнеров (кодеки контейнеров)

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

Допустим, у нас есть объект picture, который является экземпляром класса BMP. Что бы работать с объектом сразу же на уровне предоставляемой им информации (поле параметров RGB, или они же цвета точек картинки), нам необходимо использовать соответствующий кодек, методы которого позволят работать сразу же с графической информацией заложенной в объекте.

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

Рассмотрим работу кодеков поподробнее:

Данные в объектной системе хранятся в виде объектов, т.е. для нас они представляются не как последовательность байт (в стандартных ФС), а в четко структурированном виде (структура объекта описана его классом). Получается что процесс (программа) может манипулировать конкретными элементами структуры объекта. Более того, мы можем манипулировать элементами данных, которые могут находиться внутри различных контейнеров (например, данные могут быть заархивированы).

Для того, что бы процесс (программа) получал данные не в виде потока байт, а в виде структурированных типов данных, в объектной системе реализован механизм кодеков (модель “объект” --> “кодек” --> “приложение”).

Как же это работает? Каждый класс данных в системе 3OS имеет набор методов, которые выделены в отдельный объект, называемый кодек. Т.е. мы можем иметь множество объектов типа jpg-изображение, но JPG-кодек в данном случае будет один.

Разовьем наш пример дальше. Пусть наше приложение действительно хочет получить данные от объекта класса JPGImage в формате, готовом к употреблению. А сам JPGImage находится внутри контейнера, объекты в котором заархивированы архиватором arch.

  1. Процесс открывает именованный канал (типа stream) ( что-то вроде open (StreamName, /archive/pic.jpg); ).
  2. Объектная система обращается сначала к объекту archive и загружает соответствующий кодек, связывая его с каналом StreamName.
  3. Кодек архива (точно так же как наше приложение) открывает входящий (для себя) канал и через объектную систему обращается к объекту pic.jpg. Система загружает соответствующий кодек (JPG).
  4. Кодек JPG так же открывает входящий канал, и т.к. именно непосредственно с ним связан конечный объект, этот же канал будет выходным каналом для самой объектной системы.
  5. На этом шаге у нас самоорганизовалась цепочка кодеков, через которую приложение работает с конкретным объектом.

Корень Объектной Системы как контейнер

Все объекты, которые мы можем адресовать, логически помещены внутрь простейшего контейнера, который и является, корнем файловой системы. Получается, что для работы нам необходим кодек данного контейнера, методы которого и есть API объектной системы.

Логически все объекты содержаться внутри корня объектной системы, физически же они могут быть расположены где угодно.

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

Отображение на объектную систему устройств, процессов и других “логических” объектов

Любой объект, существующий для системы 3OS, может быть отображен на объектную систему в виде имени. Таким объектом может быть процесс, сессия, устройство и многие другие объекты. Зачем это нужно? Когда в UNIX был реализован механизм отображения устройств на файловую систему, мы получили прекрасный механизм, который позволял управлять устройствами с помощью тех же самых функций, которые использовались для работы с файлами. Т.е. мы получили унифицированный интерфейс, состоящий из минимально необходимого набора вызовов.

В 3OS же, мы пошли еще дальше, установив один единый интерфейс для работы (управления) со всеми объектами в системе. Для этого каждый объект имеет свое собственное имя, к которому мы можем обратиться с помощью методов корня объектной системы. Система сама определит, с каким классом объектов ей приходится иметь дело, и вызовет соответствующий кодек.

Кодеки отображенных объектов могут так же содержать дополнительные (расширенные) методы, которые могут нам понадобится для работы с объектом.

Очень важно понимать, что изначально объекты отображаются в корень объектной системы, т.к. мы стараемся уйти от иерархического представления объектов. Конечно, мы можем выделить специальные контейнеры, для отображения объектов определенных классов, но это, как говориться, "не наш метод".

GUID и PUID – средства разрешения конфликтов

Что вообще-то не очень правильно. GUID – глобальный идентификатор, по которому система обращается к объекту. Почему не по имени? Дело в том, что объектная система 3OS подразумевает ситуацию, когда в системе может оказаться 2 объекта с одинаковыми именами (находящиеся на одном уровне вложенности), более того, это могут быть совершенно идентичные объекты. Такая ситуация может возникнуть при монтировании всех объектов в корень объектной системы.

Такая ситуация есть, и она несет в себе целый ряд проблем, начиная от безопасности системы и заканчивая автоматизацией работы с данными. И именно по этому для работы с объектами применяется вовсе не имя (хотя это частично сокрыто от пользователя).

Другая, не очевидная проблема состоит в том, что GUID, являясь уникальным не является статичным. Грубо говоря, если мы переносим файл на несколько компьютеров, то на каждом из них он получит, совершенно разный GUID. Так же, разные GUID’ы будет иметь общий для этих компьютеров объект. GUID может так же изменяться с течением времени (например при перемещении объекта).

Когда мы пишем программу, мы должны не забывать, что вместо нужного нам объекта, мы можем попасть на совершенно чужой объект. Поэтому каждая программа должна уметь “метить” свои объекты. Это достигается тем, что вводится еще один идентификатор – PUID, который точно может отнести объект к тому или иному приложению.

Конечно, мы можем не заморачиваться с PUID, а просто определить все рабочие объекты программы в отдельный контейнер, но при этом не стоит забывать, что изначально контейнеры не рассматриваются нами, как средство сортировки объектов.

На физическом уровне GUID – это номер записи в объектной системе, соответствующей конкретному объекту.

PUID – это номер, который получает каждое устанавливаемое в системе приложение. PUID обладает всеми свойствами и недостатками GUID’а. Но в отличие от GUID каждый объект может иметь несколько PUID’ов.

Количество возможных GUID и PUID определяется размерностью поля в соответствующих таблицах. Предполагается, что это будет 64-х битная величина.