Skip to content

gmSCLongMemoryClass

The service class LongMemory manages long memory areas. In the area of information management program storage must be viewed as containing a wide variety of different structures, indexes, lists, fixed records, long unformatted records, etc.. In addition it may be purely memory bound or it may be stored in a persistent file system. The role of this class is to provide a single interface for storing and retrieving information. It is sufficiently robust to allow for the management of large files in the multiple gigabyte size range; while it is still efficient for use by purely memory bound applications.

Physically, a long memory storage area consists of a series or relatively large fixed sized blocks. The manner in which these blocks are created, maintained, and accessed is determined when the storage area is created. See the discussion within the LongMemory_Create method for a description of the different approaches used. Within these large fixed sized blocks there are four fundamentally different record types stored within the storage area:

  1. Control Tables — These are relatively short tables that are always stored entirely within a single block. The method LongMemory_Allocate is used to enter new control tables into the storage area.
  2. Data Tables — These are arbitrarily long vectors that may cross block boundaries, but whose entire expanse consists of a logically contiguous area. The method LongMemory_Expand is used to enter new data tables into the storage area.
  3. Blocked Tables — These are arbitrary collections of information that use entire storage blocks that need not be contiguous. The manner in which the blocks are used is dependent on the type of information collections. Most complex entities like indexes, storage based property sequences, short volatile records, etc. are blocked tables. The method LongMemory_EmptyBlock is used to allocate blocked tables in the storage area.
  4. Posting blocks — These are fixed sized linked smaller blocks used to contain posting, collections of integer value such as selection vectors, inverted indexes, and sorting control tables.

At a logical level the storage area is viewed as consisting of a simple sequence of words. In this implementation a word is a 32-bit signed integer. All information is stored on a word boundary and all offsets are expressed in terms of words.


Prototype

int* LongMemory_Access(void* This,int Offset,int Delta);

The LongMemory_Access method is the lowest level logical access method in the storage system. The caller specifies a word offset into the storage area that he wishes to access along with his intent to change it. This method returns a semipermanent pointer to that word in the storage area. This method has the logical view of the storage area — i.e., a long linear sequence of words numbered from zero. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the sequence number relative to zero of the word in the storage area that
the user wishes to access.
DeltaSpecifies, if nonzero, the callers intent to change the content of the word; else
he wishes only to read it.

If all goes well this method returns a semipermanent pointer to the word; else it takes a fatal error branch and does not return.


Prototype

int LongMemory_Allocate(void* This,int Size);

The LongMemory_Allocate method allocates a contiguous area of storage. Though normal “data” storage in the persistent storage area makes no assumptions about the occurrence of block boundaries, the basic entry tables around which the object identifiers and property vectors are built assume that they do not contain any internal boundaries. It is this assumption that makes it possible to use semipermanent pointers to access these areas. This method allocates a stretch of continuous storage in the storage area that does not cross a block boundary. Obviously the length of that area must be less than the pagesize being used in the underlying physical storage of the blocks. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
SizeSpecifies the size in words of the structure being allocated.

This method returns the actual starting offset in the persistent storage area of the allocated area.


Prototype

int LongMemory_AllocateBytes(void* This,int Size);

The LongMemory_AllocateBytes method allocates sufficient storage to accommodate a specified number of bytes that crosses no block boundaries. The storage starts on a word boundary. Though normal “data” storage in the persistent storage area makes no assumptions about the occurrence of block boundaries, the basic entry tables around which the object identifiers and property vectors are built assume that they do not contain any internal boundaries. It is this assumption that makes it possible to use semipermanent pointers to access these areas. This method allocates a stretch of continuous storage in the storage area that does not cross a block boundary. Obviously the length of that area must be less than the pagesize being used in the underlying physical storage of the blocks. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
SizeSpecifies size in bytes of the structure being allocated.

This method returns the actual starting offset in the persistent storage area of the allocated area.


Prototype

void LongMemory_Close(void* This);

The LongMemory_Close method closes the specified storage area and returns all of its memory resources to the operating system. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. This must have been
obtained from a storage area creation or open method.

This method has no return value.


Prototype

void* LongMemory_Create(char* FileName,int PagingMethod,int PageSize,int MaximumPages,int MaximumBlocks);

