OSMバイナリレコードの管理は地図アプリのパフォーマンスに大きな影響を与える。
低ズームでは、広域な地図データが必要となるため、予め、レコードの絞り込みや簡単化が必要となる。 現在は、低、中、高ズームに分割しているが、可能ならば、低、高ズーム分割としたい。
例えば、zoom 15以上では、zoom 13で分割されたバイナリレコードを使ってタイル画像をレンダリングする。 一つのバイナリレコードファイルには多数のレコードが含まれている。 このため、一つ一つのレコードを独立したオブジェクトとして管理すると、 オブジェクト管理に伴うオーバヘッドが強大となり、メモリ不足に陥る。 このため、ファイルをそのまま byte配列データとしてメモリに読込んでおく。 タイルのレンダリングに使われるレコードはごく一部となる。それらのレコードだけをオブジェクトとして取り出す。
OSMバイナリレコードは class Block で管理している。メンバーを下に示す。
現在は 40ブロックを配列で管理している。
広範囲な地図を見れば、ブロックの入れ替えが起きるが、日常の散歩などでは、 ブロックの入れ替えはほとんど起きない。一度読み込まれるだけ、入れ替えなしで終わる日が多いであろう。
入れ替えは、LRU方式である。すなわち、もっとも長時間利用されていないブロックが入れ替え候補となる。
レンダリングはマルチスレッドで行われるため、現時点で、何スレッドが利用中かを int ref_count で 管理している。全てのブロックが有効なとき、新しいブロックが要求された場合、 ref_count が 0 で、最終参照時間 time が最も小さい(古い)ものを廃棄して、ここに新ブロックを読み込む。
ファイルパス path は src、range、zoom、x、y から一意的に決まるものであり、必ずしも、 class Block のメンバーとする必要はない。
public class Block { static final int MaxBlocks = 40; static final Block[] blocks = new Block[MaxBlocks]; int ix; // Block番号 Tile.Source src; // japan、kanto Tile.Range range; // 低、中、高ズーム int zoom, x, y; // ブロック座標 String path; // ファイルパス int ref_count; // 参照スレッド数 long time; // 最終参照時間 byte[] vals; // OSMバイナリレコード(ファイル全体をbyte配列として読込んだもの) }
Map の onDraw でタイル(zoom, x, y)の要求が起きる。