view renderingEngine.tex @ 32:8512227869d5

zemi
author tatsuki
date Tue, 29 Nov 2016 19:52:37 +0900
parents 4845a4f7b02a
children 388da5c83f48
line wrap: on
line source

\section{HTML Rendering Engine}
前章でJungle上にmaTrixを実装し、性能評価を行うことで、Jungleに実用データベースたる表現力、性能があることが確認できた。
本章ではにJungle上に例題アプリケーションとしてHTML Rendering Engineの開発を行い、その際に発生した問題、解法について解説する。
HtmlRenderingEngineは、出力するデータが記述されたContents Tree、出力する形式が記述されたLayout Treeの2つの木構造を持ち、これらを参照しながらhtmlのレンダリングを行う。
またレンダリングする例題は日記を選択した。

\subsection{Contents TreeのJungle上での表現}
RenderingEngineではContents Treeに図\ref{contentTree}のように出力するデータを格納した。

\begin{figure}[h]
\begin{center}
\includegraphics[height = 6cm , bb=0 0 830 643]{images/contentTree.pdf}
\caption{ContentTree}
\label{contentTree}
\end{center}
\end{figure}


RootNodeはContentのtitle、日時、Renderingする時に参照するLayout名を持つ。
そして子ノードがContentsの本文等のデータを持つ。
表\ref{NodeAttribute}にNodeが保持しているContentsの一覧を記述する。

\begin{table}[htb]
  \begin{center}
    \caption{ノードが保持しているContents一覧}
    \begin{tabular}{|c|c|}        \hline
      属性名         & 属性値                             \\ \hline 
      title          & 日記のタイトル                      \\ \hline 
      date(rootNode) & 日記の日時                          \\ \hline 
      type           & そのノードが保持しているContextType  \\
                     & text(日記本文) or image(画像データ)  \\ \hline
      date(image)    & 画像の保存日時                       \\ \hline
      fileName       & 画像の名前                           \\ \hline
    \end{tabular}
    \label{NodeAttribute}
  \end{center}  
\end{table}

\subsection{Layout}
htmlの出力形式を定義するLayoutは、複数のComponentからなる。
表\ref{LayoutTreeTable}に、LayoutTreeの主要要素を記す。
Layout Treeには図\ref{layoutTree}のようにデータを格納した。
また、LayoutTreeはノード同士がNodeNameを用いて参照を行う。


\begin{figure}[hH]
\begin{center}
\includegraphics[height = 6cm , bb=0 0 913 768]{images/LayoutTree.pdf}
\caption{LayoutTree}
\label{layoutTree}
\end{center}
\end{figure}


\begin{table}[htbH]
\begin{center}
\caption{LayoutTreeの主要な要素}
\begin{tabular}{|l|l|}        \hline
属性名              & 属性値                     \\ \hline 
NodeName            &ノードの名前。 \\
                    &ノード同士の参照時に用いられる。\\ \hline
displayComponent    &参照するノードの名前。          \\
Name                &この属性名で取得できる値を持つ  \\
                    &NodeNameを持つノードを参照する。\\ \hline 
use                 &このノードが、どのContentsに \\
                    &対してのLayoutを持つかを。                \\
                    &記述するタグ。表\ref{tag}に\\
                    &タグとContentsの対応を記述する。\\ \hline
その他              &css等と同じ様な記述を行う。 \\
                    &例 属性名 font  \\
                    &   属性値 fontSize \\
                    &など                \\ \hline
\end{tabular}
\label{LayoutTreeTable}
\end{center}  
\end{table}


Layout Treeは、ルートノードに属性名 NodeName 属性値 displayinformation の値を持つ(図\ref{layoutTree}ではNode1が該当する)。
ルートノードは、子ノードに複数のComponentを保持する(図\ref{layoutTree}ではNode2、Node3がそれに該当する)。
Node2は、"use" = "image"のペアでタグを保持しているため、Contents Treeの日記の画像表示に対応する記述が行われている。
Node3は、"use" = "text"のペアでタグを保持しているため、Contents Treeの日記の本文に対応する記述が行われている。
表\ref{tag}にタグとContentsの対応を記述する。

\begin{table}[htb]
\begin{center}
\caption{tagとcontentsの対応}
\begin{tabular}{|c|c|}        \hline
tag   & content          \\ \hline 
image & 画像の表示       \\ \hline 
cals  & table            \\ \hline
date  & 日付の表示       \\ \hline
text  & 日記の本文       \\ \hline
title & 日記のタイトル   \\ \hline
\end{tabular}
\label{tag}
\end{center}  
\end{table}



