1
0
Fork 0
arangodb/arangod/BitIndexes/bitarrayIndex.c

423 lines
15 KiB
C
Executable File

////////////////////////////////////////////////////////////////////////////////
/// @brief bitarray index
///
/// @file
///
/// DISCLAIMER
///
/// Copyright by triAGENS GmbH - All rights reserved.
///
/// The Programs (which include both the software and documentation)
/// contain proprietary information of triAGENS GmbH; they are
/// provided under a license agreement containing restrictions on use and
/// disclosure and are also protected by copyright, patent and other
/// intellectual and industrial property laws. Reverse engineering,
/// disassembly or decompilation of the Programs, except to the extent
/// required to obtain interoperability with other independently created
/// software or as specified by law, is prohibited.
///
/// The Programs are not intended for use in any nuclear, aviation, mass
/// transit, medical, or other inherently dangerous applications. It shall
/// be the licensee's responsibility to take all appropriate fail-safe,
/// backup, redundancy, and other measures to ensure the safe use of such
/// applications if the Programs are used for such purposes, and triAGENS
/// GmbH disclaims liability for any damages caused by such use of
/// the Programs.
///
/// This software is the confidential and proprietary information of
/// triAGENS GmbH. You shall not disclose such confidential and
/// proprietary information and shall use it only in accordance with the
/// terms of the license agreement you entered into with triAGENS GmbH.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. O
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "bitarrayIndex.h"
// .............................................................................
// forward declaration of static functions used for iterator callbacks
// .............................................................................
static bool BitarrayIndexHasNextIterationCallback (TRI_index_iterator_t*);
static void* BitarrayIndexNextIterationCallback (TRI_index_iterator_t*);
static void* BitarrayIndexNextsIterationCallback (TRI_index_iterator_t*, int64_t);
static bool BitarrayIndexHasPrevIterationCallback (TRI_index_iterator_t*);
static void* BitarrayIndexPrevIterationCallback (TRI_index_iterator_t*);
static void* BitarrayIndexPrevsIterationCallback (TRI_index_iterator_t*, int64_t);
static void BitarrayIndexDestroyIterator (TRI_index_iterator_t*);
// .............................................................................
// forward declaration of static functions used here
// .............................................................................
static void BitarrayIndex_findHelper (BitarrayIndex*, TRI_vector_t*, TRI_index_operator_t*, TRI_index_iterator_t*);
static int generateBitMask (BitarrayIndex*, const BitarrayIndexElement*, TRI_bitarray_mask_t*);
// -----------------------------------------------------------------------------
// --SECTION-- bitarrayIndex common public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup bitarrayIndex
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a bitarray index , but does not free the pointer
////////////////////////////////////////////////////////////////////////////////
void BitarrayIndex_destroy(BitarrayIndex* baIndex) {
if (baIndex == NULL) {
return;
}
TRI_FreeBitarray(baIndex->bitarray);
baIndex->bitarray = NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a bitarray index and frees the pointer
////////////////////////////////////////////////////////////////////////////////
void BitarrayIndex_free(BitarrayIndex* baIndex) {
if (baIndex == NULL) {
return;
}
BitarrayIndex_destroy(baIndex);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, baIndex);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// Public Methods
//------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief Creates a new bitarray index. Failure will return an appropriate error code
////////////////////////////////////////////////////////////////////////////////
int BitarrayIndex_new(BitarrayIndex** baIndex,
TRI_memory_zone_t* memoryZone,
size_t cardinality,
bool addOtherColumn,
bool addUndefinedColumn,
void* context) {
int result;
size_t numArrays;
// ...........................................................................
// If the bit array index has arealdy been created, return internal error
// ...........................................................................
if (*baIndex != NULL) {
return TRI_ERROR_INTERNAL;
}
// ...........................................................................
// If the memory zone is invalid, then return an internal error
// ...........................................................................
if (memoryZone == NULL) {
return TRI_ERROR_INTERNAL;
}
// ...........................................................................
// Create the bit array index structure
// ...........................................................................
*baIndex = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(BitarrayIndex), true);
if (*baIndex == NULL) {
return TRI_ERROR_OUT_OF_MEMORY;
}
// ...........................................................................
// Determine the number of bit columns which will comprise the bit array index.
// ...........................................................................
numArrays = cardinality;
if (addOtherColumn) {
++numArrays;
}
if (addUndefinedColumn) {
++numArrays;
}
// ...........................................................................
// Create the bit arrays
// ...........................................................................
result = TRI_InitBitarray(&((*baIndex)->bitarray), memoryZone, numArrays, NULL);
// ...........................................................................
// return the result of creating the bit arrays
// ...........................................................................
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief adds (inserts) a data element into one or more bit arrays
////////////////////////////////////////////////////////////////////////////////
int BitarrayIndex_add(BitarrayIndex* baIndex, BitarrayIndexElement* element) {
int result;
TRI_bitarray_mask_t mask;
// ..........................................................................
// generate bit mask
// ..........................................................................
result = generateBitMask (baIndex, element, &mask);
if (result != TRI_ERROR_NO_ERROR) {
return result;
}
// ..........................................................................
// insert the bit mask into the bit array
// ..........................................................................
result = TRI_InsertBitMaskElementBitarray(baIndex->bitarray, &mask, element->data);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief attempts to locate one or more documents which match an index operator
////////////////////////////////////////////////////////////////////////////////
TRI_index_iterator_t* BitarrayIndex_find(BitarrayIndex* baIndex,
TRI_index_operator_t* indexOperator,
TRI_vector_t* shapeList,
bool (*filter) (TRI_index_iterator_t*) ) {
TRI_index_iterator_t* iterator;
// ...........................................................................
// Attempt to allocate memory for the index iterator which stores the results
// if any of the lookup.
// ...........................................................................
iterator = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_index_iterator_t), true);
if (iterator == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
return NULL; // calling procedure needs to care when the iterator is null
}
// ...........................................................................
// We now initialise the index iterator with all the call back functions.
// ...........................................................................
TRI_InitVector(&(iterator->_intervals), TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_index_iterator_interval_t));
iterator->_index = baIndex;
iterator->_currentInterval = 0;
iterator->_cursor = NULL;
iterator->_filter = filter;
iterator->_hasNext = BitarrayIndexHasNextIterationCallback;
iterator->_next = BitarrayIndexNextIterationCallback;
iterator->_nexts = BitarrayIndexNextsIterationCallback;
iterator->_hasPrev = BitarrayIndexHasPrevIterationCallback;
iterator->_prev = BitarrayIndexPrevIterationCallback;
iterator->_prevs = BitarrayIndexPrevsIterationCallback;
iterator->_destroyIterator = BitarrayIndexDestroyIterator;
BitarrayIndex_findHelper(baIndex, shapeList, indexOperator, iterator);
return iterator;
}
//////////////////////////////////////////////////////////////////////////////////
/// @brief alias for add Index item
//////////////////////////////////////////////////////////////////////////////////
int BitarrayIndex_insert(BitarrayIndex* baIndex, BitarrayIndexElement* element) {
return BitarrayIndex_add(baIndex,element);
}
//////////////////////////////////////////////////////////////////////////////////
/// @brief removes an entry from the bit arrays and master table
//////////////////////////////////////////////////////////////////////////////////
int BitarrayIndex_remove(BitarrayIndex* baIndex, BitarrayIndexElement* element) {
int result;
result = TRI_RemoveElementBitarray(baIndex->bitarray, element->data);
return result;
}
//////////////////////////////////////////////////////////////////////////////////
/// @brief updates a bit array index entry
//////////////////////////////////////////////////////////////////////////////////
bool BitarrayIndex_update(BitarrayIndex* baIndex,
const BitarrayIndexElement* oldElement,
const BitarrayIndexElement* newElement) {
int result;
TRI_bitarray_mask_t oldMask;
TRI_bitarray_mask_t newMask;
// ..........................................................................
// updates an entry in the bit arrays and master table
// essentially it replaces the bit mask with a new bit mask
// ..........................................................................
// ..........................................................................
// Check that something has not gone terribly wrong
// ..........................................................................
if (oldElement->data != newElement->data) {
TRI_set_errno(TRI_ERROR_INTERNAL);
return false;
}
// ..........................................................................
// generate bit masks
// ..........................................................................
result = generateBitMask (baIndex, oldElement, &oldMask);
if (result != TRI_ERROR_NO_ERROR) {
TRI_set_errno(result);
return false;
}
result = generateBitMask (baIndex, newElement, &newMask);
if (result != TRI_ERROR_NO_ERROR) {
TRI_set_errno(result);
return false;
}
// ..........................................................................
// replace the old mask with the new mask into the bit array
// ..........................................................................
result = TRI_ReplaceBitMaskElementBitarray(baIndex->bitarray, &oldMask, &newMask, oldElement->data);
if (result != TRI_ERROR_NO_ERROR) {
TRI_set_errno(result);
return false;
}
return true;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Implementation of static functions forward declared above
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// .............................................................................
// forward declaration of static functions used for iterator callbacks
// .............................................................................
bool BitarrayIndexHasNextIterationCallback(TRI_index_iterator_t* iterator) {
assert(0);
return false;
}
void* BitarrayIndexNextIterationCallback(TRI_index_iterator_t* iterator) {
assert(0);
return NULL;
}
void* BitarrayIndexNextsIterationCallback(TRI_index_iterator_t* iterator, int64_t jumpSize) {
assert(0);
return NULL;
}
bool BitarrayIndexHasPrevIterationCallback(TRI_index_iterator_t* iterator) {
assert(0);
return false;
}
void* BitarrayIndexPrevIterationCallback(TRI_index_iterator_t* iterator) {
assert(0);
return NULL;
}
void* BitarrayIndexPrevsIterationCallback(TRI_index_iterator_t* iterator, int64_t jumpSize) {
assert(0);
return NULL;
}
void BitarrayIndexDestroyIterator(TRI_index_iterator_t* iterator) {
assert(0);
}
// .............................................................................
// forward declaration of static functions used internally here
// .............................................................................
void BitarrayIndex_findHelper(BitarrayIndex* baIndex,
TRI_vector_t* shapeList,
TRI_index_operator_t* indexOperator,
TRI_index_iterator_t* iterator) {
assert(0);
}
int generateBitMask(BitarrayIndex* baIndex, const BitarrayIndexElement* element, TRI_bitarray_mask_t* mask) {
assert(0);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End: