com.github.kyriosdata.adapter:oe-seed

Biblioteca serialização/desserialização de objetos do MR do openEHR.

License

License

Categories

Categories

Data
GroupId

GroupId

com.github.kyriosdata.adapter
ArtifactId

ArtifactId

oe-seed
Last Version

Last Version

1.0.0
Release Date

Release Date

Type

Type

jar
Description

Description

com.github.kyriosdata.adapter:oe-seed
Biblioteca serialização/desserialização de objetos do MR do openEHR.
Project URL

Project URL

https://github.com/kyriosdata/adapter
Project Organization

Project Organization

Instituto de Informática (UFG) - Fábrica de Software
Source Code Management

Source Code Management

https://github.com/kyriosdata/adapter

Download oe-seed

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.kyriosdata.adapter/oe-seed/ -->
<dependency>
    <groupId>com.github.kyriosdata.adapter</groupId>
    <artifactId>oe-seed</artifactId>
    <version>1.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.kyriosdata.adapter/oe-seed/
implementation 'com.github.kyriosdata.adapter:oe-seed:1.0.0'
// https://jarcasting.com/artifacts/com.github.kyriosdata.adapter/oe-seed/
implementation ("com.github.kyriosdata.adapter:oe-seed:1.0.0")
'com.github.kyriosdata.adapter:oe-seed:jar:1.0.0'
<dependency org="com.github.kyriosdata.adapter" name="oe-seed" rev="1.0.0">
  <artifact name="oe-seed" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.kyriosdata.adapter', module='oe-seed', version='1.0.0')
)
libraryDependencies += "com.github.kyriosdata.adapter" % "oe-seed" % "1.0.0"
[com.github.kyriosdata.adapter/oe-seed "1.0.0"]

Dependencies

compile (9)

Group / Artifact Type Version
com.github.kyriosdata.seed : seed jar 1.0.0
openehr » measure-serv jar 1.0.5
openehr » mini-termserv jar 1.0.5
openehr » openehr-rm-core jar 1.0.5
openehr » openehr-rm-domain jar 1.0.5
org.junit.jupiter : junit-jupiter-api jar 5.0.0-M2
org.junit.jupiter : junit-jupiter-engine jar 5.0.0-M2
org.junit.vintage : junit-vintage-engine jar 4.12.0-M2
org.apache.maven.plugins : maven-surefire-plugin jar 2.19.1

Project Modules

There are no modules declared in this project.

adapter

Adaptador do Modelo de Referência (MR) do openEHR para Seed.

Sonarqube Javadocs

Get more details at codescene.io.


Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.
Fábio Nogueira de Lucena - Fábrica de Software - Instituto de Informática (UFG).

Caso de uso

O Modelo de Referência (MR) do openEHR é um conjunto de classes que define os blocos básicos para empacotamento de informações em saúde. Quando essas informações precisam ser transferidas ou mesmo persitidas, existem várias possibilidades.

Como usar (via maven)?

Acrescente a dependência no arquivo pom.xml:

<dependency>
  <groupId>com.github.kyriosdata.adapter</groupId>
  <artifactId>oe-seed</artifactId>
  <version>1.0.0</version>
</dependency>

Documentação

Tipos (dos campos)

Os tipos contemplados seguem abaixo, identificados pelo correspondente tipo em Java.

  • Os tipos inteiros: BYTE (byte), SHORT (16 bits), INT (int) (32 bits), INT64 (long) (64 bits).
  • Os tipos em ponto flutuante: REAL (float) (32 bits), DOUBLE (double) (64 bits).
  • O tipo lógico: BOOLEAN (boolean).
  • O tipo que representa um caractere: CHAR (char).
  • O tipo sequência de caracteres: STRING (String).
  • O tipo vetor de bytes: VECTOR (byte[]).
  • O tipo intervalo: INTERVAL_INT, INTERVAL_INT64, INTERVAL_REAL, INTERVAL_DOUBLE. Cada um desses tipos é formado por quatro valores. Dois para os limites do intervalo, lower e upper, e outros dois lógicos, lowerIncluded e upperIncluded. Os tipos dos limites do intervalo são definidos pelo tipo do intervalo, por exemplo, INTERVAL_INT faz uso de dois inteiros, enquanto INTERVAL_DOUBLE faz uso de dois valores do tipo ponto-flutuante de precisão dupla.
  • O tipo lista: LIST (List). Uma lista é uma coleção de itens, não necessariamente únicos, mas em uma ordem.
  • O tipo conjunto: SET (Set). É uma coleção de itens únicos, não podem existir repetições, não há ordem entre eles.
  • O tipo dicionário: HASH (Hash). É um dicionário ou mapa, ou seja, uma coleção de valores, cada um deles disponível e associado a uma dada chave.

