ヘッダーをスキップ
Oracle® Coherence開発者ガイド
リリース3.7.1
B65026-01
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

19 Portable Object Formatの使用

Portable Object Format(POF)を使用すると、パフォーマンス上のメリットから言語の独自性にいたるまで幅広い利点を得ることができます。Coherenceで作業する際には、シリアライズ・ソリューションとしてPOFを詳細に検討することをお薦めします。.NET拡張クライアントを構築する際のPOFの操作方法の詳細は、『Oracle Coherenceクライアント・ガイド』の「.NETクライアントの統合オブジェクトの構築」を参照してください。C++拡張クライアントを構築する際のPOFの操作方法の詳細は、『Oracle Coherenceクライアント・ガイド』の「C++クライアントの統合オブジェクトの構築」を参照してください。

この章は次の各項で構成されています。

19.1 POFシリアライズの概要

シリアライズとは、オブジェクトをバイナリ形式にエンコードするプロセスです。これは、Coherenceを使用してデータをネットワーク上で移動させることが必要になった場合に重要となる機能です。Portable Object Format(POF)は言語に依存しないバイナリ形式です。POFは領域と時間の両面で効率を向上させるように設計されており、Coherenceの使用時に不可欠なものとなっています。POFバイナリ・ストリームの詳細は、付録E「PIF-POFバイナリ形式」を参照してください。

シリアライズで使用可能なオプションには、標準Javaシリアライズ、POF、独自のカスタム・シリアライズ・ルーチンなどいくつかあります。各オプションには、それぞれトレードオフがあります。標準Javaシリアライズは簡単に実装可能であり、循環オブジェクト・グラフをサポートし、オブジェクトIDを保持します。ただし、比較的動作が低速で、冗長なバイナリ形式が使用され、Javaオブジェクトのみが処理対象となります。

Portable Object Formatには次のようなメリットがあります。

19.2 オブジェクトをシリアライズするためのPOF APIの使用方法

POFには、オブジェクトのシリアライズおよびデシリアライズの方法を認識するシリアライズ・ルーチンの実装が必要です。オブジェクトのシリアライズには、com.tangosol.io.pof.PortableObjectインタフェースとcom.tangosol.io.pof.PofSerializerインタフェースという2つのインタフェースが使用可能です。POFは、PortableObjectまたはPofSerializerインタフェースを実装せずにシリアライズを自動的に実装する注釈もサポートしています。詳細は、「オブジェクトをシリアライズするためのPOF注釈の使用方法」を参照してください。

この項の内容は次のとおりです。

19.2.1 PortableObjectインタフェースの実装

PortableObjectインタフェースは、次の2つのメソッドで構成されるインタフェースです。

  • public void readExternal(PofReader reader)

  • public void writeExternal(PofWriter writer)

POFストリームに対する書込みまたは読取りを行う各要素に数値を指定することで、POF要素に索引が付けられます。索引はPOFストリームにおいて書込みと読取りが実行される各要素に対して一意である必要があります。索引はスーパー・クラスと派生クラスの間で一意である必要があるため、派生タイプが存在する場合には特に注意が必要です。次の例では、PortableObjectインタフェースの実装を示します。

public void readExternal(PofReader in) 
   throws IOException 
   {
   m_symbol    = (Symbol) in.readObject(0);
   m_ldtPlaced = in.readLong(1);
   m_fClosed   = in.readBoolean(2);
   }
 
public void writeExternal(PofWriter out) 
   throws IOException 
   {
   out.writeObject(0, m_symbol);
   out.writeLong(1, m_ldtPlaced);
   out.writeBoolean(2, m_fClosed);
   }

19.2.2 PofSerializerインタフェースの実装

PofSerializerインタフェースには、シリアライズ・ロジックをシリアライズするクラスから外部化する手段が用意されています。これは、CoherenceでPOFを使用する場合に、クラスの構造を変更したくないときには特に役立ちます。PofSerializerインタフェースは、次の2つのメソッドで構成されています。

  • public Object deserialize(PofReader in)

  • public void serialize(PofWriter out, Object o)

