ハッシュ マップを使用して結果をキャッシュすることを決定するのに時間がかかりすぎました。
私の戦略は、単一のハッシュマップを使用するのではなく、キャッシュの静的インスタンスを格納する単一の共通オブジェクト クラスを使用することでした。過剰なレベルのハッシュツリー分岐を含む単一のハッシュマップをロードする理由がわかりませんでした。
ハッシュ解決の量を減らす
扱っているオブジェクトが Employee、Address、Project であることがわかっている場合、3 つの静的ハッシュを作成します。
final static private Map<Long, Employee> employeeCache =
new HashMap<Long, Employee>();
final static private Map<Long, Address> addressCache =
new HashMap<Long, Address>();
final static private Map<String name, Project> projectCache =
new HashMap<String name, Project>();
public static void putEmployee(Long id, Employee emp){
employeeCache.put(id, emp);
}
public static Employee getEmployee(Long id){
return employeeCache.get(id);
}
public static void putEmployee(Long id, Address addr){
addressCache.put(id, addr);
}
public static Address getEmployee(Long id){
return addressCache.get(id);
}
public static void putProject(String name, Address addr){
projectCache.put(name, addr);
}
public static Address getProject(String name){
return projectCache.get(name);
}
すべてを 1 つのマップにまとめるのは大変です。データの効率的なアクセスと保存の原則は、データについて決定した情報が多ければ多いほど、その情報を使用してそのデータを分離して活用する必要があるということです。これにより、データへのアクセスに必要なハッシュ解決のレベルが低下します。実行する必要があるすべての危険で不明確な型キャストは言うまでもありません。
可能であればハッシュ化を避ける
CurrentEmployee と NextEmployee の値が常に 1 つだけであることがわかっている場合は、それらを Employee のハッシュに格納しないでください。静的インスタンスを作成するだけ
Employee CurrentEmployee, NextEmployee;
これにより、ハッシュ解決がまったく必要なくなります。
グローバル名前空間の汚染を避ける
また、可能であれば、それらを静的インスタンスではなくクラス インスタンスとして保持し、グローバル名前空間を汚染しないようにします。
グローバル名前空間の汚染を避けるのはなぜですか? なぜなら、複数のクラスが誤って同じ名前を使用して、グローバルな名前空間の混乱が原因で数え切れないほどのバグが発生するからです。
予想される場所または使用される場所に最も近いキャッシュを保持する
可能であれば、キャッシュが主に特定のクラス用である場合は、キャッシュをそのクラス内のクラス インスタンスとして保持します。また、別のクラスがそのキャッシュからデータを取得する必要があるまれなインスタンスにイベントバス イベントを提供します。
期待できるパターンになるように
ZZZManager.getZZZ(id);
可能であればキャッシュをファイナライズし、
それ以外の場合は、パターとゲッターを提供して民営化します。別のクラスが誤ってキャッシュを再インスタンス化することを許可しないでください。特に、ある日、クラスが一般的なユーティリティ ライブラリになる場合は注意してください。また、パターとゲッターは、キャッシュが処理できないキーまたは値をキャッシュに直接提示することにより、リクエストがキャッシュを一掃したり、アプリを例外にプッシュしたりすることを回避するために、リクエストを検証する機会があります。
これらの原則を Javascript ローカル ストレージに変換する
GWTページには
命名規則を適切に使用すると、ストレージ データの処理に役立ちます。たとえば、MyWebApp という名前の Web アプリでは、Stock という名前の UI テーブルの行に関連付けられたキー値データに、MyWebApp.Stock というプレフィックスが付いたキー名を付けることができます。
したがって、クラスの HashMap をかなり粗いコードで補足すると、
public class EmployeePresenter {
Storage empStore = Storage.getLocalStorageIfSupported();
HashMap<Long, Employee> employeeCache;
public EmployeePresenter(){
if (empStore==null) {
employeeCache = new HashMap<Employee>();
}
}
private String getPrefix(){
return this.getClass()+".Employee";
//return this.getClass().getCanonicalName()+".Employee";
}
public Employee putEmployee(Long id, Employee employee)
if (empStore==null) {
stockStore.setItem(getPrefix()+id, jsonEncode(employee));
return;
}
employeeCache.put(id, employee);
}
public Employee getEmployee(Long id)
if (empStore==null) {
return (Employee) jsonDecode(Employee.class, stockStore.getItem(getPrefix()+id));
}
return employeeCache(id);
}
}
localstore は文字列ベースのみであるため、独自の json エンコーダー デコーダーを作成すると想定しています。一方で、json をコールバックから受け取った瞬間にストアに直接書き込んでみませんか?
メモリの制約?
この質問の専門知識を公言することはできませんが、ハッシュマップの答えは、ブラウザーの OS によって制限される最大メモリであると予測しています。ブラウザー、プラグイン、JavaScript などのオーバーヘッドによって既に消費されているすべてのメモリを差し引いたものです。
HTML5ローカルストレージの場合、GWTページには次のように記載されています
「LocalStorage: ブラウザごとのアプリごとに 5MB。HTML5 仕様によると、この制限は必要に応じてユーザーが増やすことができます。ただし、これをサポートするブラウザはごくわずかです。」
「SessionStorage: システム メモリによってのみ制限されます」