Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
2ac4cf51
Commit
2ac4cf51
authored
Apr 26, 2005
by
tulin@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bitvector.h:
new file
parent
033988f0
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
254 additions
and
0 deletions
+254
-0
sql/bitvector.h
sql/bitvector.h
+254
-0
No files found.
sql/bitvector.h
0 → 100644
View file @
2ac4cf51
/* -*- Mode: C++ -*-
Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef BITVECTOR_H
#define BITVECTOR_H
#include <my_global.h>
#include <my_sys.h>
#include <cstring>
#include <climits>
/* Some compile-time checks to ensure the integrity of the implementation. */
#if CHAR_BIT != 8
# error "This implementation is designed for 8-bit bytes!"
#endif
#ifndef __cplusplus
# error "This is not a C header file, it's a C++ header file"
#endif
namespace
{
/* Defining my own swap, since we cannot use std::swap() */
template
<
class
T
>
inline
void
my_swap
(
T
&
x
,
T
&
y
)
{
T
t
(
x
);
x
=
y
;
y
=
t
;
}
}
/*
A run-time sized bitvector for storing bits.
CAVEAT
This class is not designed to be inherited from, please don't do that.
Right now, the vector cannot change size. It's only used as a replacement
for using an array of bytes and a counter. If you want to change the size
of the vector, construct a new bitvector and assign it to the vector,
e.g.:
bitvector new_bv(new_size);
old_bv= new_bv;
An alternative is to use the swap member function to replace the instance:
bitvector new_bv(new_size);
old_bv.swap(new_bv);
The latter may be more efficient on compilers that are not so good at
inlining code.
*/
class
bitvector
{
private:
/* Helper classes */
struct
flip_bit_op
{
void
operator
()(
byte
*
p
,
byte
m
)
{
*
p
^=
m
;
}
};
struct
set_bit_op
{
void
operator
()(
byte
*
p
,
byte
m
)
{
*
p
|=
m
;
}
};
struct
clear_bit_op
{
void
operator
()(
byte
*
p
,
byte
m
)
{
*
p
&=
~
m
;
}
};
struct
test_bit_op
{
bool
operator
()(
byte
*
p
,
byte
m
)
{
return
*
p
&
m
;
}
};
/* Compute the number of bytes required to store 'bits' bits in an array. */
static
inline
size_t
byte_size
(
size_t
bits
)
{
int
const
byte_bits
=
sizeof
(
byte
)
*
CHAR_BIT
;
return
(
bits
+
(
byte_bits
-
1
))
/
byte_bits
;
}
/* Tidy the last byte (by clearing the unused bits) of the bitvector to make
* comparison easy. This code is assuming that we're working with 8-bit
* bytes.
*/
void
tidy_last_byte
()
{
byte
*
const
last_byte
=
m_data
+
bytes
()
-
1
;
/* Get the number of used bits (1..8) in the last byte */
unsigned
int
const
used
=
1U
+
((
size
()
-
1U
)
&
0x7U
);
/* Create a mask with the upper 'unused' bits clear and the lower 'used'
* bits set. The bits within each byte is stored in big-endian order.
*/
unsigned
int
const
mask
=
((
1
<<
used
)
-
1
);
/* Mask the last byte */
*
last_byte
&=
mask
;
}
template
<
class
ReturnType
,
class
Func
>
inline
ReturnType
apply_to_byte
(
size_t
const
pos
,
Func
op
)
const
{
/* Here I'm assuming that we're working with 8-bit bytes. */
ptrdiff_t
const
byte_pos
=
pos
>>
3
;
byte
const
mask
=
(
1
<<
(
pos
&
0x7U
));
return
op
(
&
m_data
[
byte_pos
],
mask
);
}
public:
bitvector
()
:
m_size
(
0
),
m_data
(
0
)
{
}
explicit
bitvector
(
size_t
size
,
bool
value
=
false
)
:
m_size
(
size
),
m_data
(
my_malloc
(
byte_size
(
size
),
MYF
(
0
)))
{
if
(
value
)
set_all
();
else
clear_all
();
}
/* Constructor to create a bitvector from data. Observe that 'size' is the
* number of *bits* in the bitvector.
*/
explicit
bitvector
(
byte
const
*
data
,
size_t
size
)
:
m_size
(
size
),
m_data
(
my_malloc
(
byte_size
(
size
),
MYF
(
0
)))
{
/* std::copy(data, data + byte_size(size), m_data); */
memcpy
(
m_data
,
data
,
byte_size
(
size
));
tidy_last_byte
();
}
bitvector
(
bitvector
const
&
other
)
:
m_size
(
other
.
size
()),
m_data
(
my_malloc
(
other
.
bytes
(),
MYF
(
0
)))
{
/* std::copy(other.m_data, other.m_data + other.bytes(), m_data); */
memcpy
(
m_data
,
other
.
data
(),
other
.
bytes
());
tidy_last_byte
();
/* Just a precaution */
}
/* Assignment operator */
bitvector
&
operator
=
(
bitvector
other
)
{
swap
(
other
);
return
*
this
;
}
~
bitvector
()
{
if
(
m_data
)
my_free
(
m_data
,
MYF
(
0
));
}
/* Swap the guts of this instance with another instance. */
void
swap
(
bitvector
&
other
)
{
my_swap
(
m_size
,
other
.
m_size
);
my_swap
(
m_data
,
other
.
m_data
);
}
/* A pointer to the bytes representing the bits */
byte
const
*
data
()
const
{
return
m_data
;
}
/* The size of the data in *bytes* */
size_t
bytes
()
const
{
return
byte_size
(
m_size
);
}
/* The number of bits in the bit vector */
size_t
size
()
const
{
return
m_size
;
}
/* Set all bits in the vector */
void
set_all
()
{
/* std::fill_n(m_data, bytes(), 255); */
memset
(
m_data
,
255
,
bytes
());
tidy_last_byte
();
}
/* Set a bit to a value */
void
set_bit
(
size_t
pos
)
{
apply_to_byte
<
void
>
(
pos
,
set_bit_op
());
}
/* Reset (clear) all bits in the vector */
void
clear_all
()
{
/* std::fill_n(m_data, bytes(), 0); */
memset
(
m_data
,
0
,
bytes
());
tidy_last_byte
();
}
/* Reset one bit in the vector */
void
clear_bit
(
size_t
pos
)
{
apply_to_byte
<
void
>
(
pos
,
clear_bit_op
());
}
void
flip_bit
(
size_t
pos
)
{
apply_to_byte
<
void
>
(
pos
,
flip_bit_op
());
}
bool
get_bit
(
size_t
pos
)
const
{
return
apply_to_byte
<
bool
>
(
pos
,
test_bit_op
());
};
bool
operator
==
(
bitvector
const
&
rhs
)
const
{
if
(
size
()
!=
rhs
.
size
())
return
false
;
/* This works since I have ensured that the last byte of the array contain
* sensible data.
*/
if
(
memcmp
(
data
(),
rhs
.
data
(),
bytes
())
!=
0
)
return
false
;
return
true
;
}
bool
operator
!=
(
bitvector
const
&
rhs
)
const
{
return
!
(
*
this
==
rhs
);
}
private:
size_t
m_size
;
byte
*
m_data
;
};
#endif
/* BITVECTOR_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment