diff options
-rw-r--r-- | include/hashcomp.h | 53 | ||||
-rw-r--r-- | src/hashcomp.cpp | 10 |
2 files changed, 50 insertions, 13 deletions
diff --git a/include/hashcomp.h b/include/hashcomp.h index 805929f5d..6e171549d 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -378,6 +378,47 @@ namespace irc * bit values in a bitmap dynamically, rather than having to define * costs in a fixed size unsigned integer and having the possibility * of collisions of values in different third party modules. + * + * IMPORTANT NOTE: + * + * To use this class, you must derive from it. + * This is because each derived instance has its own freebits array + * which can determine what bitfields are allocated on a TYPE BY TYPE + * basis, e.g. an irc::dynamicbitmask type for userrecs, and one for + * chanrecs, etc. You should inheret it in a very simple way as follows. + * The base class will resize and maintain freebits as required, you are + * just required to make the pointer static and specific to this class + * type. + * + * class mydbitmask : public irc::dynamicbitmask + * { + * private: + * + * static unsigned char* freebits; + * + * public: + * + * mydbitmask() : irc::dynamicbitmask() + * { + * freebits = new unsigned char[this->bits_size]; + * memset(freebits, 0, this->bits_size); + * } + * + * ~mydbitmask() + * { + * delete[] freebits; + * } + * + * unsigned char* GetFreeBits() + * { + * return freebits; + * } + * + * void SetFreeBits(unsigned char* freebt) + * { + * freebits = freebt; + * } + * }; */ class dynamicbitmask : public classbase { @@ -387,12 +428,6 @@ namespace irc * more than 32 entries with Allocate(). */ unsigned char* bits; - /** A bitmask containing 1's for allocated - * bits and 0's for free bits. When we - * allocate a bit using Allocate(), we OR - * its position in here to 1. - */ - unsigned char* freebits; /** Current set size (size of freebits and bits). * Both freebits and bits will ALWAYS be the * same length. @@ -406,7 +441,7 @@ namespace irc /** Free the memory used by bits and freebits */ - ~dynamicbitmask(); + virtual ~dynamicbitmask(); /** Allocate an irc::bitfield. * @return An irc::bitfield which can be used @@ -447,6 +482,10 @@ namespace irc * for the freebits array. */ unsigned char GetSize(); + + virtual unsigned char* GetFreeBits() { return NULL; } + + virtual void SetFreeBits(unsigned char* freebits) { } }; /** The irc_char_traits class is used for RFC-style comparison of strings. diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index d44ab54c2..27c71defa 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -473,24 +473,20 @@ long irc::portparser::GetToken() } } -irc::dynamicbitmask::dynamicbitmask() +irc::dynamicbitmask::dynamicbitmask() : bits_size(4) { /* We start with 4 bytes allocated which is room * for 4 items. Something makes me doubt its worth * allocating less than 4 bytes. */ - bits_size = 4; bits = new unsigned char[bits_size]; - freebits = new unsigned char[bits_size]; memset(bits, 0, bits_size); - memset(freebits, 0, bits_size); } irc::dynamicbitmask::~dynamicbitmask() { /* Tidy up the entire used memory on delete */ delete[] bits; - delete[] freebits; } irc::bitfield irc::dynamicbitmask::Allocate() @@ -499,6 +495,7 @@ irc::bitfield irc::dynamicbitmask::Allocate() * should only be allocating bitfields on load, the Toggle and * Get methods are O(1) as these are called much more often. */ + unsigned char* freebits = this->GetFreeBits(); for (unsigned char i = 0; i < bits_size; i++) { /* Yes, this is right. You'll notice we terminate the loop when !current_pos, @@ -536,6 +533,7 @@ irc::bitfield irc::dynamicbitmask::Allocate() */ bits = temp_bits; freebits = temp_freebits; + this->SetFreeBits(freebits); /* Initialize the new byte on the end of * the bitfields, pre-allocate the one bit * for this allocation @@ -560,7 +558,7 @@ bool irc::dynamicbitmask::Deallocate(irc::bitfield &pos) */ if (pos.first < bits_size) { - freebits[pos.first] &= ~pos.second; + this->GetFreeBits()[pos.first] &= ~pos.second; return true; } /* They gave a bitfield outside of the |