2012-05-13 16 views
1

6時間ごとに更新されたこの風のデータにアクセスする必要があるC++プログラムがあります。サーバーのクライアントがデータを必要とすると、サーバーはデータベースに照会し、そのデータをクライアントに提供します。クライアントはlat、lon、およびmbをキーとして使用して5つの値を検索します。キャッシュされたデータ構造の設計

+------------+-------+-----+-----+----------+----------+-------+------+------+ 
| id   | lat | lon | mb | wind_dir | wind_spd | uv | vv | ts | 
+------------+-------+-----+-----+----------+----------+-------+------+------+ 
| 1769584117 | -90.0 | 0.0 | 100 |  125 |  9 | -3.74 | 2.62 | 2112 | 
| 1769584118 | -90.0 | 0.5 | 100 |  125 |  9 | -3.76 | 2.59 | 2112 | 
| 1769584119 | -90.0 | 1.0 | 100 |  124 |  9 | -3.78 | 2.56 | 2112 | 

データは非常にまれにしか変更されるため、クライアントが以前に照会データを必要とするので、もし、私はデータがサーバによってキャッシュされたいのですが、2番目のSQLクエリは必要ありません。

私はストレージ/スピードに関して最も効率的なインメモリのデータ構造を決定しようとしていますが、もっと重要なのはアクセスの容易さです。

私の最初の考えは、lonによってキーが付けられたマップを含んでいて、値がwind_dir、wind_speed、uv、vvおよびtsフィールドを含むマップであるmbによってキーされたマップを含んでいます。

しかし、それは速く複雑になります。もう1つの考えは、最後の5つのフィールドの構造体を含む3次元配列(lat、lon、mbインデックス)です。

私はここに座っているので、lat、lon、およびmbを文字列に組み合わせるという考えを思いつきました。これは、マップのインデックスとして使用できます。 lat、lon、およびmbは常に一意になります。

その他のアイデアは意味がありますか?

編集:データの面では

以下のコメントからのより多くの詳細、データセット内の3119040行があります。それはかなり一定ですが、新しい報告所が追加されるにつれてそれは徐々に成長するかもしれません。一般に、データを要求するクライアントは700〜1500人です。クライアントは飛行シミュレータです。可能な最大頻度は30秒ごとですが、デフォルトでは5分ごとにデータが要求されます。追加情報はありません。上に表示されているのは、返却したいデータです。

最後に私は言及を忘れていました。私はC++や特にSTLのものではかなり錆びています。

+0

地図地図はあまり複雑ではありません。一度それを定義すると、 'cache [lat] [lon] [mb]'があり、そこにデータを取得できます!それはまたかなり速いです。ハッシュマップと同じくらい高速ではありませんが、許容可能です。 – Shahbaz

+1

私は個人的にハッシュキーとして文字列の組み合わせを使用します。私はサーバーではなくクライアントでキャッシュします。 – Jake

+0

メモリマップされた[SQLite](http://www.sqlite.org/)ファイルに同じテーブル構造を保持することはどうですか? – Vikas

答えて

1

あなたは3つの部分キーと演算子よりも適し少ないとstd::mapを使用することができます(これはクレイジーエディは、コードのいくつかの行で拡張、提案されたものです)

struct key 
{ 
    double mLat; 
    double mLon; 
    double mMb; 
    key(double lat, double lon, double mb) : 
     mLat(lat), mLon(lon), mMb(mb) {} 
}; 

bool operator<(const key& a, const key& b) 
{ 
    return (a.lat < b.lat || 
      a.lat == b.lat && a.lon < b.lon || 
      a.lat == b.lat && a.lon == b.lon && a.mb < b.mb); 
} 

の定義やマップに挿入するには、次のようになります:

std::map<key, your_wind_struct> values; 
values[key(-90.0, 0.0, 100)] = your_wind_struct(1769584117, 125, ...); 
+0

マップの地図の地図はおそらく高速ルックアップを持っていますが、 – Shahbaz

+0

@Shahbaz:コードを修正していただきありがとうございます。どのバージョンがより速いのかわかりません。 [比較では、両方のキー(複数キーとネストマップ)のパフォーマンスはほぼ同等です](http://ideone.com/BA9OB)。 –

+0

これは@ Shahbazの提案に最も近いので、これを受け入れようとしており、サンプルコードを提供するために余分なクレジットがあります。 – wadesworld

0

ソートベクターも意味があります。 3つの部分キーを比較するより少ない述語をフィードすることができます。あなたは地図やセットで同じことをすることができます。ハッシュ...あなたが選んだコンテナの多くの要因に依存します。

0

もう1つのオプションは、赤い黒のツリーの代わりにハッシュテーブルを内部データ構造として使用し、O(1)とO(logn)の償却された検索時間を赤黒のために。どのデータ構造を使用するかは、問題のデータの特性(データの数、アクセス頻度など)によって決まります。私はいくつかのコメント者と合意しています。行く最善の方法。また、ユニークなキーが将来変更されるべきであるかどうかを簡単に変更することもできます。キー構造にメンバーを追加するだけで、まったく新しいレベルのマップを作成する必要はありません。

関連する問題