Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c-color Choice Dictionary #102

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
BasedOnStyle: 'google'
IndentWidth: 4
AccessModifierOffset: -3
ColumnLimit: 80
ColumnLimit: 80
90 changes: 90 additions & 0 deletions docs/c-color_choice-dictionary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# C-color Choice Dictionary

A choice dictionary is a bitset containing n elements that supports reading and setting a field of bits to a color in constant time and additionally a so-called _choice_ operation that returns the position of an arbitrary index of a field that has a chosen color other than 0 in constant time.

## Operations

- get(i): Returns the color at index i.
- insert(i, c): Set the color at index i to c.
- choice(c): Returns an arbitrary index that is set to the color c.

## Efficiency

- Time: O(1) (all operations)
- Space: O(n + n/w + 3n/(w^2))

## Example

```cpp
CcolorChoiceDictionary *cd = new CcolorChoiceDictionary(100, 4); // The 2nd parameter defines the amount of colors including 0

cd->insert(0, 1); // Indexing beginns with 0
cd->insert(10, 1);
cd->insert(72, 1);
cd->insert(31, 1);
cd->insert(17, 2);
cd->insert(41, 2);
cd->insert(0, 3); // This overrides the previously inserted color
cd->insert(10, 0);

cd.get(0); // Returns 3
cd.get(10); // Returns 0
cd.get(31); // Returns 1
cd.get(17); // Returns 2

cd.choice(1); // May return 31, or 72
cd.choice(2); // May return 17, or 41

delete cd;
```

<br>

# Iterator

An Iterator is used to iterate over all fields set to a specific color within a choice dictionary.
It supports the so-called _more_ operation that returns true if the choice dictionary contains more bits of that color, aswell as the _next_ operation that returns the index of the next field.

## Operations

- setColor(c): Sets the color the iterate should use.
- init: Initializes the Iterator.
- more: Returns true if there are more fields with color c.
- next: Returns the next arbitrary position of a field that is set to c.

## Efficiency

- Time: O(1) (all operations)

## Example

```cpp
CcolorChoiceDictionary *cd = new CcolorChoiceDictionary(100, 4); // The 2nd parameter defines the amount of colors including 0
ChoiceDictionaryIterator* it = new ChoiceDictionaryIterator(cd);

cd->insert(0, 1);
cd->insert(10, 1);
cd->insert(72, 1);
cd->insert(31, 1);
cd->insert(17, 2);
cd->insert(41, 2);
cd->insert(0, 3);
cd->insert(10, 0);

it->setColor(1);
it->init();

while (it->more()) { // Returns true if more fields are of color 1
it->next(); // May return the next arbitrary position 31, or 72
}

it->setColor(2);
it->init();

while (it->more()) { // Returns true if more fields are of color 1
it->next(); // May return the next arbitrary position 17, or 41
}

delete it;
delete cd;
```
49 changes: 49 additions & 0 deletions include/sealib/collection/cdbitutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef SEALIB_CDBITUTIL_H_
#define SEALIB_CDBITUTIL_H_

#define TWO 2
#define FOUR 4
#define EIGHT 8
#define SIXTEEN 16
#define THIRTYTWO 32

#define XOR_2 12297829382473034410UL
#define XOR_4 14757395258967641292UL
//#define XOR_4 9838263505978427528UL
#define XOR_8 17361588704580268272UL
//#define XOR_8 9259542123273814144UL
#define XOR_16 18374966859414961920UL
//#define XOR_16 9223512776490647552UL
#define XOR_32 18446462603027742720UL
//#define XOR_32 9223372039002259456UL

#define SHIFT_OFFSET 1UL

#include <cstdint>

const uint64_t WORDSIZE = sizeof(uint64_t) * 8;

namespace Sealib {

class CdBitUtil {
private:
static uint64_t getXor(uint64_t colorFieldSize);
static uint64_t getMask(uint64_t colorFieldSize);
static uint64_t foldWord(uint64_t _word,
uint64_t colorFieldSize);
static uint64_t generateXorWord(uint64_t color,
uint64_t colorFieldSize,
uint64_t word);

public:
static int64_t cdXorLoop(uint64_t _word, uint64_t color,
uint64_t colorFieldSize);
static int64_t cdXor(uint64_t _word, uint64_t color,
uint64_t colorFieldSize);
static uint64_t cdColorIndices(uint64_t value,
uint64_t color,
uint64_t colorFieldSize);
};

} // namespace Sealib
#endif // SEALIB_CDBITUTIL_H_
120 changes: 120 additions & 0 deletions include/sealib/dictionary/ccolorchoicedictionary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#ifndef SEALIB_CCOLORCHOICEDICTIONARY_H_
#define SEALIB_CCOLORCHOICEDICTIONARY_H_

#define SHIFT_OFFSET 1UL

#include <cstdint>
#include <sealib/collection/cdbitutil.h>