The LongMemory_Create method creates a storage area. Once the information about how the blocks of the persistent storage area are to be managed in memory is known, this method creates that area along with the machinery needed to manage its fixed-sized blocks and block boundaries. Note that this is a very low level method. Typically the methods LongMemory_OpenArea or LongMemory_OpenRaw should be used, as these select the best approach to be used given the context of use. Its parameters are:

ParameterDescription
FileNameContains the name of the file to be used if the persistent storage area is to
reside within the file system of the host platform. Note that non-file resident
persistent areas must use a the memory mapped paging algorithm. This parameter
is NULL for non-file-based persistent storage areas.
PagingMethodSpecifies the paging algorithm to be used. One of the following constants
must be used: PagingType_BlockVector, PagingType_BlockSequence,
PagingType_SarchForBlock, PagingType_MemoryMapped, or
PagingType_MemorySequence.
PageSizeSpecifies the size of each page in the storage area. If set to zero, the value
PagingSystem_PageSize is used. Note this value is expressed in bytes not words.
MaximumPagesSpecifies the maximum number of pages in memory to be allocated for the storage
area.
MaximumBlocksspecifies the maximum number of blocks to be allocated for the storage area in
its file-based form.

If all goes well, this method returns the storage area handle to be used for the created area; else it returns NULL.


Prototype

void LongMemory_DeleteBlock(void* This,int BlockNumber);

The LongMemory_DeleteBlock method logically deletes a block from blocked-table storage. The block is not physically deleted, rather it is entered into the deleted block chain. From there it can be reused via the LongMemory_EmptyBlock or the LongMemory_Allocate methods. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
BlockNumbercontains the number of the block to be marked as being deleted.

This method has no return value.


Prototype

void LongMemory_DeleteRecord(void* This,int ioiad,int length);

The LongMemory_DeleteRecord method logically deletes a contiguous record from long memory. The record is not physically deleted, rather it is posted into a deleted record chain. From there it can be reused via the LongMemory_Allocate method. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
ioiadSpecifies the starting address of the record in the long memory area.
length Specifies the length of the contiguous area being deleted.

This method has no return value.


Prototype

int* LongMemory_EmptyBlock(void* This,int* BlockNumber);

The LongMemory_EmptyBlock method gets an empty block from a storage area. It is used whenever a block is needed by a blocked-table storage user. The block may be at the end of the storage area or it may be a block somewhere inside of the area that was marked as being deleted by the method LongMemory_DeleteBlock. To emphasize, blocks returned by this method are not guaranteed to be contiguous. If contiguous long storage is needed use the LongMemory_Expand method. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
BlockNumberreturns the block number of the empty block. It is this block number that is the
primary persistent retrieval value for the block in all future accesses.

If all goes well this method returns a semipermanent pointer to the start of the block; else it returns a NULL and stores a zero in the BlockNumber parameter.


Prototype

int LongMemory_Extend(void* This,int nWord);

The LongMemory_Extend method extends a storage area. Information can only be put or gotten from areas that have been previously allocated either via the LongMemory_Allocate or the LongMemory_Extend methods. This method extends the persistent storage area by the indicated number of words without regard to any block boundaries that might be spanned by the new area. This area then can be used for data storage but not for control tables and property vector storage. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
nWordSpecifies the number of words to extend the storage area by.

This method returns the actual offset in the persistent storage area of the start of the new area.


Prototype

int* LongMemory_GetBlock(void* This,int BlockNumber,int Delta);

The LongMemory_GetBlock method is the lowest level physical access method for the persistent storage area. The caller specifies a physical block number that he wishes to access along with his intent to change it. This method returns a semipermanent pointer to the start of the block in memory. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. This must have been
obtained from a storage area creation or open method.
BlockNumberSpecifies the number of the block to access.
DeltaSpecifies the callers intent to change the content of the block. If it is
nonzero, then the user intends to change the content of the block; else he will
only read it.

If all goes well this method returns a semipermanent pointer to the start of the block, else it takes a fatal error branch and does not return.


Prototype

int LongMemory_GetDeleted(void* This,int nAllocate);