PortableObjectインタフェース同様、POFストリームに対して書込みまたは読取りが実行される要素はすべて一意に索引付けされている必要があります。PofSerializerインタフェースの実装例を、次に示します。

例19-1 PofSerializerインタフェースの実装

public Object deserialize(PofReader in) 
   throws IOException 
   {
   Symbol symbol    = (Symbol)in.readObject(0);
   long   ldtPlaced = in.readLong(1);
   bool   fClosed   = in.readBoolean(2);
   
   // mark that reading the object is done
   in.readRemainder(null);
 
   return new Trade(symbol, ldtPlaced, fClosed);
   }
 
public void serialize(PofWriter out, Object o) 
   throws IOException 
   {
   Trade trade = (Trade) o;
   out.writeObject(0, trade.getSymbol());
   out.writeLong(1, trade.getTimePlaced());
   out.writeBoolean(2, trade.isClosed());
    
   // mark that writing the object is done
   out.writeRemainder(null);
   }

19.2.3 POF索引の割当てのガイドライン

POFの索引をオブジェクトの属性に割り当てるときには、次のガイドラインに従ってください。

  • 読取りと書込みの順序: シリアライズ・ルーチンの最低索引値から開始して、最高索引値で終了します。値をデシリアライズする場合には、書込みと同じ順序で読取りを実行します。

  • 非連続の索引を指定することはできますが、読取りまたは書込みが連続して実行される必要があります。

  • サブクラス作成時に索引の範囲を予約する場合: 索引は派生タイプ間で累積されます。そのため、各派生タイプがそのスーパークラスで予約されたPOF索引範囲を認識する必要があります。

  • 索引を他の目的に使用しない: 進化をサポートするためには、クラス・リビジョン全体で属性の索引を他の目的に使用しないようにすることが必須です。

  • ラベルの索引: public static final intでラベル付けされている索引は、さらに簡単に使用できます。特に、POFエクストラクタとPOFアップデータを使用する場合には簡単です。「POFエクストラクタとPOFアップデータの使用方法」を参照してください。ラベル付けされた索引の読取りおよび書込みも、上述の説明と同じ順序で実行される必要があります。

19.2.4 POFオブジェクト参照の使用方法

POFは、POFストリーム内で複数回出現するオブジェクトに対するオブジェクトIDおよび参照の使用をサポートします。オブジェクトにはIDのラベルが付けられ、同じPOFストリーム内の2回目以降に出現するラベル付きオブジェクトのインスタンスはそのIDで参照されます。オブジェクト参照は、ユーザー定義のオブジェクト・タイプに対してのみサポートされています。

参照を使用すると、同じオブジェクトを複数回エンコードしないで済み、データ・サイズの削減に役立ちます。参照は通常、かなりサイズが大きい多数のオブジェクトが複数回作成される場合、またはネストされたデータ構造か循環データ構造をオブジェクトが使用する場合に使用されます。ただし、大量のデータを含むが繰り返しはほとんどないアプリケーションの場合、オブジェクトIDおよび参照の追跡で発生するオーバーヘッドが原因で、オブジェクト参照の使用により得られる利点はわずかなものになります。

この項の内容は次のとおりです。

19.2.4.1 POFオブジェクト参照の有効化

オブジェクト参照は、デフォルトでは有効になっておらず、pof-config.xml構成ファイル内で有効にするか、またはSimplePofContextクラスの使用時にプログラムによって有効にする必要があります。

POF構成ファイルでオブジェクト参照を有効にするには、<pof-config>要素内に<enable-references>要素を含めて、値をtrueに設定します。例:

<?xml version='1.0'?>

<pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config
   coherence-pof-config.xsd">
   ...
   <enable-references>true</enable-references>
</pof-config>

SimplePofContextクラスの使用時にオブジェクト参照を有効にするには、プロパティをtrueに設定してsetReferenceEnabledメソッドをコールします。例:

SimplePofContext ctx = new SimplePofContext();
ctx.setReferenceEnabled(true);

注意:

参照をサポートしていないPOFコンテキストで書き出されたオブジェクトは、参照をサポートしているPOFコンテキストで読み取ることはできません。この逆も当てはまります。

