#include "base/rebase.hpp"
+enum RELOC_HASHLIST {
+ LC_NEXT_1 = LC_HASHLIST + 1, // 50301
+};
+
+/**
+ * Constructor.
+ */
+ReArrayPosition::ReArrayPosition() :
+ m_position(-1),
+ m_forward(true)
+{
+}
+/**
+ * Sets the cursor behind the last position.
+ *
+ * Calling <code>ReHashList::prior() returns the last element.
+ */
+void ReArrayPosition::behindLast(){
+ m_position = (ReSeqList::Index) -2;
+}
+/**
+ * Sets the cursor behind the last position.
+ * Calling <code>ReHashList::next() returns the first element.
+ */
+void ReArrayPosition::priorFirst(){
+ m_position = (ReSeqList::Index) -1;
+}
+
/** Constructor.
*/
-ReHashList::ReHashList(int keyTagSize, int contentLengthSize, int keyLengthSize) :
+ReHashList::ReHashList(bool ignoreCase, int keyTagSize, int contentLengthSize,
+ int keyLengthSize) :
m_keys(),
m_values()
{
+ m_keys.setIgnoreCase(ignoreCase);
+ m_keys.setSorted(true);
m_keys.setSizes(keyTagSize, keyLengthSize);
m_keys.setSizes(0, contentLengthSize);
}
*/
bool ReHashList::get(const Byte* key, size_t keyLength,
ReByteBuffer& value) const{
- if (keyLength == (size_t) -1)
- keyLength = strlen(key);
-
- int ix = find(key, keyLength);
- bool rc = ix >= 0;
-#if 0
+ ReSeqList::Index index;
+ ReSeqList::Tag tag;
+ bool rc = m_keys.binarySearch(key, keyLength, index, &tag);
if (rc){
- ReSeqList::Sequence* seq = m_keys.getInfo(ix);
- // m_tag contains the index into m_values:
- const Byte* ptr = reinterpret_cast<const Byte*>(m_values.str() + seq->m_tag);
- // m_values contains <length><sequence>:
- size_t valLength = * (size_t*) ptr;
- ptr += sizeof (size_t);
- value.set(ptr, valLength);
+ m_values.get(tag, value);
}
-#endif
return rc;
}
/** @brief Returns the value of a key value pair.
*
* @param true: An item was found. false: No more items.
*/
-bool ReHashList::next(size_t& position, ReByteBuffer* key, ReByteBuffer* value) const{
- bool rc = position < m_keys.count();
+bool ReHashList::next(ReArrayPosition& position, ReByteBuffer* key,
+ ReByteBuffer* value) const{
+ bool rc = position.m_position < m_keys.count();
if (rc){
- ReSeqList::Sequence* seq = m_keys.getInfo(position++);
- if (key != NULL){
- const Byte* ptr = m_keys.getContent() + seq->m_index;
- key->setLength(seq->m_length);
- memcpy(key->buffer(), ptr, seq->m_length);
- }
- if (value != NULL){
-#if 0
- const Byte* ptr = reinterpret_cast<const Byte*>(m_values.str() + seq->m_tag);
- size_t length = * (size_t*) ptr;
- ptr += sizeof (size_t);
- value->setLength(length);
- memcpy(value->buffer(), ptr, length);
-#endif
+ ReByteBuffer dummy;
+ ReSeqList::Tag tag;
+ if (key == NULL)
+ key = &dummy;
+ if (! m_keys.get(++position.m_position, *key, &tag)){
+ globalLogger()->sayF(LOG_ERROR | CAT_LIB, LC_NEXT_1,
+ i18n("next(): invalid cursor: $1"))
+ .arg((int) position.m_position).end();
+ } else {
+ if (value != NULL)
+ if (! m_values.get((size_t) tag, *value)){
+ globalLogger()->sayF(LOG_ERROR | CAT_LIB, LC_NEXT_1,
+ i18n("next(): invalid content index: $1")).arg((int) tag).end(); }
}
}
return rc;
*/
void ReHashList::put(const Byte* key, size_t keyLength,
const Byte* value, size_t valueLength){
-#if 0
if (keyLength == (size_t) -1)
keyLength = strlen(key);
if (valueLength == (size_t) -1)
valueLength = strlen(value);
- int ix = find(key, keyLength);
- bool storeValue = false;
- if (ix < 0){
- ReSeqList::Index pos = m_values.length();
- storeValue = true;
- m_keys.add(-1, key, keyLength, pos);
+ ReSeqList::Index index;
+ ReSeqList::Tag tag;
+ if (m_keys.binarySearch(key, keyLength, index, &tag)){
+ // replace the value:
+ m_values.set((ReSeqList::Index) tag, value, valueLength, 0);
} else {
- Sequence* seq = m_keys.getInfo(ix);
- // m_tag contains the index into <code>m_values</code>.
- Byte* ptr = m_values.buffer() + seq->m_tag;
- size_t valLength = * (size_t *) ptr;
- // Can we take the old storage?
- if (valLength >= valueLength){
- // Yes, it is enough space:
- * (size_t *) ptr = valueLength;
- ptr += sizeof (size_t);
- memcpy(ptr, value, valueLength);
- } else {
- storeValue = true;
- seq->m_tag = m_values.length();
- }
- }
- if (storeValue){
- m_values.append((Byte*) &valueLength, sizeof valueLength);
- m_values.append(value, valueLength);
+ // insert a new value.
+ tag = (ReSeqList::Tag) m_values.count();
+ m_values.add(-1, value, valueLength);
+ m_keys.add(index, key, keyLength, tag);
}
-#endif
}
/** @brief Puts a key value pair into the hashlist.
*
#ifndef REHASHLIST_H_
#define REHASHLIST_H_
+class ReArrayPosition{
+public:
+ ReArrayPosition();
+public:
+ void behindLast();
+ void priorFirst();
+public:
+ ReSeqList::Index m_position;
+ bool m_forward;
+};
/** @brief A simple associative array.
*
* An instance stores key value pairs.
typedef char Byte;
typedef ReSeqList::Sequence Sequence;
public:
- ReHashList(int keyTagSize = 1, int contentLengthSize = 1, int keyLengthSize = 1);
+ ReHashList(bool ignoreCase = false, int keyTagSize = 1,
+ int contentLengthSize = 1, int keyLengthSize = 1);
virtual ~ReHashList();
public:
void clear();
bool get(const Byte* key, size_t keyLength, ReByteBuffer& value) const;
bool get(const ReByteBuffer& key, ReByteBuffer& value) const;
- bool next(size_t& position, ReByteBuffer* key, ReByteBuffer* val) const;
+ bool next(ReArrayPosition& position, ReByteBuffer* key, ReByteBuffer* val) const;
void put(const Byte* key, size_t keyLength, const Byte* value, size_t valueLength);
void put(const char* key, const char* value);
void put(const ReByteBuffer& key, const ReByteBuffer& value);
//@ Containing an array of keys.
ReSeqList m_keys;
//@ Containing the values. The tag of <code>m_key</code> is the index
- //@ of the start position in <code>m_values</code>.
+ //@ in <code>m_values</code>.
ReSeqList m_values;
};
ReSeqList list;
list.setIgnoreCase(true);
ReByteBuffer value, expectedValue;
- ReSeqList::Tag tag = 0;
- ReSeqList::Tag expectedTag = 0;
list.add(-1, "bcd", -1, 200);
list.add(-1, "abcd", -1, 100);
list.add(-1, "abc", -1, 300);
checkElement(list, 3U, "bCd", 200);
checkElement(list, 4U, "cde", 400);
ReSeqList::Index index;
+ ReSeqList::Tag tag;
checkT(list.binarySearch("Abc", -1, index, &tag));
checkEqu(0u, index);
checkT(list.binarySearch("AbcD", -1, index, &tag));
ReSeqList list;
list.setIgnoreCase(true);
ReByteBuffer value, expectedValue;
- ReSeqList::Tag tag = 0;
- ReSeqList::Tag expectedTag = 0;
list.add(-1, "bcd", -1, 200);
list.add(0, "abc", -1, 100);
list.dump(stdout);