dtl


ContainerFactory<Index>

Category: functors Component type: concept

Description

When using an IndexedDBView, you may want control over what kind of container is used to index elements within the IndexedDBView. A common example would be that you have a large number of fields in an index and you want to use a custom hashing function to look up elements quickly using that index. ContainerFactory<Index> gives you the ability to control any index within an IndexedDBView. It lets you control what type of container is used to index the elements (e.g. multiset, hashmultiset, or any kind of user defined container) and it allows you to specify what kinds of comparison and indexing functions you want to use with that container. Internally, a ContainerFactory<Index> is a function object that is used by each index in an IndexedDBView<View, IdxContainer, HashOrNoHash> . Each index in DTL is represented internally by a DBIndex<View, IdxContainer, HashOrNoHash> which has an associative container of type IdxContainer that holds pointers to DataObjs owned by the IndexedDBView. Through the use of explicit specialization of this class you can build different containers of type IdxContainer which may use their own comparison functions based on the index (usually by it's name, accessible through the Index::GetName() method). The container factory makes the process of instantiating any kind of underlying associative container uniform; whether it's sorted or hashed, or even if the constructors for the containers take a number of differing arguments. The generic implementation of ContainerFactory<Index> contains overloads for both hashed and non-hashed containers. The compiler will build the appropriate one based on the HASH/NO_HASH tag. If the IdxContainer type and the HASH/NO_HASH tag are not compatible (for example, specifying a hashed container for what's actually a non-hashed container), the compiler will generate an error. The generic implementation always uses the built in generic Index::lt() for the less-than comparison function on non-hashed containers and Index::hash() and Index::eq() (default implementations of hashing and equality comparison for the index) for hashed containers.

Definition

Defined in the DBIndex.h header file.

Refinement of

None.

Associated types

IndexedDBView, DBIndex

Example: A customized ContainerFactory using a nonhashed IdxContainer type

// ... classes as in IndexedDBView example ....
typedef DBView<Example, ParamObjExample> ViewType;
typedef CBFunctor2wRet<const Example *, const Example *, bool> IVCompare;
typedef multiset<Example *, IVCompare> MultisetType; 
typedef DBIndex<ViewType. MultisetType, NO_HASH > IdxType;

// reverse comparison on exampleStr
bool reverse_compare_strings(const Example *pData1, const Example *pData2)
{
	return pData1->GetExampleStr() > pData2->GetExampleStr();
}


// "specialized" ContainerFactory() tells the indices in the IndexedDBView
// to use a custom container for indexing records
// in this case, the container is a multiset which sorts in reverse order
// for the Primary Index and normal for all other indices
// assume the IndexedDBView<ViewType, MultisetType, NO_HASH> that uses this
// specialization of ContainerFactory has the following indices:
// PrimaryIndex = nonunique key with fields: STRING_VALUE = we want sorted // based on reverse_compare_strings() // AlternateIndex = unique key with fields: EXAMPLE_LONG, EXAMPLE_DATE = // we want sorted based on the default DBIndex::lt() function
template<> class dtl::ContainerFactory<IdxType> { public: MultisetType operator()(IdxType *pDBIndex, NO_HASH h) { // for STRING_VALUE's, compare true if first exampleStr > second exampleStr if (pDBIndex->GetName() == "PrimaryIndex") return MultisetType(cb_ptr_fun_w_ret(reverse_compare_strings)); else // for all other indices, in this case, pDBIndex->GetName() == "AlternateIndex", use generic comparison return MultisetType(cb_ptr_fun_w_ret(*pDBIndex, &IdxType::lt)); } };

Example: A customized ContainerFactory using a hashed IdxContainer type

// ... classes as in IndexedDBView example ....
typedef DBView<Example, ParamObjExample> ViewType;
typedef CBFunctor1wRet<const Example *, size_t> IVHash;
typedef CBFunctor2wRet<const Example *, const Example *, bool> IVCompare;
typedef hash_multiset<Example *, IVHash, IVCompare> HashMultisetType; 
typedef DBIndex<ViewType. HashMultisetType, HASH> HashIdxType;

// alternative hashing scheme on exampleStr
size_t my_hash_strings(const Example *pData1)
{
   string str = pData1->GetExampleStr();

   size_t sum = 0;

   // sum all the per character hash values together
   // a character c's hash value = 5*c + 13
   for (size_t i = 0; i < str.length(); i++)
		sum += (5 * str[i] + 13);

   return sum;
}

// "specialized" ContainerFactory() tells IndexedDBView to use a custom
// container for indexing records
// in this case, the container is a hash_multiset which uses an alternative hash
// function for the Primary Index and normal for all other indices

template<> class dtl::ContainerFactory<HashIdxType>
{
public:
	HashMultisetType operator()(HashIdxType *pDBIndex, HASH h) 
	{
		 // for STRING_VALUE's, hash on exampleStr using alternative hash function
	
		 if (pDBIndex->GetName() == "PrimaryIndex")
			return HashMultisetType(MEDIUM_HASH_TABLE, cb_ptr_fun_w_ret(my_hash_strings),
			                        cb_ptr_fun_w_ret(*pDBIndex, &HashIdxType::eq));
		 else // for all other indices use generic hash and comparison
			return HashMultisetType(MEDIUM_HASH_TABLE, cb_ptr_fun_w_ret(*pDBIndex, &HashIdxType::hash),
			                        cb_ptr_fun_w_ret(*pDBIndex, &HashIdxType::eq));
	}
};

Public Base Classes

None.

Template parameters

Parameter Description Default
Index The type of the index that the underlying container is being built for (always a DBIndex instantiation).  

Members

Member Where defined Description
Index::index_container_type operator()(Index *pDBIndex, HASH h) DBIndex Returns a freshly constructed hashed associative container of type Index::index_container_type for the DataObj references built based on properties of the Index passed in.
Index::index_container_type operator()(Index *pDBIndex, NO_HASH nh) DBIndex Returns a freshly constructed non-hashed associative container of type Index::index_container_type for the DataObj references built based on properties of the Index passed in.

 

See also

IndexedDBView


[DTL Home]

Copyright © 2002, Michael Gradman and Corwin Joy.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Corwin Joy and Michael Gradman make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

This site written using the ORB. [The ORB]

1