INTRODUZIONE
Xindice
Apache Xindice è un database progettato per memorizzare dati
in formato XML, o meglio un database nativo XML, ed è
sviluppato in Java.
Marco Buzzoni
INTRODUZIONE (1)
Il vantaggio di una soluzione nativa è che non occorre
preoccuparsi di mappare l'XML in qualche altra struttura dati.
I dati vengono inseriti e recuperati in formato XML. Si ha anche
molta flessibilità con la natura semi-strutturata di XML e il
modello indipendente di Xindice, e ciò si può riscontrare quando
si hanno strutture XML complesse che sarebbe difficile o
impossibile mappare in un singolo database.
LINGUAGGI SUPPORTATI
Al momento Xindice usa XPath come linguaggio per le query e
XUpdate per gli aggiornamenti, ovvero rende possibile la
modifica di dati in un documento XML.
ARCHITETTURA
Durante l'esecuzione, una istanza del programma deve
memorizzare un certo numero di dati:
● Gerarchia delle collezzioni
● Informazzioni sulla connessione del client
● Vari oggetti in cache
Una collezzione è un insieme di documenti XML e può contenere
a sua volta collezioni per formare una gerarchia.
La radice, chiamata anche Database, è speciale perchè:
● Non ha parenti
● Contiene solo collezioni figlie, non documenti XML
MEMORIZZAZIONE DEI DATI
I dati XML contenuti nei documenti XML di una collezione sono
memorizzati in un singolo file dati con estensione .tbl
(posizionato nella cartella delle collezioni da qualche parte nella
cartella radice del database).
Una classe speciale Java (chiamata filer) è responsabile di
leggere e scrivere i dati XML in questo file .tbl.
MEMORIZZAZIONE DEI DATI: PAGED FILES
Il paging fornisce un
accesso efficiente ad un
file ad accesso casuale
mappando parti del file
(pagine) nella memoria
principale. Le pagine
hanno lunghezza fissa.
Le dimensioni dell'header
e delle pagine possono
essere modificati nel
codice sorgente in:
org.apache.core.filer.Pag
e
MEMORIZZAZIONE DEI DATI: PAGED FILES HEADER
MEMORIZZAZIONE DEI DATI: PAGED FILES HEADER (1)
●
header size (2 bytes): 4096 (0x1000), la dimensione dell'header.
●
page size (4 bytes): set to 4096 (0x00001000), la dimensione di una pagina.
●
page count (8 bytes): questo campo non è più usato, è presente solo per ragioni
storiche.
●
total page count (8 bytes): numero totale di pagine presenti nel file.
●
first free page (8 bytes): numero della prima pagina non utilizzata nel file.
●
last free page (8 bytes): numero dell'ultima pagina non utilizzata nel file.
●
●
page header size (1 byte): dimensione di ogni page header. Il valore standard è
64 (0x40).
record count (8 bytes): numero di record memorizzati nel file.
MEMORIZZAZIONE DEI DATI: PAGINE E RECORDS
Se la lunghezza dei dati di un record sta nello spazio disponibile in una sola pagina, nessun
problema. Se invece il record è più grande di una pagina, si usano più pagine collegato tra
loro per contenerlo. I puntatori sono negli header delle pagine.
MEMORIZZAZIONE DEI DATI: PAGE HEADER
Ogni pagina ha un suo header la cui struttura è mostrata sopra.
●
●
●
●
●
●
status (1 byte): le pagine nel file sono usate o inutilizzate.
key length (2 bytes): le pagine hanno la possibilità di memorizzare una chiave. La
lunghezza massima della chiave è impostata a 256 (0x0100).
key hash (4 bytes): Quest camp memorizza un valore hash di 32 bit calcolato dalla
chiave, per ottimizzare le ricerche.
data len (4 bytes): La lunghezza dei dati nella pagina. Se una parte di essa continua in
un'altra pagina, questo compo contiene solo la lunghezza della parte di dati di questa
pagina.
record len (4 bytes): La lunghezza totale dei dati di cui una parte è memorizzata in questa
pagina.
next page (8 bytes): Il numero di pagina della pagina che contiene i dati seguenti del
record di questa pagina. Se questa è l'ultima pagina, il record contiene -1 (0xFFFFFFFF).
MEMORIZZAZIONE DEI DATI: B-TREE
Xindice implementa B-Trees usando i page file. Ogni nodo del
B-Tree è memorizzato in un record contenuto in una o più
pagine.
MEMORIZZAZIONE DEI DATI: B-TREE PAGED FILE HEADER
I 2 campi più significativi sono:
● root node page number (8 bytes): numero di pagina della radice del B-Tree.
● total bytes (8 bytes): la dimensione in byte del file che contiene i nodi del B-Tree e i record
dei dati.
MEMORIZZAZIONE DEI DATI: B-TREE PAGE HEADER
●
●
●
●
status (1 byte): questo campo è usato pper indicare se un record è:
o un record usato per memorizzare un nodo intermedio, allora lo stato è 0x01.
o un record usato per memorizzare un nodo foglia, allora lo stato è 0x02.
o un record usato per memorizzare i dati, allora lo stato è 0x14.
val_count (2 bytes): se il record è usato per memorizzare un nodo, questo record contiene
il numero di chiavi nel nodo..
created (8 bytes): se il record è usato per memorizzare dati, contiene la data(in formato
UNIX long) di memorzzazione.
modified (8 bytes): contiene la data dell'ultima modifica, sempre nel caso di
memorizzazione di dati.
MEMORIZZAZIONE DEI DATI: B-TREE NODE
Che si tratti di un nodo intermedio o di un nodo foglia, il nodo
viene memorizzato nel modo seguente:
● Le chiavi, che in Xindice sono stringhe utf-8, vengono
precedute da 2 byte ciascuna che contengono la lunghezza.
● Subito dopo ci sono i puntatori, che occupano 8 byte
ciascuno e sono scritti uno dopo l'altro.
XML STORAGE
Per ogni documento XML, Xindice calcola il DOM compresso.
Esso è un arrey di byte che può essere usato per ricostruire il
documento XML completo.
Un documento XML è memorizzato come coppia chiave-valore
nel B-Tree, dove la chiave è il nome del documento XML e il
valore è il DOM calcolato.
TAVOLA SIMBOLI
Una tavola simboli viene utilizzata per memorizzare i contenuti
XML in maniera efficiente. Essa è a sua volta un file XML che
associa un numero di 16 bit per ogni copia (Qname, namespace)
usata come elemento o attributo in XML per tutti i file in una
collezione.
TAVOLA SIMBOLI: ESEMPIO
Documento XML che sarà aggiunto ad una collezione Xindice:
<?xml version="1.0"?>
<p:person xmlns:p="http://www.xindice.org/Examples/PersonData"
gender="female"
xml:lang="fr">
<p:first-name>Susanne</p:first-name>
<p:last-name>Carpentier</p:last-name>
<p:e-mail active="yes">[email protected]</p:e-mail>
</p:person>
TAVOLA SIMBOLI: ESEMPIO (1)
Quando questo documento è immagazzinato in una collezione vuota, viene creata la seguente
tavola simboli:
<?xml version="1.0"?>
<?xindice-class org.apache.xindice.xml.SymbolTable?>
<symbols>
<symbol name="p:first-name"
nsuri="http://www.xindice.org/Examples/PersonData" id="4" />
<symbol name="p:e-mail" nsuri="http://www.xindice.org/Examples/PersonData"
id="6" />
<symbol name="p:last-name"
nsuri="http://www.xindice.org/Examples/PersonData" id="5" />
<symbol name="gender" id="2" />
<symbol name="xml:lang" id="3" />
<symbol name="p:person" nsuri="http://www.xindice.org/Examples/PersonData"
id="0" />
<symbol name="active" id="7" />
<symbol name="xmlns:p" nsuri="http://www.w3.org/2000/xmlns/" id="1" />
</symbols>
DOM COMPRESSO
Per generarlo Xindice scorre ricorsivamente il documento
costruendo una sequenza di byte per un particolare nodo nella
rappresentazione ad albero dell'XML. Questa contiene i dati per i
nodi figli, che a loro volta conterranno i dati per i relativi figli,
ecc....
QUERY
Il compito principale del query engine di Xindice è quello di
creare uno o più QueryResolver. Essi sono istanze di una classe
java che fornisce un'implementazione di tutte le funzionalità dei
linguaggi per query Xpath e Xupdate. L'interfaccia che viene
implementata dalle due classi per i linguaggi è situata in
org.apache.xindice.core.query.QueryResolver. Come utenti
noi potremmo creare altre implementazioni per supportare nuovi
linguaggi.
QUERY: XPATH
Quando una query deve essere valutata, viene scelto un insieme
di documenti candidati della collezione. Poi Xpath viene valutato
usando le classi Xalan (analizzatore e compilatore per Xpath)
con ognuno dei documenti a turno: il documento è caricato in un
albero DOM usando il le classi B-Tree filer, e Xpath è valutato
con questo albero DOM. I risultati di tutte le valutazioni sono
aggregati e restituiti.
QUERY: XPATH E SCELTA DEI DOCUMENTI CANDIDATI
Quando si esegue una query, è possibile specificare quali
documenti dovrebbero essere considerati. Se ciò avviene,
Xindice userà l'insieme dei candidati ed eseguirà la query su di
essi, spostandoli prima in memoria.
Se nessun insieme è specificato esplicitamente, Xindice proverà
a creare un appropriato indice basato sulla query, il quale fornirà
un insieme logico di documenti come candidati.
Se non trova neanche un indice appropriato, Xindice ricorre al
metodo “brute force”: valuta ogni documento della collezione,
leggendolo, convertendolo e cercando i risultati.
QUERY: XUPDATE
Le query di tipo Xupdate inviano istruzioni di aggiornamento a
Xindice. Questo tipo di query consiste in un documento XML che
può contenere un numero qualsiasi di istruzioni di update.
Come nel caso di Xpath, si ha un query resolver, che prima di
tutto compila le query poi può decidere se eseguirle in un
secondo momento oppure subito (metodo query())
Per convertire ed eseguire le istruzioni Xupdate, Xindice usa il
Lexus Engine.
QUERY: XUPDATE E LA SCELTA DEI DOCUMENTI DA AGGIORNARE
Nel caso la query sia sottomessa a uno specifico insieme di documenti, le
istruzioni di Xupdate sono eseguite su ognuno di essi.
Se non vengono specificati documenti, Xindice procede nel modo seguente:
● Per ogni istruzione di modifica, cerca l'espressione di selezione, che
conseste in una espressione Xpath per indicare quale nodo del
documento deve essere modificato.
● Poi una query Xpath viene eseguita su tutta la collezione, usando il
QueryResolver per trovare tutti i nodi che corrispondono alla query nei
documenti, e i documenti contenenti questi nodi vengono conservati.
Questo passaggio può fare uso di tutti gli indici impostati per Xpath, come
determinato nel comportamento della classe QueryResolver di Xpath.
● Le istruzioni di modifica XUpdate sono eseguite su tutti i documenti
conservati.
QUERY: XUPDATE E L'ESECUZIONE DEGLI AGGIORNAMENTI
L'insieme dei documenti è processato come segue:
● Per ogni documento viene creato un albero DOM in memoria
usando le classi DOM Compressor e B-Tree filer.
● Lexus aggiorna questa rappresentazione DOM secondo le
modifiche
● Xindice riscrive l'intero documento usando le stesse classi. La
data di modifica del documento è aggiornata.
QUERY: RISULTATI
Le query in Xindice restituiscono, sempre dei risultati, e le query
Xupdate restituiscono un risultato con una risorsa XML che
appare così:
<?xml version="1.0"?>
<src:modified
xmlns:src="http://xml.apache.org/xindice/Query">4</src:modified>
Essa indica essenzialmente il numero di aggiornamenti (in
questo caso 4) che la query ha eseguito.
RISORSE
Tutte le informazioni sono reperibili all'indirizzo:
http://xml.apache.org/xindice/dev/guide-internals.html