19.2.4.2 循環オブジェクトおよびネストされたオブジェクトのためのPOFオブジェクトIDの登録

循環オブジェクトまたはネストされたオブジェクトは、オブジェクトの作成時に手動でIDを登録する必要があります。そうしないと、親オブジェクトを参照する子オブジェクトは、参照マップ内で親のIDを見つけることができません。オブジェクトIDは、com.tangosol.io.pof.PofReader.registerIdentityメソッドを使用して、デシリアライズ・ルーチン中にシリアライザから登録できます。

次の例は、循環参照を含む2つのオブジェクト(CustomerProduct)、およびCustomerオブジェクトのIDを登録するシリアライザの実装を示しています。

Customerオブジェクトの定義は次のとおりです。

public class Customer
   {
      private String m_sName;
      private Product m_product;
 
   public Customer(String sName)
      {
      m_sName = sName;
      }
 
   public Customer(String sName, Product product)
      {
      m_sName = sName;
      m_product = product;
      }

   public String getName()
      {
      return m_sName;
      }

   public Product getProduct()
      {
      return m_product;
      }
 
   public void setProduct(Product product)
      {
      m_product = product;
      }
   }

Productオブジェクトの定義は次のとおりです。

public class Product
   {
      private Customer m_customer;
 
   public Product(Customer customer)
      {
      m_customer = customer;
      }
 
   public Customer getCustomer()
      {
      return m_customer;
      }
   }

シリアライザの実装は、デシリアライズ中にIDを登録します。定義は次のとおりです。

public class CustomerSerializer implements PofSerializer
   {
   @Override
   public void serialize(PofWriter pofWriter, Object o) throws IOException
   {
      Customer customer = (Customer) o;
      pofWriter.writeString(0, customer.getName());
      pofWriter.writeObject(1, customer.getProduct());
      pofWriter.writeRemainder(null);
   }
 
   @Override
   public Object deserialize(PofReader pofReader) throws IOException
      {
         String sName = pofReader.readString(0);
         Customer customer = new Customer(sName);

         pofReader.registerIdentity(customer);
         customer.setProduct((Product) pofReader.readObject(1));
         pofReader.readRemainder();
         return customer;
      }
   }

19.2.5 POFオブジェクトの登録

Coherenceには、com.tangosol.io.pof.ConfigurablePofContextシリアライザ・クラスが用意されていて、それによりPOFのシリアライズ・オブジェクトが適切なシリアライズ・ルーチン(PofSerializer実装、またはPortableObjectインタフェースを介した呼び出しによる)にマップされます。

クラスにシリアライズ・ルーチンが指定されると、そのクラスはpof-config.xml構成ファイルを使用してConfigurablePofContextクラスに登録されます。POF構成ファイルには<user-type-list要素があり、それにはPortableObjectを実装するクラスまたはそれらに関連付けられているPofSerializerを持つクラスのリストが記載されています。各クラスに対する<type-idは一意である必要があり、すべてのクラスタ・インスタンス(拡張クライアントを含む)で一致している必要があります。POFの構成要素の詳細は、付録D「POFユーザー定義型の構成要素」を参照してください。

POF構成ファイルの例を次に示します。

<?xml version='1.0'?>

<pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config
   coherence-pof-config.xsd">
   <user-type-list>
      <include>coherence-pof-config.xml</include>

      <!-- User types must be above 1000 -->
      <user-type>
         <type-id>1001</type-id>
         <class-name>com.examples.MyTrade</class-name>
         <serializer>
            <class-name>com.examples.MyTradeSerializer</class-name>
         </serializer>
      </user-type>
 
      <user-type>
        <type-id>1002</type-id>
        <class-name>com.examples.MyPortableTrade</class-name>
      </user-type>
   </user-type-list>
</pof-config>

注意:

Coherenceでは、最初の1000個のtype-idは内部使用のために予約されています。上の例に示されているように、<user-type-list>にはcoherence.jarファイルのルートにあるcoherence-pof-config.xmlファイルが含まれます。このリストにはCoherence固有のユーザー型が定義されており、それらのユーザー型はすべてのPOF構成ファイルに含まれている必要があります。

