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
7e4641bc
Commit
7e4641bc
authored
Nov 18, 2005
by
pekka@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ndb - wl#1497 LinearPool seize_index
parent
50afa94d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
300 additions
and
79 deletions
+300
-79
storage/ndb/src/kernel/vm/LinearPool.hpp
storage/ndb/src/kernel/vm/LinearPool.hpp
+251
-75
storage/ndb/src/kernel/vm/testSuperPool.cpp
storage/ndb/src/kernel/vm/testSuperPool.cpp
+49
-4
No files found.
storage/ndb/src/kernel/vm/LinearPool.hpp
View file @
7e4641bc
...
@@ -17,7 +17,8 @@
...
@@ -17,7 +17,8 @@
#ifndef LINEAR_POOL_HPP
#ifndef LINEAR_POOL_HPP
#define LINEAR_POOL_HPP
#define LINEAR_POOL_HPP
#include <SuperPool.hpp>
#include <Bitmask.hpp>
#include "SuperPool.hpp"
/*
/*
* LinearPool - indexed record pool
* LinearPool - indexed record pool
...
@@ -38,22 +39,26 @@
...
@@ -38,22 +39,26 @@
*
*
* This works exactly like numbers in a given base. Each map has base
* This works exactly like numbers in a given base. Each map has base
* size entries. For implementation convenience the base must be power
* size entries. For implementation convenience the base must be power
* of 2 and is given as its log2 value.
* of 2 between 2^1 and 2^15. It is given by its log2 value (1-15).
*
* A position in a map is also called a "digit".
*
*
* There is a doubly linked list of available maps (some free entries)
* There is a doubly linked list of available maps (some free entries)
* on each level. There is a singly linked free list within each map.
* on each level. There is a doubly linked freelist within each map.
* There is also a bitmask of used entries in each map.
*
*
* Level 0 free entry has space for one record. Level N free entry
* Level 0 free entry has space for one record. Level N free entry
* implies space for base^N records. The implied levels are created and
* implies space for base^N records. The implied levels are created and
* removed on demand.
Completely empty maps are
removed.
* removed on demand.
Empty maps are usually
removed.
*
*
* Default base is 256 (log2 = 8) which requires maximum 4 levels or
* Default base is 256 (log2 = 8) which requires maximum 4 levels or
*
"digits"
(similar to ip address).
*
digits
(similar to ip address).
*
*
* TODO
* TODO
*
*
* - move most of the inline code to LinearPool.cpp
* - move most of the inline code to LinearPool.cpp
* - add methods to check / seize user-specified index
* - optimize for common case
* - add optimized 2-level implementation (?)
*/
*/
#include "SuperPool.hpp"
#include "SuperPool.hpp"
...
@@ -71,6 +76,9 @@ class LinearPool {
...
@@ -71,6 +76,9 @@ class LinearPool {
// Max possible levels (0 to max root level).
// Max possible levels (0 to max root level).
STATIC_CONST
(
MaxLevels
=
(
32
+
LogBase
-
1
)
/
LogBase
);
STATIC_CONST
(
MaxLevels
=
(
32
+
LogBase
-
1
)
/
LogBase
);
// Number of words in map used bit mask.
STATIC_CONST
(
BitmaskSize
=
(
Base
+
31
)
/
32
);
// Map.
// Map.
struct
Map
{
struct
Map
{
Uint32
m_level
;
Uint32
m_level
;
...
@@ -80,6 +88,7 @@ class LinearPool {
...
@@ -80,6 +88,7 @@ class LinearPool {
Uint32
m_index
;
// from root to here
Uint32
m_index
;
// from root to here
PtrI
m_nextavail
;
PtrI
m_nextavail
;
PtrI
m_prevavail
;
PtrI
m_prevavail
;
Uint32
m_bitmask
[
BitmaskSize
];
PtrI
m_entry
[
Base
];
PtrI
m_entry
[
Base
];
};
};
...
@@ -97,9 +106,15 @@ public:
...
@@ -97,9 +106,15 @@ public:
// Allocate record from the pool. Reuses free index if possible.
// Allocate record from the pool. Reuses free index if possible.
bool
seize
(
Ptr
<
T
>&
ptr
);
bool
seize
(
Ptr
<
T
>&
ptr
);
// Allocate given index. Like seize but returns -1 if in use.
int
seize_index
(
Ptr
<
T
>&
ptr
,
Uint32
index
);
// Return record to the pool.
// Return record to the pool.
void
release
(
Ptr
<
T
>&
ptr
);
void
release
(
Ptr
<
T
>&
ptr
);
// Return number of used records (may require 1 page scan).
Uint32
count
();
// Verify (debugging).
// Verify (debugging).
void
verify
();
void
verify
();
...
@@ -114,6 +129,12 @@ private:
...
@@ -114,6 +129,12 @@ private:
// Add new non-root map.
// Add new non-root map.
bool
add_map
(
Ptr
<
Map
>&
map_ptr
,
Ptr
<
Map
>
parent_ptr
,
Uint32
digit
);
bool
add_map
(
Ptr
<
Map
>&
map_ptr
,
Ptr
<
Map
>
parent_ptr
,
Uint32
digit
);
// Subroutine to initialize map free lists.
void
init_free
(
Ptr
<
Map
>
map_ptr
);
// Add entry at given free position.
void
add_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
,
PtrI
ptr_i
);
// Remove entry and map if it becomes empty.
// Remove entry and map if it becomes empty.
void
remove_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
);
void
remove_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
);
...
@@ -126,8 +147,11 @@ private:
...
@@ -126,8 +147,11 @@ private:
// Remove map from available list.
// Remove map from available list.
void
remove_avail
(
Ptr
<
Map
>
map_ptr
);
void
remove_avail
(
Ptr
<
Map
>
map_ptr
);
// Verify available lists
void
verify_avail
();
// Verify map (recursive).
// Verify map (recursive).
void
verify
(
Ptr
<
Map
>
map_ptr
,
Uint32
level
);
void
verify
_map
(
Ptr
<
Map
>
map_ptr
,
Uint32
level
,
Uint32
*
count
);
RecordPool
<
T
>
m_records
;
RecordPool
<
T
>
m_records
;
RecordPool
<
Map
>
m_maps
;
RecordPool
<
Map
>
m_maps
;
...
@@ -166,6 +190,7 @@ LinearPool<T, LogBase>::getPtr(Ptr<T>& ptr)
...
@@ -166,6 +190,7 @@ LinearPool<T, LogBase>::getPtr(Ptr<T>& ptr)
// get record
// get record
Ptr
<
T
>
rec_ptr
;
Ptr
<
T
>
rec_ptr
;
Uint32
digit
=
index
&
DigitMask
;
Uint32
digit
=
index
&
DigitMask
;
assert
(
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
));
rec_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
digit
];
rec_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
digit
];
m_records
.
getPtr
(
rec_ptr
);
m_records
.
getPtr
(
rec_ptr
);
ptr
.
p
=
rec_ptr
.
p
;
ptr
.
p
=
rec_ptr
.
p
;
...
@@ -193,26 +218,20 @@ LinearPool<T, LogBase>::seize(Ptr<T>& ptr)
...
@@ -193,26 +218,20 @@ LinearPool<T, LogBase>::seize(Ptr<T>& ptr)
}
}
m_maps
.
getPtr
(
map_ptr
);
m_maps
.
getPtr
(
map_ptr
);
// walk down creating missing levels and using an entry on each
// walk down creating missing levels and using an entry on each
Uint32
firstfree
;
Uint32
digit
;
Ptr
<
Map
>
new_ptr
;
new_ptr
.
i
=
RNIL
;
while
(
true
)
{
while
(
true
)
{
assert
(
map_ptr
.
p
->
m_occup
<
Base
);
digit
=
map_ptr
.
p
->
m_firstfree
;
map_ptr
.
p
->
m_occup
++
;
firstfree
=
map_ptr
.
p
->
m_firstfree
;
assert
(
firstfree
<
Base
);
map_ptr
.
p
->
m_firstfree
=
map_ptr
.
p
->
m_entry
[
firstfree
];
if
(
map_ptr
.
p
->
m_occup
==
Base
)
{
assert
(
map_ptr
.
p
->
m_firstfree
==
Base
);
// remove from available list
remove_avail
(
map_ptr
);
}
if
(
n
==
0
)
if
(
n
==
0
)
break
;
break
;
Ptr
<
Map
>
child_ptr
;
Ptr
<
Map
>
child_ptr
;
if
(
!
add_map
(
child_ptr
,
map_ptr
,
firstfree
))
{
if
(
!
add_map
(
child_ptr
,
map_ptr
,
digit
))
{
remove_entry
(
map_ptr
,
firstfree
);
if
(
new_ptr
.
i
!=
RNIL
)
remove_map
(
new_ptr
);
return
false
;
return
false
;
}
}
map_ptr
.
p
->
m_entry
[
firstfree
]
=
child_ptr
.
i
;
new_ptr
=
child_ptr
;
map_ptr
=
child_ptr
;
map_ptr
=
child_ptr
;
n
--
;
n
--
;
}
}
...
@@ -220,11 +239,71 @@ LinearPool<T, LogBase>::seize(Ptr<T>& ptr)
...
@@ -220,11 +239,71 @@ LinearPool<T, LogBase>::seize(Ptr<T>& ptr)
assert
(
map_ptr
.
p
->
m_level
==
0
);
assert
(
map_ptr
.
p
->
m_level
==
0
);
Ptr
<
T
>
rec_ptr
;
Ptr
<
T
>
rec_ptr
;
if
(
!
m_records
.
seize
(
rec_ptr
))
{
if
(
!
m_records
.
seize
(
rec_ptr
))
{
remove_entry
(
map_ptr
,
firstfree
);
if
(
new_ptr
.
i
!=
RNIL
)
remove_map
(
new_ptr
);
return
false
;
return
false
;
}
}
map_ptr
.
p
->
m_entry
[
firstfree
]
=
rec_ptr
.
i
;
add_entry
(
map_ptr
,
digit
,
rec_ptr
.
i
);
ptr
.
i
=
firstfree
+
(
map_ptr
.
p
->
m_index
<<
LogBase
);
ptr
.
i
=
digit
+
(
map_ptr
.
p
->
m_index
<<
LogBase
);
ptr
.
p
=
rec_ptr
.
p
;
return
true
;
}
template
<
class
T
,
Uint32
LogBase
>
inline
int
LinearPool
<
T
,
LogBase
>::
seize_index
(
Ptr
<
T
>&
ptr
,
Uint32
index
)
{
// extract all digits at least up to current root level
Uint32
digits
[
MaxLevels
];
Uint32
n
=
0
;
Uint32
tmp
=
index
;
do
{
digits
[
n
]
=
tmp
&
DigitMask
;
tmp
>>=
LogBase
;
}
while
(
++
n
<
m_levels
||
tmp
!=
0
);
// add any new root levels
while
(
n
>
m_levels
)
{
if
(
!
add_root
())
return
false
;
}
// start from root
Ptr
<
Map
>
map_ptr
;
map_ptr
.
i
=
m_root
;
m_maps
.
getPtr
(
map_ptr
);
// walk down creating or re-using existing levels
Uint32
digit
;
bool
used
;
Ptr
<
Map
>
new_ptr
;
new_ptr
.
i
=
RNIL
;
while
(
true
)
{
digit
=
digits
[
--
n
];
used
=
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
);
if
(
n
==
0
)
break
;
if
(
used
)
{
map_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
digit
];
m_maps
.
getPtr
(
map_ptr
);
}
else
{
Ptr
<
Map
>
child_ptr
;
if
(
!
add_map
(
child_ptr
,
map_ptr
,
digit
))
{
if
(
new_ptr
.
i
!=
RNIL
)
remove_map
(
new_ptr
);
}
new_ptr
=
child_ptr
;
map_ptr
=
child_ptr
;
}
}
// now at level 0
assert
(
map_ptr
.
p
->
m_level
==
0
);
Ptr
<
T
>
rec_ptr
;
if
(
used
||
!
m_records
.
seize
(
rec_ptr
))
{
if
(
new_ptr
.
i
!=
RNIL
)
remove_map
(
new_ptr
);
return
used
?
-
1
:
false
;
}
add_entry
(
map_ptr
,
digit
,
rec_ptr
.
i
);
assert
(
index
==
digit
+
(
map_ptr
.
p
->
m_index
<<
LogBase
));
ptr
.
i
=
index
;
ptr
.
p
=
rec_ptr
.
p
;
ptr
.
p
=
rec_ptr
.
p
;
return
true
;
return
true
;
}
}
...
@@ -249,17 +328,32 @@ LinearPool<T, LogBase>::release(Ptr<T>& ptr)
...
@@ -249,17 +328,32 @@ LinearPool<T, LogBase>::release(Ptr<T>& ptr)
ptr
.
p
=
0
;
ptr
.
p
=
0
;
}
}
template
<
class
T
,
Uint32
LogBase
>
inline
Uint32
LinearPool
<
T
,
LogBase
>::
count
()
{
SuperPool
&
sp
=
m_records
.
m_superPool
;
Uint32
count1
=
sp
.
getRecUseCount
(
m_records
.
m_recInfo
);
return
count1
;
}
template
<
class
T
,
Uint32
LogBase
>
template
<
class
T
,
Uint32
LogBase
>
inline
void
inline
void
LinearPool
<
T
,
LogBase
>::
verify
()
LinearPool
<
T
,
LogBase
>::
verify
()
{
{
if
(
m_root
==
RNIL
)
verify_avail
();
if
(
m_root
==
RNIL
)
{
assert
(
m_levels
==
0
);
return
;
return
;
}
assert
(
m_levels
!=
0
);
assert
(
m_levels
!=
0
);
Ptr
<
Map
>
map_ptr
;
Ptr
<
Map
>
map_ptr
;
map_ptr
.
i
=
m_root
;
map_ptr
.
i
=
m_root
;
m_maps
.
getPtr
(
map_ptr
);
m_maps
.
getPtr
(
map_ptr
);
verify
(
map_ptr
,
m_levels
-
1
);
Uint32
count1
=
count
();
Uint32
count2
=
0
;
verify_map
(
map_ptr
,
m_levels
-
1
,
&
count2
);
assert
(
count1
==
count2
);
}
}
// private methods
// private methods
...
@@ -303,26 +397,18 @@ LinearPool<T, LogBase>::add_root()
...
@@ -303,26 +397,18 @@ LinearPool<T, LogBase>::add_root()
assert
(
n
<
MaxLevels
);
assert
(
n
<
MaxLevels
);
// set up
// set up
map_ptr
.
p
->
m_level
=
n
;
map_ptr
.
p
->
m_level
=
n
;
if
(
n
==
0
)
{
map_ptr
.
p
->
m_parent
=
RNIL
;
map_ptr
.
p
->
m_occup
=
0
;
map_ptr
.
p
->
m_index
=
0
;
map_ptr
.
p
->
m_firstfree
=
0
;
init_free
(
map_ptr
);
}
else
{
// on level > 0 digit 0 points to old root
// on level > 0 digit 0 points to old root
if
(
n
>
0
)
{
map_ptr
.
p
->
m_occup
=
1
;
map_ptr
.
p
->
m_firstfree
=
1
;
Ptr
<
Map
>
old_ptr
;
Ptr
<
Map
>
old_ptr
;
old_ptr
.
i
=
m_root
;
old_ptr
.
i
=
m_root
;
m_maps
.
getPtr
(
old_ptr
);
m_maps
.
getPtr
(
old_ptr
);
assert
(
old_ptr
.
p
->
m_parent
==
RNIL
);
assert
(
old_ptr
.
p
->
m_parent
==
RNIL
);
old_ptr
.
p
->
m_parent
=
map_ptr
.
i
;
old_ptr
.
p
->
m_parent
=
map_ptr
.
i
;
map_ptr
.
p
->
m_entry
[
0
]
=
old_ptr
.
i
;
add_entry
(
map_ptr
,
0
,
old_ptr
.
i
)
;
}
}
// set up free list with Base as terminator
for
(
Uint32
j
=
map_ptr
.
p
->
m_firstfree
;
j
<
Base
;
j
++
)
map_ptr
.
p
->
m_entry
[
j
]
=
j
+
1
;
map_ptr
.
p
->
m_parent
=
RNIL
;
map_ptr
.
p
->
m_index
=
0
;
add_avail
(
map_ptr
);
// set new root
// set new root
m_root
=
map_ptr
.
i
;
m_root
=
map_ptr
.
i
;
return
true
;
return
true
;
...
@@ -337,25 +423,81 @@ LinearPool<T, LogBase>::add_map(Ptr<Map>& map_ptr, Ptr<Map> parent_ptr, Uint32 d
...
@@ -337,25 +423,81 @@ LinearPool<T, LogBase>::add_map(Ptr<Map>& map_ptr, Ptr<Map> parent_ptr, Uint32 d
assert
(
parent_ptr
.
p
->
m_level
!=
0
);
assert
(
parent_ptr
.
p
->
m_level
!=
0
);
// set up
// set up
map_ptr
.
p
->
m_level
=
parent_ptr
.
p
->
m_level
-
1
;
map_ptr
.
p
->
m_level
=
parent_ptr
.
p
->
m_level
-
1
;
map_ptr
.
p
->
m_occup
=
0
;
map_ptr
.
p
->
m_firstfree
=
0
;
// set up free list with Base as terminator
for
(
Uint32
j
=
map_ptr
.
p
->
m_firstfree
;
j
<
Base
;
j
++
)
map_ptr
.
p
->
m_entry
[
j
]
=
j
+
1
;
map_ptr
.
p
->
m_parent
=
parent_ptr
.
i
;
map_ptr
.
p
->
m_parent
=
parent_ptr
.
i
;
map_ptr
.
p
->
m_index
=
digit
+
(
parent_ptr
.
p
->
m_index
<<
LogBase
);
map_ptr
.
p
->
m_index
=
digit
+
(
parent_ptr
.
p
->
m_index
<<
LogBase
);
add_avail
(
map_ptr
);
init_free
(
map_ptr
);
add_entry
(
parent_ptr
,
digit
,
map_ptr
.
i
);
return
true
;
return
true
;
}
}
template
<
class
T
,
Uint32
LogBase
>
inline
void
LinearPool
<
T
,
LogBase
>::
init_free
(
Ptr
<
Map
>
map_ptr
)
{
map_ptr
.
p
->
m_occup
=
0
;
map_ptr
.
p
->
m_firstfree
=
0
;
// freelist
Uint32
j
;
Uint16
back
=
ZNIL
;
for
(
j
=
0
;
j
<
Base
-
1
;
j
++
)
{
map_ptr
.
p
->
m_entry
[
j
]
=
back
|
((
j
+
1
)
<<
16
);
back
=
j
;
}
map_ptr
.
p
->
m_entry
[
j
]
=
back
|
(
ZNIL
<<
16
);
// bitmask
BitmaskImpl
::
clear
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
);
// add to available
add_avail
(
map_ptr
);
}
template
<
class
T
,
Uint32
LogBase
>
inline
void
LinearPool
<
T
,
LogBase
>::
add_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
,
PtrI
ptr_i
)
{
assert
(
map_ptr
.
p
->
m_occup
<
Base
&&
digit
<
Base
);
assert
(
!
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
));
// unlink from freelist
Uint32
val
=
map_ptr
.
p
->
m_entry
[
digit
];
Uint16
back
=
val
&
ZNIL
;
Uint16
forw
=
val
>>
16
;
if
(
back
!=
ZNIL
)
{
assert
(
back
<
Base
);
map_ptr
.
p
->
m_entry
[
back
]
&=
ZNIL
;
map_ptr
.
p
->
m_entry
[
back
]
|=
(
forw
<<
16
);
}
if
(
forw
!=
ZNIL
)
{
assert
(
forw
<
Base
);
map_ptr
.
p
->
m_entry
[
forw
]
&=
(
ZNIL
<<
16
);
map_ptr
.
p
->
m_entry
[
forw
]
|=
back
;
}
if
(
back
==
ZNIL
)
{
map_ptr
.
p
->
m_firstfree
=
forw
;
}
// set new value
map_ptr
.
p
->
m_entry
[
digit
]
=
ptr_i
;
map_ptr
.
p
->
m_occup
++
;
BitmaskImpl
::
set
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
);
if
(
map_ptr
.
p
->
m_occup
==
Base
)
remove_avail
(
map_ptr
);
}
template
<
class
T
,
Uint32
LogBase
>
template
<
class
T
,
Uint32
LogBase
>
inline
void
inline
void
LinearPool
<
T
,
LogBase
>::
remove_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
)
LinearPool
<
T
,
LogBase
>::
remove_entry
(
Ptr
<
Map
>
map_ptr
,
Uint32
digit
)
{
{
assert
(
map_ptr
.
p
->
m_occup
!=
0
&&
digit
<
Base
);
assert
(
map_ptr
.
p
->
m_occup
!=
0
&&
digit
<
Base
);
map_ptr
.
p
->
m_occup
--
;
assert
(
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
));
map_ptr
.
p
->
m_entry
[
digit
]
=
map_ptr
.
p
->
m_firstfree
;
// add to freelist
Uint32
firstfree
=
map_ptr
.
p
->
m_firstfree
;
map_ptr
.
p
->
m_entry
[
digit
]
=
ZNIL
|
(
firstfree
<<
16
);
if
(
firstfree
!=
ZNIL
)
{
assert
(
firstfree
<
Base
);
map_ptr
.
p
->
m_entry
[
firstfree
]
&=
(
ZNIL
<<
16
);
map_ptr
.
p
->
m_entry
[
firstfree
]
|=
digit
;
}
map_ptr
.
p
->
m_firstfree
=
digit
;
map_ptr
.
p
->
m_firstfree
=
digit
;
map_ptr
.
p
->
m_occup
--
;
BitmaskImpl
::
clear
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
digit
);
if
(
map_ptr
.
p
->
m_occup
+
1
==
Base
)
if
(
map_ptr
.
p
->
m_occup
+
1
==
Base
)
add_avail
(
map_ptr
);
add_avail
(
map_ptr
);
else
if
(
map_ptr
.
p
->
m_occup
==
0
)
else
if
(
map_ptr
.
p
->
m_occup
==
0
)
...
@@ -375,7 +517,7 @@ LinearPool<T, LogBase>::remove_map(Ptr<Map> map_ptr)
...
@@ -375,7 +517,7 @@ LinearPool<T, LogBase>::remove_map(Ptr<Map> map_ptr)
m_maps
.
release
(
map_ptr
);
m_maps
.
release
(
map_ptr
);
if
(
m_root
==
map_ptr_i
)
{
if
(
m_root
==
map_ptr_i
)
{
assert
(
parent_ptr
.
i
==
RNIL
);
assert
(
parent_ptr
.
i
==
RNIL
);
Uint32
used
=
m_maps
.
m_superPool
.
getRecUseCount
(
m_maps
.
m_recInfo
);
Uint32
used
=
count
(
);
assert
(
used
==
0
);
assert
(
used
==
0
);
m_root
=
RNIL
;
m_root
=
RNIL
;
m_levels
=
0
;
m_levels
=
0
;
...
@@ -431,49 +573,83 @@ LinearPool<T, LogBase>::remove_avail(Ptr<Map> map_ptr)
...
@@ -431,49 +573,83 @@ LinearPool<T, LogBase>::remove_avail(Ptr<Map> map_ptr)
template
<
class
T
,
Uint32
LogBase
>
template
<
class
T
,
Uint32
LogBase
>
inline
void
inline
void
LinearPool
<
T
,
LogBase
>::
verify
(
Ptr
<
Map
>
map_ptr
,
Uint32
level
)
LinearPool
<
T
,
LogBase
>::
verify_avail
()
{
// check available lists
for
(
Uint32
n
=
0
;
n
<
MaxLevels
;
n
++
)
{
Ptr
<
Map
>
map_ptr
;
map_ptr
.
i
=
m_avail
[
n
];
Uint32
back
=
RNIL
;
while
(
map_ptr
.
i
!=
RNIL
)
{
m_maps
.
getPtr
(
map_ptr
);
assert
(
map_ptr
.
p
->
m_occup
<
Base
);
assert
(
back
==
map_ptr
.
p
->
m_prevavail
);
back
=
map_ptr
.
i
;
map_ptr
.
i
=
map_ptr
.
p
->
m_nextavail
;
}
}
}
template
<
class
T
,
Uint32
LogBase
>
inline
void
LinearPool
<
T
,
LogBase
>::
verify_map
(
Ptr
<
Map
>
map_ptr
,
Uint32
level
,
Uint32
*
count
)
{
{
assert
(
level
<
MaxLevels
);
assert
(
level
<
MaxLevels
);
assert
(
map_ptr
.
p
->
m_level
==
level
);
assert
(
map_ptr
.
p
->
m_level
==
level
);
Uint32
j
=
0
;
// check freelist
while
(
j
<
Base
)
{
{
bool
free
=
false
;
Uint32
nused
=
BitmaskImpl
::
count
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
);
Uint32
j2
=
map_ptr
.
p
->
m_firstfree
;
assert
(
nused
<=
Base
);
while
(
j2
!=
Base
)
{
assert
(
map_ptr
.
p
->
m_occup
==
nused
);
if
(
j2
==
j
)
{
Uint32
nfree
=
0
;
free
=
true
;
Uint32
j
=
map_ptr
.
p
->
m_firstfree
;
break
;
Uint16
back
=
ZNIL
;
}
while
(
j
!=
ZNIL
)
{
assert
(
j2
<
Base
);
assert
(
j
<
Base
);
j2
=
map_ptr
.
p
->
m_entry
[
j2
];
assert
(
!
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
j
));
Uint32
val
=
map_ptr
.
p
->
m_entry
[
j
];
assert
(
back
==
(
val
&
ZNIL
));
back
=
j
;
j
=
(
val
>>
16
);
nfree
++
;
}
}
if
(
!
free
)
{
assert
(
nused
+
nfree
==
Base
);
}
// check entries
{
for
(
Uint32
j
=
0
;
j
<
Base
;
j
++
)
{
bool
free
=
!
BitmaskImpl
::
get
(
BitmaskSize
,
map_ptr
.
p
->
m_bitmask
,
j
);
if
(
free
)
continue
;
if
(
level
!=
0
)
{
if
(
level
!=
0
)
{
Ptr
<
Map
>
child_ptr
;
Ptr
<
Map
>
child_ptr
;
child_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
j
];
child_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
j
];
m_maps
.
getPtr
(
child_ptr
);
m_maps
.
getPtr
(
child_ptr
);
assert
(
child_ptr
.
p
->
m_parent
==
map_ptr
.
i
);
assert
(
child_ptr
.
p
->
m_parent
==
map_ptr
.
i
);
assert
(
child_ptr
.
p
->
m_index
==
j
+
(
map_ptr
.
p
->
m_index
<<
LogBase
));
assert
(
child_ptr
.
p
->
m_index
==
j
+
(
map_ptr
.
p
->
m_index
<<
LogBase
));
verify
(
child_ptr
,
level
-
1
);
verify
_map
(
child_ptr
,
level
-
1
,
count
);
}
else
{
}
else
{
Ptr
<
T
>
rec_ptr
;
Ptr
<
T
>
rec_ptr
;
rec_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
j
];
rec_ptr
.
i
=
map_ptr
.
p
->
m_entry
[
j
];
m_records
.
getPtr
(
rec_ptr
);
m_records
.
getPtr
(
rec_ptr
);
(
*
count
)
++
;
}
}
Ptr
<
Map
>
avail_ptr
;
}
avail_ptr
.
i
=
m_avail
[
map_ptr
.
p
->
m_level
];
}
bool
found
=
false
;
// check membership on available list
while
(
avail_ptr
.
i
!=
RNIL
)
{
{
if
(
avail_ptr
.
i
==
map_ptr
.
i
)
{
Ptr
<
Map
>
avail_ptr
;
found
=
true
;
avail_ptr
.
i
=
m_avail
[
map_ptr
.
p
->
m_level
];
break
;
bool
found
=
false
;
}
while
(
avail_ptr
.
i
!=
RNIL
)
{
m_maps
.
getPtr
(
avail_ptr
);
if
(
avail_ptr
.
i
==
map_ptr
.
i
)
{
avail_ptr
.
i
=
avail_ptr
.
p
->
m_nextavail
;
found
=
true
;
break
;
}
}
assert
(
found
==
(
map_ptr
.
p
->
m_occup
<
Base
));
m_maps
.
getPtr
(
avail_ptr
);
avail_ptr
.
i
=
avail_ptr
.
p
->
m_nextavail
;
}
}
j
++
;
assert
(
found
==
(
map_ptr
.
p
->
m_occup
<
Base
))
;
}
}
}
}
...
...
storage/ndb/src/kernel/vm/testSuperPool.cpp
View file @
7e4641bc
#if 0
#if 0
make -f Makefile -f - testSuperPool <<'_eof_'
make -f Makefile -f - testSuperPool <<'_eof_'
testSuperPool: testSuperPool.cpp libkernel.a
testSuperPool: testSuperPool.cpp libkernel.a
LinearPool.hpp
$(CXXCOMPILE) -o $@ $@.cpp libkernel.a -L../../common/util/.libs -lgeneral
$(CXXCOMPILE) -o $@ $@.cpp libkernel.a -L../../common/util/.libs -lgeneral
_eof_
_eof_
exit $?
exit $?
...
@@ -57,6 +57,7 @@ random_coprime(Uint32 n)
...
@@ -57,6 +57,7 @@ random_coprime(Uint32 n)
{
{
Uint32
prime
[]
=
{
101
,
211
,
307
,
401
,
503
,
601
,
701
,
809
,
907
};
Uint32
prime
[]
=
{
101
,
211
,
307
,
401
,
503
,
601
,
701
,
809
,
907
};
Uint32
count
=
sizeof
(
prime
)
/
sizeof
(
prime
[
0
]);
Uint32
count
=
sizeof
(
prime
)
/
sizeof
(
prime
[
0
]);
assert
(
n
!=
0
);
while
(
1
)
{
while
(
1
)
{
Uint32
i
=
urandom
(
count
);
Uint32
i
=
urandom
(
count
);
if
(
n
%
prime
[
i
]
!=
0
)
if
(
n
%
prime
[
i
]
!=
0
)
...
@@ -208,7 +209,7 @@ lp_test(GroupPool& gp)
...
@@ -208,7 +209,7 @@ lp_test(GroupPool& gp)
ndbout
<<
"linear pool test"
<<
endl
;
ndbout
<<
"linear pool test"
<<
endl
;
Ptr
<
T
>
ptr
;
Ptr
<
T
>
ptr
;
Uint32
loop
;
Uint32
loop
;
for
(
loop
=
0
;
loop
<
3
*
loopcount
;
loop
++
)
{
for
(
loop
=
0
;
loop
<
loopcount
;
loop
++
)
{
int
count
=
0
;
int
count
=
0
;
while
(
1
)
{
while
(
1
)
{
bool
ret
=
lp
.
seize
(
ptr
);
bool
ret
=
lp
.
seize
(
ptr
);
...
@@ -223,6 +224,7 @@ lp_test(GroupPool& gp)
...
@@ -223,6 +224,7 @@ lp_test(GroupPool& gp)
assert
(
ptr
.
p
==
ptr2
.
p
);
assert
(
ptr
.
p
==
ptr2
.
p
);
count
++
;
count
++
;
}
}
assert
(
count
!=
0
);
ndbout
<<
"seized "
<<
count
<<
endl
;
ndbout
<<
"seized "
<<
count
<<
endl
;
switch
(
loop
%
3
)
{
switch
(
loop
%
3
)
{
case
0
:
case
0
:
...
@@ -264,6 +266,47 @@ lp_test(GroupPool& gp)
...
@@ -264,6 +266,47 @@ lp_test(GroupPool& gp)
}
}
break
;
break
;
}
}
{
Uint32
cnt
=
lp
.
count
();
assert
(
cnt
==
0
);
}
// seize_index test
char
*
used
=
new
char
[
10
*
count
];
memset
(
used
,
false
,
sizeof
(
used
));
Uint32
i
,
ns
=
0
,
nr
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
Uint32
index
=
urandom
(
10
*
count
);
if
(
used
[
index
])
{
ptr
.
i
=
index
;
lp
.
release
(
ptr
);
lp
.
verify
();
nr
++
;
}
else
{
int
i
=
lp
.
seize_index
(
ptr
,
index
);
assert
(
i
>=
0
);
lp
.
verify
();
if
(
i
==
0
)
// no space
continue
;
assert
(
ptr
.
i
==
index
);
Ptr
<
T
>
ptr2
;
ptr2
.
i
=
ptr
.
i
;
ptr2
.
p
=
0
;
lp
.
getPtr
(
ptr2
);
assert
(
ptr
.
p
==
ptr2
.
p
);
ns
++
;
}
used
[
index
]
=
!
used
[
index
];
}
ndbout
<<
"random sparse seize "
<<
ns
<<
" release "
<<
nr
<<
endl
;
nr
=
0
;
for
(
i
=
0
;
i
<
10
*
count
;
i
++
)
{
if
(
used
[
i
])
{
ptr
.
i
=
i
;
lp
.
release
(
ptr
);
lp
.
verify
();
used
[
i
]
=
false
;
nr
++
;
}
}
ndbout
<<
"released "
<<
nr
<<
endl
;
{
Uint32
cnt
=
lp
.
count
();
assert
(
cnt
==
0
);
}
}
}
}
}
...
@@ -291,8 +334,10 @@ template static void sp_test<T5>(GroupPool& sp);
...
@@ -291,8 +334,10 @@ template static void sp_test<T5>(GroupPool& sp);
template
static
void
lp_test
<
T3
>(
GroupPool
&
sp
);
template
static
void
lp_test
<
T3
>(
GroupPool
&
sp
);
int
int
main
()
main
(
int
argc
,
char
**
argv
)
{
{
if
(
argc
>
1
&&
strncmp
(
argv
[
1
],
"-l"
,
2
)
==
0
)
loopcount
=
atoi
(
argv
[
1
]
+
2
);
HeapPool
sp
(
pageSize
,
pageBits
);
HeapPool
sp
(
pageSize
,
pageBits
);
sp
.
setInitPages
(
7
);
sp
.
setInitPages
(
7
);
sp
.
setMaxPages
(
7
);
sp
.
setMaxPages
(
7
);
...
@@ -304,7 +349,7 @@ main()
...
@@ -304,7 +349,7 @@ main()
ndbout
<<
"rand "
<<
s
<<
endl
;
ndbout
<<
"rand "
<<
s
<<
endl
;
int
count
;
int
count
;
count
=
0
;
count
=
0
;
while
(
++
count
<=
0
)
{
while
(
++
count
<=
0
)
{
// change to 1 to find new bug
sp_test
<
T1
>
(
gp
);
sp_test
<
T1
>
(
gp
);
sp_test
<
T2
>
(
gp
);
sp_test
<
T2
>
(
gp
);
sp_test
<
T3
>
(
gp
);
sp_test
<
T3
>
(
gp
);
...
...
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