namespace Sealib {
/**
* A choice dictionary is a bitset containing n elements that supports reading
* and setting a field of bits to a color in constant time and additionally a
* so-called _choice_ operation that returns the position of an arbitrary index
* of a field that has a chosen color other than 0 in constant time.
* @author Dennis Appel
*/

const uint64_t ULONGBITS = sizeof(uint64_t) * 8;

class CcolorChoiceDictionary {
private:
uint64_t *choiceDictionary, *pointerStructure, *pointer;

const uint64_t wordSize, colorCount, colorFieldSize, wordCount,
mask;

uint64_t extend(uint64_t color);

void updatePointer(uint64_t blockIndex);

void movePointer(uint64_t color, bool forward);

bool isWritten(uint64_t index, uint64_t color);

bool isInitialized(uint64_t blockIndex);

void initializeBlock(uint64_t blockIndex);

bool isChained(uint64_t index, uint64_t color);

void makeChain(uint64_t blockWritten,
uint64_t blockUnwritten, uint64_t color);

uint64_t chainedWith(uint64_t blockIndex,
uint64_t color);

void breakChain(uint64_t index, uint64_t color);

/* Initialization Functions */
uint64_t computeColorFieldSize();

uint64_t computeMask();

void createDataStructure();

public:
/**
* Creates choice dictionary with given size and colors.
* @param length Length of the choice dictionary
* @param colors Amount of colors including zero
*/
explicit CcolorChoiceDictionary(uint64_t size,
uint64_t colors);

/**
* Sets a field at specified index to a color.
* @param index Index of the field that should be set to a color.
* @param color Color the field should be set to.
*/
void insert(uint64_t index, uint64_t color);

/**
* Returns the color of the field at the specified index.
* @param index Index of field.
*/
uint64_t get(uint64_t index);

/**
* Returns an arbitrary position of a field with a color.
* @param color Color of the field.
*/
uint64_t choice(uint64_t color);

/**
* Returns the block size used within the choice dictionary.
* The block size is directly related to the amount of colors.
*/
uint64_t getBlockSize();

/**
* Returns the size of a field that can store a color.
* The field size is usually a power of 2.
*/
uint64_t getColorFieldSize();

/**
* Returns the value of an entire word containing multiple fields.
* @wordIndex index of the word which value is to be returned.
*/
uint64_t getWordValue(uint64_t wordIndex);

/**
* Returns the block that corresponds to a pointer of a color.
* @param pointerIndex Index within the pointer structure.
* @param color Color which the index corresponds to.
*/
uint64_t getBlock(uint64_t pointerIndex,
uint64_t color);

/**
* Returns the index of the first word of the last block that contains
* either a pointer to a block with a color or the block itself.
* @param color Color for which the barrier is to be returned.
*/
uint64_t getBarrier(uint64_t color);

~CcolorChoiceDictionary();
};
} // namespace Sealib
#endif // SEALIB_CCOLORCHOICEDICTIONARY_H_
69 changes: 69 additions & 0 deletions include/sealib/iterator/ccolorcditerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#ifndef SEALIB_CCOLORCDITERATOR_H_
#define SEALIB_CCOLORCDITERATOR_H_

#include <cstdint>
#include <sealib/dictionary/ccolorchoicedictionary.h>
#include <sealib/iterator/iterator.h>

#define SHIFT_OFFSET 1UL

namespace Sealib {
/**
* Iteration class to return all bit positions of a choice dictionary that
* are set to 1.
*
* @author Dennis Appel
*/
class CcolorCdIterator : Iterator<uint64_t> {
private:
/**
* @param primaryWord Value of the currently used word in primary.
* @param secondaryWord Value of the currently used word in secondary.
* @param primaryIndex Index of the currently used word in primary.
* @param secondaryIndex Index of the currently used word in secondary.
* @param pointer currently used pointer Position.
* @param choicedictionary Pointer to an existing choice dictionary.
*/
const uint64_t blockSize, colorFieldSize;
CcolorChoiceDictionary* choicedictionary;
uint64_t pointer, barrier, activeBlock, activeWord, nextWordIndex,
color;
bool done;

bool nextBlock();

bool nextWord();

public:
/**
* Creates an Iterator for a choice dictionary.
* @param _choicedictionary Pointer to an existing choice dictionary.
*/
explicit CcolorCdIterator(CcolorChoiceDictionary* _choicedictionary);

/**
* Initializes the iterator.
*/
void init();

/**
* Set the iterator to a color to iterate over.
* @param Color to iterate over
*/
void setColor(uint64_t color);

/**
* Returns true if there are more fields of a color in the choice
* dictionary.
*/
bool more();

/**
* Returns the arbitrary index of a field with a color.
*/
uint64_t next();

~CcolorCdIterator();
};
} // namespace Sealib
#endif // SEALIB_CCOLORCDITERATOR_H_
Loading