Chapter 6: Vstr and List Classes

Both lists and vstrs provide variable length storage and can be attributes of persistent objects.

The C++/VERSANT vstr and list classes are:

Vstr<type>

Typed, variable length storage of elemental types.

VstrAny

Untyped, variable length storage of elemental types.

PList<type>

Typed, variable length storage of items.

PItem

Untyped list item.

 

 

Vstr<type> and VstrAny

Vstr Support of Standard Template Library

Standard Template Library algorithms can be used on instances of Vstr<type>. Please see the chapter "Standard Template Library" for further information.

 

Vstr Usage

The vstr classes provide variable length storage of elemental types. "Vstr" is pronounced "vee-stir" and means "variable storage."

The vstr classes are:

Vstr<type>

Typed, variable length storage.

VstrAny

Untyped, variable length storage.

 
Methods defined on Vstr<type> are also defined on VstrAny.

The vstr classes are used as building blocks for the VERSANT collection and string classes. You can use the vstr classes to build your own variable length arrays and collections. C++/VERSANT uses Vstr<type> extensively to pass arrays to and from methods.

The Vstr<type> and VstrAny classes implement many of the methods defined in the Standard Template Library. See the chapter "Standard Template Library" for more information.

Some Vstr<type> methods are:

Vstr<type>( o_u4b hint )

Constructor giving initial vstr size.

void add( const type& newelem )

Append a new element to the end of this vstr.

type& operator[]( o_u4b n )

Reference the n-th element of the vstr.

operator=( Vstr<type>& from )

Make the vstr point to the same array as another vstr.

void set( Vstr<type>& from )

Copy contents of the given vstr into this vstr, which allocates a new array.

o_bool is_empty()

Determine if the length of the vstr is zero.

o_u4b size()

Return the number of elements in the vstr.

void release()

Release the memory allocated for the vstr.

The Vstr<type> class does not derive from PObject, so it cannot be used as a stand-alone persistent class. If the parameter type for a Vstr<type> class is an elemental type, it can be used as an attribute of a persistent object.

If the parameter type for a Vstr<type> class is a class or struct, it cannot be used as an attribute of a persistent object, although instances can be used as transient objects.

For storage of objects rather than elemental values, use the LinkVstr<type> or LinkVstrAny classes which are built upon the Vstr<type> class.

To avoid making copies of data arrays, the assignment of vstrs and the copy constructor only copy a pointer to the vstr memory. To make a copy of the elements of a vstr, you must explicitly use the copy method set(). By contrast, the assignment of instances of collections does create a new instance.

When using a vstr as an attribute, you could check to see whether the containing object is persistent and then, only for persistent objects, define the vstr copy constructor to make a copy of the contents using the set() method. A better approach is always to copy the contents rather than having different conventions for transient versus persistent objects.

Some vstr constructors do not allocate memory. To use a vstr, you can create an empty vstr and then add elements with append(). If a vstr is empty at the time of a commit, then it is deleted.

Vstr destructors do not release the dynamic memory allocated by the constructor. You must explicitly release vstr memory with the release() method.

The size of a vstr is part of the persistent state of an object and is the number of elements that will be saved to or retrieved from a database. The initial size of a vstr depends on the constructor and is changed by adding elements with add() or resizing with set_size().

In the following example, the vstr ints grows as elements are added, elements are retrieved with the index operator, and vstr memory is released when done:

#include <cxxcls/pobject.h>

void vstr_example()
{  Vstr<o_4b> ints;
   ints.add( 9 );
   ints.add( 4 );
   ints.add( 2 );
   int len = ints.size();
   int sum = 0;
   for ( int i=0; i<len; i++ )
   {  sum = sum + ints[i];
   }
   ints.release();
}

The following example illustrates the assignment operator:

#include <cxxcls/pobject.h>