Tamanho de um registro

Um registro é uma combinação de campos. O tamanho de um registro, portanto, depende da quantidade de bytes necessária para armazenar cada um dos campos do registro. Se um registro é formado exclusivamente por campos de tamanho fixo, então o registro possui tamanho fixo. Caso contrário, o tamanho do registro varia. Ou seja, no pode ser definido antecipadamente e, é único por registro. Por exemplo, o formato de registro definido por uma única STRING que deve registrar um logradouro pode ter o tamanho 30 em um exemplo e 50 em outro. Se inclui uma lista, pode ter 0 elementos em um caso e 20 em outro.

Representação (serialização) de um registro

Um registro é formado por um header seguido dos dados correspondentes aos tipos dos campos do registro, conforme ilustrado abaixo.

+-----------------+
|      RECORD     |
+-----------------+
| Header | Fields |
+-----------------+
Representação dos dados de um registro

Abaixo segue a ilustração de um registro, sem o detalhamento do header. Esse registro reúne um campo inteiro e duas sequências de caracteres. Ou seja, os campos são dos tipos INT, STRING e STRING. O valor do INT é 23 (faz uso de 4 bytes); a primeira STRING apenas 4 bytes ("nome") e a segunda STRING ocupa outros 7 bytes ("contato"). A primeira linha contendo números abaixo indica os deslocamentos do início de cada campo com base na posição inicial (0). Ou seja, o inteiro faz uso dos bytes de 0 a 3 (inclusive), o "nome" ocupa os quatro bytes seguintes de 4 a 7 (inclusive) e, por último, "contato" faz uso dos bytes de 8 a 14 (inclusive). O décimo quinto byte está além do registro. Nesse arranjo observe que o tipo de tamanho fixo (INT) segue antes dos demais, ou seja, aquele de tamanho fixo segue antes daqueles de tamanho variável.

+------------------------------+
| HEADER |       FIELDS        |
+------------------------------+
---------|0---|4-----|8--------|15
+------------------------------+
| HEADER | 23 | nome | contato |
+------------------------------+
Representação do header de um registro

O header obrigatoriamente identifica, em seu primeiro byte, o tipo do registro. Observe que não é o formato propriamente dito, mas um identificador que permite localizar o formato empregado pelo registro. Dado que um único byte é empregado, tem-se um limite natural para os possíveis formatos (tipos) de registros.

Em geral o tipo de um registro inclui campos de tamanho variável. Nesses caso, o header deve conter várias informações:

  • Tipo, que identifica unicamente o formato do registro.
  • Tamanho do registro. Permite rapidamente "saltar" para o próximo registro. Observe que esse valor pode ser "recuperado" a partir do percurso do conteúdo do registro.
  • Apontadores. Após campos de tamanho fixo, que não dependem de apontadores, segue o primeiro campo de tamanho variável que também não depende de apontador. Contudo, após o primeiro campo de tamanho variável, todos os demais dependem de "saltar" sobre o conteúdo dos dados para serem localizados ou de apontadores, que não dependem desse percurso. Imagine por exemplo uma STRING. Segundo o tipo de registro ilustrado anteriormente, para o acesso à segunda STRING estão disponíveis duas estratégias: (a) localiza-se o término da STRING anterior (sabe-se que a seguinte é iniciada no byte seguinte) e (b) um apontador no header pode indicar diretamente o início da segunda STRING.

Abaixo é ilustrada a composição do header, conforme comentada acima, onde o tipo de um byte precede o tamanho do registro, 4 bytes, que são seguidos, possivelmente, de apontadores, cada um deles de 4 bytes. Observe que abaixo o valor A identifica o total de apontadores.