layoutが複数のComponentを参照する際は図\ref{multiComponent}のような木構造を構築する(この木はLayoutTreeの一部であり、本来は参照先のノード等が存在している)。
\begin{figure}[h]
\begin{center}
\includegraphics[height = 8cm , bb=0 0 913 1105]{images/multiComponent.pdf}
\caption{複数のComponentを参照するLayout}
\label{multiComponent}
\end{center}
\end{figure}

図\ref{multiComponent}の例では、diaryMulti@componentはdiaryText@componentとdiaryImage@componentを参照している。

以下に図\ref{contentTree}のContentsTree、図\ref{multiComponent}のLayoutTreeの2つを使用した、レンダリングの流れを記述する。
\begin{enumerate}
\item ContentsTreeのルートノードは、属性名 component 属性値 Multi@Componentの組を持つ。よって今回はLayoutTreeの、NodeNameがMulti@Componentのノードに記述されたルールに則ってレンダリング。

\item ContentTreeは、属性名 component 属性値 Multi@Componentの組を持つノード、つまりNode2を参照する。

\item Node2はこれ以上データを持たないので、子ノードであるNode3、Node4に記述されているデータの参照を行う。

\item Node3は属性名 displayComponentName 属性名 dialyImage@Componentの組を持つため、NodeNameがdialyImage@Componentのノードを参照する。

\item レンダリングエンジンは、参照先のノードに記述されたルールに則ってHtmlを生成する。

\item Node3は、これ以上データを持たないため、次はNode4を参照する。

\item Node4は属性名 displayComponentName 属性名 dialyText@Componentの組を持つため、NodeNameがdialyText@Componentのノードを参照する。

\item レンダリングエンジンは、参照先のノードに記述されているルールに則ってhtmlを生成する。

\end{enumerate}

(4)、(7)で参照しているノードに関しては、図\ref{layoutTree}のNode2、Node3の様な記述が行われている。

\subsection{Layout Treeのデータ設計}
Jungleは汎用の木構造を持つので、データベースを特に設計しなくても、あるがままの形で格納することが可能である。
しかし、設計を行うことでより効率的に木構造を扱うことが可能になる。
図\ref{goodLayoutTree}、図\ref{badLayoutTree}は同じデータを格納した2つの木の一部である。

\begin{figure}[h]
\begin{center}
\includegraphics[height = 4cm , bb=0 0 356 276]{images/goodLayoutTree.pdf}
\caption{コードとギャップのないLayoutの格納方法}
\label{goodLayoutTree}
\end{center}
\end{figure}


\begin{figure}[h]
\begin{center}
\includegraphics[height = 8cm , bb=0 -100 714 665]{images/badLayoutTree.pdf}
\caption{コードとギャップのあるLayoutの格納方法}
\label{badLayoutTree}
\end{center}
\end{figure}


図\ref{goodLayoutTree}のTreeは、1つのNodeにRenderingに必要な値が全て格納されている。
そのため、Renderingを行う際、複数のNodeをまたぐ必要が無く、簡潔にコードを書くことができる。



一方、図\ref{badLayoutTree}のTreeはRenderingする際に必要な値が複数Nodeに分散されて保存されている。
そのため、全てのNodeを参照し、値を集める処理を行う必要があり、コードの可読性が下がり余計な処理も増えてしまった。


\subsection{性能評価}
本節では、図\ref{goodLayoutTree}の木と図\ref{badLayoutTree}を使った2つのRenderinEngineの性能測定を行い、木の構造が実行速度にどれだけ影響するかを確かめる。
測定は100000回のRenderingRequestを処理するまでの時間の比較で行う。

測定結果を表\ref{BenchMark}に記す。
これより、設計を行った木の方が高速にRenderingを行えている。

\begin{table}[htb]
\begin{center}
\caption{性能評価}
\begin{tabular}{|c|c|}        \hline
使用した木 & 処理時間   \\ \hline
設計を行った木   &     249s      \\ \hline
設計を行わなかった木 & 277s      \\ \hline
\end{tabular}
\label{BenchMark}
\end{center}
\end{table}

%\begin{figure}[h]
%\begin{flushleft}
%\includegraphics[height = 8cm , bb=150 0 792 612]{images/benchMarck.pdf}
%\caption{性能評価}
%\label{fig:BenchMark}
%\end{flushleft}
%\end{figure}

測定結果より、Jungleデータベースはデータの設計を行うこと無く格納可能だが、設計を行ったほうがプログラム内のデータ構造とギャップがなく、高速に動作するプログラムを簡潔に記述できるようになる。
測定結果より、1つのノードにデータを記述したほうが、ノードをたどる必要が無いので、プログラムは高速に動作する。
しかし、\ref{mulitLayoutTree}のように複数のノードを用いることで簡潔にコードを記述できる例もあるので、コードの簡潔さと速度を両立した設計を行う必要がある。