バナーをクリックすれば目次に戻ります

Copyright 1999 Rogue Wave Software
Copyright 1999 Sun Microsystems, Inc.


RWVirtualPageHeap

形式

#include <rw/vpage.h>
(抽象基底クラス)

説明

このクラスは、固定長ページから成る抽象ページヒープを表す抽象基底クラスです。ここでは、このクラスの特殊化クラスの動作モデルについて説明します。

メンバー関数 allocate() を呼び出して抽象ヒープからページを割り当てます。この関数は、RWHandle 型のオブジェクトであるメモリー "ハンドル" を返します。このハンドルは、論理的にページを表しています。

割り当てられたページを使用するためにはまず、ハンドルを引数としてメンバー関数 lock() を呼び出し、ページを "ロック" しなければなりません。ハンドルに対応するページをスワップインし、それを物理メモリーに持ち込むのに必要なすべての作業を行うのは、RWVirtualPageHeap の特殊化クラスです。実際のスワップ媒体は、ディスクや EMS/XMS メモリー、またはネットワーク上のどこかにあるマシンに設定できます。lock() は、メモリー上に存在するページへのポインタを返します。

一度ページをメモリーに取ると、ページに対して自由に処理を行えます。ただし、ページの内容を変えた場合は、メンバー関数 dirty() を呼び出してからページをアンロック (ロックを取り消すこと) しなければなりません。

ロックされたページはメモリーを使いきります。特殊化クラスによっては、スワップを行うだけの決まった数のバッファしか持っていないものもあります。ページを使用しないときは、unlock() を呼び出す必要があります。unlock() を呼び出した後は、lock() が返した元のアドレスはすでに無効になっています。ページをもう一度使用するためには、lock() で再びロックしなければなりません。

ページに対する処理をすべて終了したら、deallocate() を呼び出してページを抽象ヒープに返します。

実際、ロックやアンロック、避けられない型キャストの管理などは、厄介な作業かもしれません。メモリーを自動的にスワップインまたはスワップアウトするには通常、抽象ヒープを使用するよりもクラスを設計する方が簡単です。これは、型 T の要素からなる仮想配列を表現するクラス RWTValVirtualArray<T> が実行してくれます。型 T の要素は、アドレス指定されると必要に応じて自動的にスワップインされます。

持続性

なし

次の例は、N 個のノードをリンクリストに追加しています。このリンクリストでは、次のノードへの "ポインタ" の実体はハンドルです。

#include <rw/vpage.h>
struct Node {
  int  key;
  RWHandle  next;
};
RWHandle head = 0;
void addNodes(RWVirtualPageHeap& heap, unsigned N) {
  for (unsigned i=0; i<N; i++){
    RWHandle h = heap.allocate();
    Node* newNode = (Node*)heap.lock(h);
    newNode->key  = i;
    newNode->next = head;
    head = h;
    heap.dirty(h);
    heap.unlock(h);
  }
}

公開コンストラクタ

RWVirtualPageHeap(unsigned pgsize);

ページのサイズを設定します。

公開デストラクタ

virtual ~RWVirtualPageHeap();

特殊化クラスが割り当てられた資源を解放できるよう、このデストラクタは仮想になっています。

公開メンバー関数

unsigned
pageSize() const;

抽象ページヒープのページサイズを返します。

公開純粋仮想関数

virtual RWHandle
allocate() = 0

抽象ヒープからページを割り当て、そのページのハンドルを返します。特殊化クラスが割り当て要求を満足できなかったときは、値がゼロのハンドルを返します。

virtual void
deallocate(RWHandle h) = 0;

ハンドル h のページを解放します。値がゼロのハンドルのページを解放してもエラーにはなりません。

virtual void
dirty(RWHandle h) = 0;

前回ロックされた後、ハンドル h のページの内容が変更されていることを宣言します。この関数を呼び出す前にページをロックしなければなりません。

virtual void*
lock(RWHandle h) = 0;

ページをロックし、物理メモリーにスワップインして、そのアドレスを返します。特殊化クラスがロックできなかったときは、nil ポインタを返します。このポインタは、決まったページサイズのバッファを指しているものとみなされます。

virtual void
unlock(RWHandle h) = 0;

ページをアンロックします。この関数を呼び出す前に、ページをロックしなければなりません。関数呼び出し後、lock() が返したアドレスはすでに無効になっています。