+-----------------------------------+
|             HEADER                |
+-----------------------------------|
|0-----|1--------|5-----------------| 4*A + 5
+-----------------------------------+
| Tipo | Tamanho |   Apontadores    |
+-----------------------------------+

Abaixo segue ilustração do registro exemplo apresentado anteriormente, agora acrescida do header. Suponha que o tipo de valor 54 identifica unicamente o formato desse registro, ou seja, a sequência formada por um INT, uma STRING e outra STRING.

+-----------------------------------+
|   HEADER    |      FIELDS         |
+-----------------------------------+
--------------|0---|4-----|8--------|15
+-----------------------------------+
| 54 | 15 | 8 | 23 | nome | contato |
+-----------------------------------+

Interpretação de cada um dos valores acima:

  • Primeiro segue o tipo do registro, valor 54 (suposição estabelecida acima).
  • O tipo é seguido do tamanho do registro, 15 bytes de dados. Esse tamanho não é o tamanho total do registro, pois não inclui os bytes empregados pelo header, mas apenas aqueles que dizem respeito aos dados propriamente ditos (ou payload).
  • O último valor do header é 8, a posição inicial do campo "contato". Observe que ao manter os campos de tamanho fixo no início, em ordem bem definida, não é necessário indicar a posição deles, nem do primeiro de tamanho variável, nesse caso "nome". Ou seja, para um registro do tipo 54 é suficiente armazenar a posição de início do último campo, posição 8.

Decisões

  • Campos de tamanho fixo precedem todos os campos de tamanho variável.
  • Valor de posição no header é relativa à posição inicial (0) dos dados, imediatamente após o header.

O registro representado na ilustração acima fornece o comportamento geral. Contudo, há situações especiais que demandam alteração na representação tanto do header quanto do dados. Contudo, isso é melhor compreendido após a introdução de outras questões: (a) blocos e (b) fragmentação de registros.

Blocos (elemento de divisão de um arquivo)

Uma base de dados é armazenada em um arquivo didivido em blocos de tamanho fixo. O tamanho padrão é 4KB. O acesso ao conteúdo da base de dados significa que esses blocos precisam ser transferidos para a memória RAM. No sentido inverso, atualizações precisam ser depositadas no bloco correspondente no arquivo em questão.

Fragmentação de registro

Dado que apenas parte da informação de uma base de dados se encontra em RAM, ou seja, apenas alguns blocos, e que um bloco possui tamanho fixo, enquanto os registros não, é natural que a divisão em blocos "fragmente" um registro no sentido em que parte das informações podem estar no final de um bloco e as demais a partir do bloco seguinte. De fato, um registro pode estar "espalhado" por vários blocos. Em particular, um único campo pode estar espalhado por vários blocos.

Decisão

  • Dados de um registro podem estar espalhados por vários blocos consecutivos (contíguos).

Abaixo é ilustrado o cenário onde o registro está disposto em dois blocos, sem perda de generalidade, assuma que são os blocos 6 e 7. Nessa ilustração, a STRING "contato" é dividida em "cont" (bloco 6) e "ato" (bloco 7).

------------ Bloco 6 -----------||----------- Bloco 7 ------------
--------------|0---|4-----|8----||----|15
+-------------------------------------+
| 54 | 15 | 8 | 23 | nome | cont||ato |
+-------------------------------------+

A estratégia acima tem como ponto positivo maximizar o uso de cada byte de um bloco, onde cada byte é utilizado. Por outro lado, deve-se definir como tratar campos "partidos" pela divisão dos dados em blocos. Para o registro de exemplo, apenas o tipo do registro (um único byte), necessariamente está em um único bloco. Para os demais valores, deve-se definir como identificar os "fragmentos" de um campo e montá-lo a partir de tais fragmentos. Noutras palavras, qualquer byte do 1 até o 24 pode ser a diviso de um bloco do seguinte.

+----|1 ----------------------------|24
| 54 | 15 | 8 | 23 | nome | contato |
+-----------------------------------+

Endereços

Um apontador indica o início de um campo relativo ao início dos dados do registro em questão. Ou seja, esse endereço não é o endereço do byte correspondente no arquivo onde é armazenado, também não coincide com o deslocamento referente ao bloco no qual se encontra.

Versions

Version
1.0.0