The LongMemory_GetDeleted method determines if a deleted contiguous record exists that is at least a specified size long. If so it removes it from that deleted record chain and returns its offset in the long memory area. This method is used by the contiguous record allocation methods before they attempt to allocate new memory to satisfy a request. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. This must have been
obtained from a storage area creation or open method.
nAllocatespecifies the length of the desired allocation in words.

If a deleted segment is found that contains sufficient room to satisfy the request, then its offset in the long memory area is returned. Else a zero is returned.


Prototype

int LongMemory_GetNext(void* This);

The LongMemory_GetNext method supplies the retrieval offset associated with the next available word of long memory. The user may then begin writing to this storage. Note that the user is guaranteed that he can perform offset arithmetic with this retrieval value however, he is not guaranteed that the memory associated with these values is contiguous. Thus information may only be copied into (written) and copied from (read) the storage area. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.

This method returns the retrieval offset for the next available word of storage.


Prototype

int LongMemory_GetPageSize(void* This);

The LongMemory_GetPageSize method is for use by those storage applications that use their own internal block layouts. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.

This method returns the page size of the storage area.


Prototype

int LongMemory_GetPostingSize(void* This);

The LongMemory_GetPostingSize method returns the posting size of the storage area for use by those storage applications that use their own internal block layouts. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.

This method returns the posting size of the storage area.


Prototype

int LongMemory_HasChanged(void* This);

The LongMemory_HasChanged method specifies if any changes have been made to the storage area. If not, then the closing of various components can either be skipped or simplified. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.

If the storage area has not been changed, then a zero is returned. If it has been changed, then a nonzero value is returned.


Prototype

void* LongMemory_Open(char* FileName,int PagingMethod,int AccessType,int MaximumPages,int MaximumBlocks);

The LongMemory_Open method opens a storage area. Once the information about how the blocks of a previously created persistent storage area are to be managed in memory is known, this method opens that storage area and creates the machinery needed to manage its fixed-sized blocks and block boundaries. Note that this is a very low level method. Typically the method LongMemory_OpenArea or LongMemory_OpenRaw should be used, as these select the best approach to be used given the context of use. Its parameters are:

ParameterDescription
FileNameContains the name of the file used for the persistent storage area when it was
created.
PagingMethodSpecifies the paging algorithm to be used. One of the following constants must
be used: PagingType_BlockVector, PagingType_BlockSequence,
PagingType_SearchForBlock, PagingType_MemoryMapped, or
PagingType_MemorySequence.
AccessTypeSpecifies if access is be read-write, value is zero, or one if it is to be
readonly.
MaximumPagesSpecifies the maximum number of pages in memory to be allocated for the storage
area.
MaximumBlocksspecifies the maximum number of blocks to be allocated for the storage area in
its file-based form. If zero then the number of blocks currently on the file is
used.

If all goes well,this method returns the storage area handle to be used to reference the storage area. A NULL return value means that the file could not be opened.


Prototype

int* LongMemory_NewBlock(void* This);

The LongMemory_NewBlock method adds a new block to the back of the storage area. It is used in those cases where long sequential records are being added to the memory area which must span multiple sequential blocks. It is of course also used by the various allocation methods that require storage space when no deleted blocks are available. Its parameter is:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.

If no new blocks can be allocated to the long memory area then a NULL is returned; else a semipermanent pointer to the start of the block is returned.


Prototype

void* LongMemory_OpenArea(char* FileName,int Mode,int ReadOnly);

The LongMemory_OpenArea method creates or opens a long storage area. It selects the best paging method depending upon the context of use. Its parameters are as follows:

ParameterDescription
FileNameContains the name of the file used for the long storage area when it was created
or the name to be used if it is to be a new storage area.
ModeSpecifies the mode of the file and must be one of the following constants —
LongMemory_Open_Existing, LongMemory_Open_New, LongMemory_Open_Virtual, or
LongMemory_Open_Memory.
ReadOnlySpecifies the access type. It contains zero if access is the be read-write and
one if it is to be readonly.

If all goes well,this method returns the storage area handle to be used to reference the storage area else it returns a NULL.


Prototype

void* LongMemory_OpenRaw(char* FileName,int Mode,int ReadOnly);