19.2.6 ConfigurablePofContextクラスを使用するためのCoherenceの構成

CoherenceでConfigurablePofContextシリアライザ・クラスを使用する場合には、必要な精度のレベルに基づいた、次の3通りの構成が可能です。

  • サービスごと: 各サービスには、ConfigurablePofContextシリアライザ・クラスの完全な構成が用意されており、オペレーション構成ファイルにある事前定義済の構成が参照されます。

  • すべてのサービス: すべてのサービスでグローバルConfigurablePofContextシリアライザ・クラスの構成が使用されます。独自の構成を提供するサービスによってグローバルな構成がオーバーライドされます。グローバル構成を完全構成にして、オペレーション構成ファイルに含まれる事前定義済の構成を参照することも可能です。

  • JVM: ConfigurablePofContextシリアライザ・クラスはJVM全体に対して有効化されます。

19.2.6.1 ConfigurablePofContextクラスのサービスごとの構成

ConfigurablePofContextクラスを使用するようにサービスを構成するには、キャッシュ構成ファイルのキャッシュ・スキームに<serializer>要素を追加します。<serializer>要素の完全なリファレンスは、「serializer」を参照してください。

次の例では、ConfigurablePofContextクラスを使用するように構成された分散キャッシュを示しており、カスタムPOF構成ファイルを定義しています。

 <distributed-scheme>
   <scheme-name>example-distributed</scheme-name>
   <service-name>DistributedCache</service-name>
   <serializer>
      <instance>
         <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
         <init-params>
            <init-param>
               <param-type>String</param-type>
               <param-value>my-pof-config.xml</param-value>
            </init-param>
         </init-params>
      </instance>
   </serializer>
</distributed-scheme>

次の例では、オペレーション構成ファイルのデフォルトの定義を参照します。デフォルトのConfigurablePofContextシリアライザ定義を確認するには、「serializer」を参照してください。

 <distributed-scheme>
    <scheme-name>example-distributed</scheme-name>
    <service-name>DistributedCache</service-name>
    <serializer>pof</serializer>
 </distributed-scheme>

19.2.6.2 すべてのサービスに対するConfigurablePofContextクラスの構成

ConfigurablePofContextクラスをすべてのサービスに対してグローバルに構成するには、キャッシュ構成ファイルの<defaults>要素内に<serializer>要素を追加します。次の例は両方とも、シリアライザをすべてのキャッシュ・スキームの定義に対してグローバルに構成するものであり、個々のキャッシュ・スキームの定義内にその他の構成を追加する必要はありません。<defaults>要素の完全なリファレンスは、「defaults」を参照してください。

次の例では、ConfigurablePofContextクラスに対するグローバルな構成を示しており、カスタムPOF構成ファイルを定義しています。

<?xml version='1.0'?>

<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config
   coherence-cache-config.xsd">
   <defaults>
      <serializer>
         <instance>
            <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
            <init-params>
               <init-param>
                  <param-type>String</param-type>
                  <param-value>my-pof-config.xml</param-value>
               </init-param>
            </init-params>
         </instance>
      </serializer>
   </defaults>
   ...

次の例では、オペレーション構成ファイルのデフォルトの定義を参照します。デフォルトのConfigurablePofContextシリアライザ定義を確認するには、「serializer」を参照してください。

<?xml version='1.0'?>

<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config
   coherence-cache-config.xsd">
   <defaults>
      <serializer>pof</serializer>
   </defaults>
   ...

19.2.6.3 JVMに対するConfigurablePofContextクラスの構成