void vstr_example()
{  Vstr<o_4b> v1;
   v1.add( 9 )
   v1.add( 4 );
   Vstr<o_4b> v2 = v1; // v2 now points to v1
   Vstr<o_4b> v3(2);   // v3 is created with 2 empty elements
   v3.release();       // v3 memory is released
   v3 = v1;            // v3 now points to v1
   v3.set( v1 );       // v3 is now an independent copy of v1
   v1.release()        // v1 and v2 memory is released
   v3.release()        // v3 memory is released
}

Two persistent objects may not share the same vstr.

If a Vstr<type> routine returns an empty vstr, this may be the correct result or it may mean that an error occurred. The most likely error is that your machine has run out of swap space.

 

Vstr<type>()

Vstr<type>();

Create an empty vstr.

Vstr<type>( const VstrAny& baseVstr );
Vstr<type>( const Vstr<baseType>& baseVstr );

Create a new vstr which is the same as the given vstr baseVstr. These constructors do not copy the given vstr, and any changes made to one will appear in the other.

Vstr<type>( o_u4b hint );

Create a new empty vstr and supply a hint as to how large the vstr is expected to get in the current transaction. This hint may improve performance when you are adding large numbers of elements. After the first commit or rollback, the hint is discarded.

If you do use the hint constructor to make a vstr, you should not assume that the capacity will be exactly the number you specify.

Memory is allocated by this method.

Vstr<type>(

   const type*  baseData,
   o_u4b        count );

Create a new vstr from an existing array specified as baseData using count number of elements. The elements are copied into the vstr, and memory is allocated for the new vstr.

See the chapter "Standard Template Library" in this manual for other methods on Vstr<type>.

 

VstrAny()

VstrAny( const VstrAny& base );
VstrAny( const o_vstr* base );

Convert the type of base to an instance of VstrAny.

These constructors do not copy the given vstr, and any changes made to one will appear in the other.

The VstrAny class is a generic vstr class which should be used only for converting other vstr classes when using objects not created with the C++/VERSANT interface.

Conversion from VstrAny to Vstr<type> is defined as a constructor in Vstr<type>.

 

add()

void add( const typenewElem );

Add an element newElem to this vstr at the next slot after the last one used and adjust the size of this vstr.

 

append()

void append( const Vstr<type>& baseVstr );

Append the given vstr baseVstr to this vstr.

void append(

   const type*  baseData,
   o_u4b        count );

Append the data specified as baseData to the end of this vstr using the number of elements specified as count.

These methods may allocate or expand the dynamic memory associated with this vstr. If a null value is passed for baseVstr, the space appended will be zeroed out.

Remember to later deallocate space used by the vstr with the release() method.

 

base()

type* base() const;

Return a pointer to the first element of this vstr. See also operator type*.

 

begin()

Implemented in the Standard Template Library as:

iterator begin();

const_iterator begin() const;

Return an iterator iterator positioned at the first item. See the chapter "Standard Template Library" for more information.

 

end()

type* end() const;

Return a pointer to one past the last element of this vstr. One past the last element is the same element as ( base() + size() ).

Also implemented in Standard Template Library as:

iterator end();

const_iterator end() const;

See the chapter "Standard Template Library" for more information.

 

fill()

void fill ( const typecopy_item );

Set all elements in this vstr to copy_item.

 

insert_at()

void insert_at(

   o_u4b        index,
   const type&  newElement );

Insert an element newElement into this vstr at the position specified by index and adjust the size of this vstr.

If index is equal to the number of elements in the vstr, this method is the same as append().

This method may allocate or expand the dynamic memory associated with this vstr.

Remember to later deallocate space used by the vstr with the release() method.

 

is_empty()

o_bool is_empty() const;

Return TRUE if there are no elements in this vstr; otherwise return FALSE.

 

ordered_remove()

void ordered_remove( const o_u4b index );

Remove the element at position index and shift the remaining elements to maintain the order of elements.

See also unordered_remove().

 

rbegin()

Implemented in the Standard Template Library as:

reverse_iterator rbegin();

const_reverse_iterator rbegin() const;

Return a reverse iterator positioned at the last item. See the chapter "Standard Template Library" for more information.

 

release()