The LongMemory_OpenRaw method creates or opens an existing storage area that has it own internal structure. No boot record is maintained and no deleted block or segment information is retained. The only methods that should be used with raw storage areas are: LongMemory_Access, LongMemory_Close, LongMemory_Read, LongMemory_Rewrite, or LongMemory_Write. Its parameters are:

ParameterDescription
FileNameContains the name of the file used for the persistent storage area when it was
created.
ModeSpecifies the mode of the file and must be one of the following constants — LongMemory_Open_Existing, LongMemory_Open_New, LongMemory_Open_Virtual, or LongMemory_Open_Memory.
ReadOnlySpecifies the access type. It contains zero if access is the be read-write and
one if it is to be readonly.

If all goes well this method returns the handle for the controlling storage structure; else it returns a NULL.


Prototype

void LongMemory_ReadBytes(void* This,int Offset,UBYTE* Bytes,int nByte);

The LongMemory_ReadBytes method reads bytes of information from persistent storage by copying them into a buffer supplied to this method. A byte-stream is retrieved using this method. Doing the copy ensures that the ultimate user of these bytes need not be concerned with boundary problems and need not be concerned over the duration of use of those values. This method has the logical view of the storage area — i.e., a long linear sequence of words numbered from zero. Its parameters are as follows:

ParameterDescription
ThisSpecifies the hhandle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the word offset of the start of the bytes to be read.
BytesReceives the bytes read.
nByteSpecifies the number of bytes to be read.


Prototype

void LongMemory_RewriteBytes(void* This,int Offset,UBYTE* Bytes,int nByte);

The LongMemory_RewriteBytes method rewrites bytes of information into persistent storage by copying them from a buffer supplied to this method. This method is used for storing byte-streams as opposed to word streams. Its parameters are as follows:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the word offset of the start of the bytes to be written.
BytesContains the bytes to be rewritten.
nByteSpecifies the number of bytes to be rewritten.


Prototype

void LongMemory_ZeroBytes(void* This,int Offset,int nByte);

The LongMemory_ZeroBytes method zeros bytes of information in persistent storage. This method is used for initializing byte-streams as opposed to word streams. Its parameters are:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the word offset of the start of the bytes to be zeroed.
nByteSpecifies the number of bytes to be zeroed.


Prototype

int LongMemory_WriteBytes(void* This,UBYTE* Bytes,int nByte,int nStart);

The LongMemory_WriteBytes method writes byte-stream information to the back of the storage area. Its parameters are as follows:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
BytesContains the bytes to be written.
nByteSpecifies the number of bytes to be written.
nStartSpecifies the number of bytes that must be written as part of a contiguous
block — i.e., without an intervening block boundary.

The return value from the method is the actual offset in persistent storage of the start of the new area. Note that the offset is word-oriented, not byte oriented.


Prototype

void LongMemory_Read(void* This,int Offset,int* Buffer,int nWord);

The LongMemory_Read method reads words of information from persistent storage by copying them into a buffer supplied to this method. Most “data” is retrieved using this method. Doing the copy ensures that the ultimate user of these words need not be concerned with boundary problems and need not be concerned over the duration of use of those values. This method has the logical view of the storage area — i.e., a long linear sequence of words numbered from zero. Its parameters are as follows:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the word offset of the start of the words to be read.
BufferReceives the words read.
nWordSpecifies the number of words to be read.


Prototype

void LongMemory_Rewrite(void* This,int Offset,int* Buffer,int nWord);

The LongMemory_Rewrite method rewrites words of information in persistent storage by copying them from a buffer supplied to this method. Most “data” is stored using this method. This is because the normal process of adding records to the back of storage involves extending it first and then doing a rewrite into the extension. Doing the copy ensures that the ultimate creator of these words need not be concerned with boundary problems. Its parameters are as follows:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
OffsetSpecifies the offset of the start of the words to be rewritten.
BufferContains the words being rewritten.
nWordSpecifies the number of words to be rewritten.


Prototype

int LongMemory_Write(void* This,int* Record,int nRecord);

The LongMemory_Write method writes words to back of a storage area. Its parameters are as follows:

ParameterDescription
ThisSpecifies the handle for the storage area control structure. It must have been
obtained from a storage area creation or open method.
RecordContains the words to be written.
nRecordSpecifies the number of words to be written.

The method returns the actual offset in storage of the start of the record. The record can be later read using this offset.