次のシステム・プロパティを使用して、POFを使用するようにJVMインスタンス全体を構成できます。

  • tangosol.pof.enabled=true: JVMインスタンス全体でPOFを有効化します。

  • tangosol.pof.config=CONFIG_FILE_PATH: 使用するPOF構成ファイルへのパスです。このファイルがクラスパスにない場合には、ファイル・リソースとして存在するはずです(例: file:///opt/home/coherence/mycustom-pof-config.xml)。

19.3 オブジェクトをシリアライズするためのPOF注釈の使用方法

POF注釈は、オブジェクトに対するシリアライズおよびデシリアライズ・ルーチンを自動的に実装する方法を提供します。POF注釈は、PofSerializerインタフェースの実装であるPofAnnotationSerializerクラスを使用して、シリアライズおよびデシリアライズされます。注釈は、PortableObjectおよびPofSerializerインタフェースの使用に代わる手段を提供し、オブジェクトをシリアライズ可能なものにするために必要な時間とコードを削減します。

この項の内容は次のとおりです。

19.3.1 POFシリアライズのためのオブジェクトの注釈付け

クラスとそのプロパティがPOFシリアライズ可能であることを示すには、次の2つの注釈を使用できます。

  • @Portable – クラスをPOFシリアライズ可能としてマークします。注釈は、クラス・レベルでのみ許可され、メンバーを持ちません。

  • @PortableProperty – メンバー変数またはメソッド・アクセッサをPOFシリアライズ可能属性としてマークします。注釈付きのメソッドは、アクセッサの表記法(getsetis)に従う必要があります。メンバーを使用して、POF索引だけでなく、シリアライズまたはデシリアライズの前後に実行されるカスタム・コーディックを指定できます。索引値を省略し、自動的に割り当てることができます。カスタム・コーディックが入力されない場合は、デフォルトのコーディックが使用されます。

次の例では、クラス、メソッドおよびプロパティの注釈付け、およびプロパティの索引値の明示的な割当てを示します。POF索引付けの詳細は、「POF索引の割当てのガイドライン」を参照してください。

@Portable
public class Person
   {
   @PortableProperty(0)
   public String getFirstName()
      {
      return m_firstName;
      }
 
   private String m_firstName;

   @PortableProperty(1)
   private String m_lastName;

   @PortableProperty(2)
   private int m_age;
}

19.3.2 POF注釈付きオブジェクトの登録

POF注釈付きオブジェクトは、pof-config.xmlファイルの<user-type>要素内に登録されている必要があります。POFの構成要素の詳細は、付録D「POFユーザー定義型の構成要素」を参照してください。POF注釈付きオブジェクトは、オブジェクトがPortableObjectを実装しておらず、Portableとして注釈が付けられている場合は、PofAnnotationSerializerシリアライザを使用します。ただし、オブジェクトに注釈が付けられており、ユーザー定義型の定義に含める必要がない場合は、自動的にシリアライザが使用されます。次の例では、注釈付きのPersonオブジェクトに対するユーザー定義型を登録します。

<?xml version='1.0'?>

<pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config
   coherence-pof-config.xsd">
   <user-type-list>
      <include>coherence-pof-config.xml</include>

      <!-- User types must be above 1000 -->
      <user-type>
         <type-id>1001</type-id>
         <class-name>com.examples.Person</class-name>
      </user-type>
</pof-config>

19.3.3 自動索引付けの有効化

POF注釈は、索引値を明示的に割り当てて管理する必要性を軽減する自動索引付けをサポートしています。@PortableProperty注釈を定義するときはいつでも、索引値を省略できます。明示的な索引値を割り当てるプロパティには、自動索引値は割り当てられません。自動索引のアルゴリズムは、次のようなものです。

名前 明示的な索引 決定された索引
c 1 1
a 省略 0
b 省略 2


注意:

自動索引付けは現在、Evolvableクラスをサポートしていません。

自動索引付けを有効にするには、POF構成ファイルでオブジェクトをユーザー定義型として登録するときに、PofAnnotationSerializerシリアライザ・クラスを明示的に定義する必要があります。コンストラクタ内のfAutoIndexブール・パラメータは、自動索引付けを有効にするもので、trueに設定する必要があります。例:

<user-type>
   <type-id>1001</type-id>
   <class-name>com.examples.Person</class-name>
   <serializer>
      <class-name>com.tangosol.io.pof.PofAnnotationSerializer</class-name>
         <init-params>
         <init-param>
            <param-type>int</param-type>
            <param-value>{type-id}</param-value>
         </init-param>
         <init-param>
            <param-type>class</param-type>
            <param-value>{class}</param-value>
         </init-param>
         <init-param>
            <param-type>boolean</param-type>
            <param-value>true</param-value>
         </init-param>
      </init-params>
   </serializer>
</user-type>

19.3.4 カスタム・コーディックの提供

コーディックにより、シリアライズまたはデシリアライズの前後にコードを実行できます。コーディックでは、PofWriterおよびPofReaderインタフェースを使用して、ポータブル・プロパティをエンコードおよびデコードする方法を定義します。コーディックは通常、デシリアライズの際に失われる可能性がある具体的な実装に対して、またはオブジェクトのシリアライズの前にPofWriterインタフェースで特定のメソッドを明示的にコールするために使用されます。

コーディックを作成するには、com.tangosol.io.pof.reflect.Codecインタフェースを実装するクラスを作成します。次の例では、リンクされているリスト・タイプの具体的な実装を定義するコーディックを示します。

public static class LinkedListCodec implements Codec
   {
   public Object decode(PofReader in, int index) throws IOException
      {
      return (List<String>) in.readCollection(index, new LinkedList<String>());
      }
   public void encode(PofWriter out, int index, Object value) throws IOException
      {
      out.writeCollection(index, (Collection) value);
      {
   }

プロパティにコーディックを割り当てるには、コーディックを@PortableProperty注釈のメンバーとして入力します。コーディックが指定されない場合、デフォルトのコーディック(DefaultCodec)が使用されます。次の例では、上記のLinkedListCodecコーディックの割当てを示します。

@PortableProperty(codec = LinkedListCodec.class)
private List<String> m_aliases;

19.4 POFエクストラクタとPOFアップデータの使用方法

Coherenceでは、ValueExtractorインスタンスとValueUpdaterインスタンスを使用して、キャッシュに格納されたオブジェクトの値が抽出および更新されます。PofExtractorインスタンスとPofUpdaterインスタンスは、POFの索引付けされた状態を利用して、シリアライズ・ルーチンまたはデシリアライズ・ルーチン全体を実行せずにオブジェクトを抽出または更新します。

PofExtractorPofUpdaterにより、Coherenceの非プリミティブ・タイプを使用するときの柔軟性が向上します。多くの拡張クライアントの場合、グリッド内に対応するJavaクラスは不要です。POFエクストラクタとPOFアップデータはバイナリをナビゲートできるため、キーと値全体をObjec形式にデシリアライズしなくても済みます。これは、索引付けする値をPOFエクストラクタを使用してプルするだけで索引付けできることを意味します。ただし、キャッシュ・ストアを使用している場合は、対応するJavaクラスが必要です。この場合、キーと値のデシリアライズ・バージョンがキャッシュ・ストアに渡され、バックエンドに書き込まれます。

19.4.1 POFオブジェクトの移動

POFは索引付けされているため、バイナリを抽出用または更新用の特定の要素まで迅速に横断できます。POF値オブジェクトを横断し、目的のPOF値オブジェクトを返すのは、PofNavigatorインタフェースの役目です。Coherenceには、出荷状態で、整数索引に基づいてPOF値を移動できるSimplePofPathクラスが用意されています。最も簡単な形式では、抽出または更新する属性の索引を提供します。次の例を参照してください。

public class Contact
        implements PortableObject
    {
    ...
    // ----- PortableObject interface ---------------------------------------
 
    /**
    * {@inheritDoc}
    */
    public void readExternal(PofReader reader)
            throws IOException
        {
        m_sFirstName     = reader.readString(FIRSTNAME);
        m_sLastName      = reader.readString(LASTNAME);
        m_addrHome       = (Address) reader.readObject(HOME_ADDRESS);
        m_addrWork       = (Address) reader.readObject(WORK_ADDRESS);
        m_mapPhoneNumber = reader.readMap(PHONE_NUMBERS, null);
        }
 
    /**
    * {@inheritDoc}
    */
    public void writeExternal(PofWriter writer)
            throws IOException
        {
        writer.writeString(FIRSTNAME, m_sFirstName);
        writer.writeString(LASTNAME, m_sLastName);
        writer.writeObject(HOME_ADDRESS, m_addrHome);
        writer.writeObject(WORK_ADDRESS, m_addrWork);
        writer.writeMap(PHONE_NUMBERS, m_mapPhoneNumber);
        }
 
    ....
 
    // ----- constants -------------------------------------------------------
 
    /**
    * The POF index for the FirstName property
    */
    public static final int FIRSTNAME = 0;
 
    /**
    * The POF index for the LastName property
    */
    public static final int LASTNAME = 1;
 
    /**
    * The POF index for the HomeAddress property
    */
    public static final int HOME_ADDRESS = 2;
 
    /**
    * The POF index for the WorkAddress property
    */
    public static final int WORK_ADDRESS = 3;
 
    /**
    * The POF index for the PhoneNumbers property
    */
    public static final int PHONE_NUMBERS = 4;
 
    ...
}

POFストリームへの書込みまたはPOFストリームからの書込みを実行中の各データ・メンバーに対する定数が存在することに注意してください。この方法に従えば、POFエクストラクタとPOFアップデータを容易に使用できてシリアライズ・ルーチンの書込みも簡素化されるという、優れた利点が得られます。各索引にラベルを付けることで、索引の操作はさらに容易になります。前述のように、最も簡単な場合では、WORK_ADDRESS索引を使用して連絡先から勤務先のアドレスを抽出できます。SimplePofPathにより、intsArrayを使用してPofValuesを横断できるようになります。たとえば、勤務先のアドレスの郵便番号を取得するには、[WORK_ADDRESS, ZIP]を使用します。次の例で、詳細を示します。

19.4.2 POFエクストラクタの使用方法

POFエクストラクタは通常、キャッシュに問い合せる場合に使用され、問合せのパフォーマンスを向上させます。たとえば、上記で示したクラスを使用して、姓がJonesであるすべての連絡先のキャッシュに問い合せる場合、問合せは次のとおりです。

ValueExtractor veName = new PofExtractor(String.class, Contact.LASTNAME);
Filter         filter = new EqualsFilter(veName, "Jones");
 
// find all entries that have a last name of Jones
Set setEntries = cache.entrySet(filter);

この例では、PofExtractorには便利なコンストラクタがあり、SimplePofPathを使用して1つの索引(この例ではContact.LASTNAMEの索引)を取得します。地域コードが01803であるすべての連絡先を検索する場合、問合せは次のとおりです。

ValueExtractor veZip = new PofExtractor(
   String.class, new SimplePofPath(new int[] {Contact.WORK_ADDRESS, Address.ZIP}));
 
Filter filter = new EqualsFilter(veZip, "01803");
 
// find all entries that have a work address in the 01803 zip code
Set setEntries  = cache.entrySet(filter);

前述の例では、PofExtractorコンストラクタには抽出された値またはnullのクラスを持つ最初の引数があります。型情報を渡すのは、POFがシリアライズされた値で圧縮形式を使用するからです(使用可能な場合)。たとえば、一部の数値は、型が値を暗示する特殊なPOF固有型として示されています。その結果、POFの値を受け取る側では、その型を暗黙的に認識できることが必要になります。PofExtractorは、コンストラクタで提供されたクラスを型情報のソースとして使用します。このクラスがnullの場合、PofExtractorはシリアライズされた状態から型を推測しますが、抽出される型は予想した型と異なることがあります。実際には、String型はPOFストリームから適切に推測されるので、前述の例ではnullを使用すれば十分です。ただし、通常はnullを使用しないでください。

19.4.3 POFアップデータの使用方法

POFアップデータは、オブジェクトの値を抽出するのではなく、更新するという点を除いて、POFエクストラクタと同じ方法で動作します。姓がJonesであるすべてのエントリをSmithに変更するには、次のようにUpdaterProcessorクラスを使用します。

ValueExtractor veName  = new PofExtractor(String.class, Contact.LASTNAME);
Filter         filter  = new EqualsFilter(veName, "Jones");
ValueUpdater   updater = new PofUpdater(Contact.LASTNAME);

// find all Contacts with the last name Jones and change them to have the last
// name "Smith"

cache.invokeAll(filter, new UpdaterProcessor(updater, "Smith"));

注意:

この機能は、これらの例ではStringベースの値で動作していますが、POFのエンコードされた値でも動作します。