void release();

Release dynamic memory held by this vstr.

 

rend()

Implemented in the Standard Template Library as:

reverse_iterator rend();

const_reverse_iterator rend() const;

Return a reverse iterator positioned immediately before the first item. See the chapter "Standard Template Library" for more information.

 

set()

void set( const Vstr<type>& baseVstr );

Copy the given vstr baseVstr to this vstr and drop the existing contents of this vstr.

void set(

   const type*  baseData,
   o_u4b        count );

Copy to this vstr count number of elements of the array baseData and drop the existing contents of this vstr.

To copy a vstr, use the set() method. By comparison, operator =() makes this vstr the same as a given vstr and does not copy the contents. If you use operator =, any changes made to one vstr will appear in the other.

Using set() may allocate or expand the dynamic memory associated with this vstr. Remember to later deallocate space used by the vstr with the release() method.

 

set_size()

void set_size( o_u4b new_size );

Set the size of this vstr to new_size. If the new size is less than the current size, elements are truncated from the end without regard to the contents of the elements. If the new size is greater than the current size, the new elements are zeroed.

 

size()

o_u4b size() const;

Return the number of elements in this vstr.

 

type*()

operator type*() const;

Return a pointer to the first element of this vstr. This is equivalent to the base() method.

 

unordered_remove()

void unordered_remove( const o_u4b index );

Remove the element at position index and shift the last element to fill the position of the removed element.

This method is faster than remove() but does not maintain the original order. See also ordered_remove().

 

[]()

type& operator[]( o_u4b ) const;

Return a reference to the element number i in this vstr. If i is equal to or greater than the size, an error will occur. Indexes start at zero.

 

=()

Vstr<type>& operator=( const Vstr<type>& baseVstr );
VstrAny& operator=   ( const VstrAny& baseVstr );

Make this vstr the same as the given vstr. This operator does not copy the given vstr, so any changes made to one will appear in the other.

 

&=()

Vstr<type>& operator&=( const Vstr<type>& baseVstr );
VstrAny& operator&=   ( const VstrAny& baseVstr );

Append the contents of the vstr specified as baseVstr to the end of this vstr. This is the same as the append() method except for the return type. Use the set() method to create a vstr whose contents are a copy of the contents of an existing vstr.

 

PList<type>

 

Usage

A list is a linked list of items. Each item is something like a vstr in that it can contain multiple elements of a particular type. Therefore, a list can be thought conceptally as a linked list of vstrs.

You can use PList<type> methods such as next(), first(), prev() to traverse the list and then invoke the PItem methods to access each item.

An object can have a list attribute in the same way it can have a vstr attribute.

Class PList<type> is a C++ wrapper for the kernel data type o_list, and its methods are directed at the o_list data member. The PItem<type> class wraps the kernel o_item data type. They implement shallow copy semantics and hence do not free the memory to which an instance points.

Queries on list attributes are not supported.

Like Vstr<type>, only elemental types are acceptable as types for Plist and PItem. You cannot use a class or struct as the type of a list.

The following methods can be used to manage lists:

PList<type>() Constructor.
++() Get next item.
copy() Create a copy.
current() Get current item.
find() Find an item.
first() Get the first item.
get() Get item at position.
merge() Merge two lists.
next() Get the next item.
pop() Remove the first item.
prev() Get the previous item.
push() Add item at front.
rcopy() Create a reverse copy.
release() Release memory.
remove() Delete an item.
replace() Replace an item.
reverse() Reverse item order.
rewind() Set current position to first item.
size() Get number of items.
 

 

PList<type>()

PList<type>();

Create a null list.

PList<type>(o_list list);

Create a list using list. The constructor is a shallow copy and will point to the same same list as list.

PList<type>(const Plist<type>& list);
Copy constructor. The constructor is a shallow copy and will point to the same same list as list.

 

++()

PItem<type> operator++();

Move current position to the next item and return that item. .

PItem<type> operator++(int);

Return the item at the position of the current pointer and then move the pointer. to the next item.

 

append()

PList<type>& append(PItem<type> d);

Add item d to the end of this list.

PList<type>& append(o_u4b sz, const type* d);

Create an item with the given size and contents and add it to the end of this list.

 

copy()

PList<type> copy() const;

Create a new list that is a copy of this list and return the copy.

 

current()

PItem<type> current() const ;

Returns the item at the position of the current pointer.

 

find()

o_bool find(const o_u1b* key) const;

Find an item which has the same value as key and return TRUE if found, otherwise return FALSE.

o_bool find(const o_u1b* key, const o_u4b index) const;

If the item at position index has a value equal to key, then return TRUE, otherwise return FALSE.

 

first()

PItem<type> first() const;

Return the first item on the list.

 

get()

PItem<type> get(const o_u4b i);

Get the item at position i.

 

merge()

void merge(const PList<type> &X);

Append list X to the end of this list.

Both lists must have items of type type.

 

next()

PItem<type> next();

Move the current pointer to the next item and return that item.

 

pop()

PItem<type> pop();

Remove the first item from this list and return that item. You must call PItem::release() to release the memory allocated for this item.

 

prev()

PItem<type> prev();

Move the current pointer to the previous item and return that item. Since o_list is a single linked list, this method has to traverse the whole list and is slow.

 

push()

PList<type>& push(PItem<type> d);

Insert a new item d at the front of this list.

PList<type>& push(o_u4b i , const type* d);

Create a new item with the specified size and contents and insert it at the front of this list.

 

rcopy()

PList<type> rcopy() const;

Create a new list that is a copy of this list, except that the items are in reverse order, and return the new list.

 

release()

void release();

Release memory that was allotted for the list and all of its items.

 

remove()

o_bool remove(PItem<typed);

Search for item d and remove it from this list.

If the item is found and removed, this method returns TRUE; otherwise, it returns FALSE.

 

replace()

PItem<type> replace(
o_u4b       i,
PItem<type> d);

Replace the item at position i with item d; if successful, return the replaced item and otherwise return NULL_ITEM.

PItem<type> replace(
o_u4b        i,
o_u4b        sz,
const type*  d);

Create a new item with size sz and data d and replace the item at position i with the new item; if successful, return the replaced item and otherwise return NULL_ITEM.

 

reverse()

PList<type>& reverse();

Reverse the order of the list items.

 

rewind()

void rewind() const;

Reset the current position to the first item in the list.

 

size()

o_4b size() const;

Return the number of items in this list.

 

PItem<type>

 

Usage

Class PItem<type> represents typed items in a list.

An item is a component of some list; when you create it, you add it to a list, and when you delete it, you remove it from a list.

See PList<type>.

 

PItem()

PItem();

Construct a null item.

PItem(o_item x);

Construct an item that is a copy of item x. This is a shallow copy.

PItem(const PItem<type>& x);

Construct an item that is a copy of item x. This is a shallow copy.

PItem(const type* d, const o_u4b count);

Construct an item using data d and size count.

 

!=()

bool operator != (void* o) const;
bool operator != (const PItem &o) const;

Do a shallow comparison between two items and return TRUE if this item is not equal to o and otherwise return FALSE.

 

[]()

type& operator[](const o_u4b n);

Return the element at position n in this item.

 

==()

bool operator ==(void* o) const;
bool operator == (const PItem& o) const;

Return TRUE if this item is equal to o and otherwise return FALSE.

 

get_data()

const type* get_data() const;

Get this item and cast it to type type.

 

is_null()

o_bool is_null() const;

Return TRUE if this item is NULL and otherwise return FALSE.

 

release()

void release();

Free memory allocated for this item. After being released, this item is equal to a null item.

 

size()

o_u4b size() const;

Get the number size of this item.

 

 

 


This online documentation is confidential and proprietary to Versant Corporation and is licensed to you, or to your organization, pursuant to the terms of an agreement between you and Versant that restricts the use of this documentation. Please refer to the agreement for more information or call Versant at 510-789-1500 with any questions.