zoukankan
html css js c++ java
MemMan beta 3
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEMMAN__
#define
__MEMMAN__
#include
<
malloc.h
>
#pragma pack(push,
1
)
namespace
mem
{
#define
mem_inline __forceinline
#define
mem_pool_pad 16
#define
mem_page_pad 48
#define
mem_page_size ( 1 << 18 )
#define
mem_align_size 16
#define
mem_align __declspec( align( mem_align_size ) )
typedef unsigned
int
prior_type;
typedef unsigned
long
time_type;
typedef unsigned
long
size_type;
typedef unsigned
char
byte
;
#define
mem_max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
#define
mem_min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
enum
{
ENTRY_PRIORITY
=
0
,
}
;
class
heap
{
public
:
mem_inline heap( size_type max_size )
{
allocated_size
=
0
;
available_size
=
max_size;
}
mem_inline
~
heap()
{
}
mem_inline
void
*
alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline
void
*
aligned_alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_aligned_alloc( size );
}
mem_inline
void
aligned_dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_aligned_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline size_type available()
{
return
available_size;
}
private
:
mem_inline
void
*
sys_alloc( size_type size )
{
return
malloc( size );
}
mem_inline
void
sys_dealloc(
void
*
ptr )
{
free( ptr );
}
mem_inline
void
*
sys_aligned_alloc( size_type size )
{
return
_aligned_malloc( size, mem_align_size );
}
mem_inline
void
sys_aligned_dealloc(
void
*
ptr )
{
_aligned_free( ptr );
}
private
:
size_type allocated_size,
available_size;
}
;
template
<
typename ALLOC
>
class
pool
{
private
:
class
page
{
public
:
mem_inline page( size_type _size, page
*
old )
{
base
=
get_base();
_next
=
old;
size
=
_size;
}
mem_inline
byte
*
get_base()
{
return
( (
byte
*
)
this
+
sizeof
(page) );
}
mem_inline size_type get_size()
{
return
static_cast
<
size_type
>
(
base
-
get_base()
+
size );
}
mem_inline size_type available()
{
return
size;
}
mem_inline
void
*
alloc( size_type _size )
{
byte
*
ptr
=
base
;
base
+=
_size;
size
-=
_size;
return
ptr;
}
mem_inline page
*
next()
{
return
_next;
}
private
:
mem_align union
{
struct
{
byte
*
base
;
page
*
_next;
size_type size;
}
;
byte
pad[mem_pool_pad];
}
;
}
;
class
chunk
{
public
:
mem_inline chunk( size_type _size, chunk
*
old )
{
next
=
old;
size
=
_size;
}
mem_inline size_type available()
{
return
size;
}
public
:
chunk
*
next;
size_type size;
}
;
public
:
mem_inline pool()
{
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
}
mem_inline
~
pool()
{
destory();
}
mem_inline
void
destory()
{
page
*
p;
while
( ( p
=
pages )
!=
NULL )
{
pages
=
p
->
next();
al.dealloc( p, p
->
get_size() );
}
pages
=
NULL;
chunks
=
NULL;
}
mem_inline
bool
search_chunk(
void
*
&
ptr, size_type size )
{
if
( chunks
&&
( size
<=
chunks
->
available() ) )
{
ptr
=
(
void
*
) chunks;
chunks
=
chunks
->
next;
return
true
;
}
else
return
false
;
}
mem_inline
bool
search_page(
void
*
&
ptr, size_type size )
{
if
( pages
&&
( size
<=
pages
->
available() ) )
{
ptr
=
pages
->
alloc( size );
return
true
;
}
else
return
false
;
}
mem_inline
void
allocate_page( size_type size )
{
size_type asize
=
mem_max( size, mem_page_size );
pages
=
new
(al.alloc(
sizeof
(page)
+
asize )) page( asize, pages );
}
mem_inline
void
*
alloc( size_type size )
{
void
*
ptr;
++
allocated;
if
( search_chunk( ptr, size ) )
return
ptr;
else
if
( search_page( ptr, size ) )
return
ptr;
else
{
allocate_page( size );
if
( search_page( ptr, size ) )
return
ptr;
else
return
NULL;
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
--
allocated;
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
private
:
page
*
pages;
chunk
*
chunks;
size_type allocated;
ALLOC al;
}
;
template
<
typename ALLOC
>
class
cache
{
public
:
class
node;
class
entry
{
public
:
mem_inline entry()
{
priority
=
ENTRY_PRIORITY;
last_use_time
=
pl.get_current_time();
locked
=
false
;
node_ptr
=
NULL;
}
mem_inline
virtual
~
entry()
{
}
mem_inline
void
*
alloc( size_type size )
{
return
pl.alloc( size,
this
);
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
pl.dealloc( ptr, size,
this
);
}
mem_inline
void
stream_begin()
{
locked
=
true
;
stream_in();
last_use_time
=
pl.get_current_time();
}
mem_inline
void
stream_end()
{
locked
=
false
;
}
mem_inline
bool
is_locked()
{
return
locked;
}
mem_inline
bool
operator
<
(
const
entry
&
right )
const
{
if
( priority
==
right.priority )
return
( last_use_time
<
right.last_use_time );
else
return
( priority
<
right.priority );
}
public
:
#ifdef _DEBUG
virtual
void
stream_in()
=
0
;
#endif
virtual
bool
stream_out(
void
*
&
ptr, size_type size )
=
0
;
public
:
static
cache
<
ALLOC
>
pl;
prior_type priority;
time_type last_use_time;
bool
locked;
node
*
node_ptr;
}
;
class
node
{
public
:
mem_inline node( entry
*
obj, node
*
old, node
*
g_old, node
*
phead, node
*
g_phead )
{
ptr
=
obj;
obj
->
node_ptr
=
this
;
next
=
old;
prev
=
phead;
g_next
=
g_old;
g_prev
=
g_phead;
if
( next )
next
->
prev
=
this
;
if
( prev )
prev
->
next
=
this
;
if
( g_next )
g_next
->
g_prev
=
this
;
if
( g_prev )
g_prev
->
g_next
=
this
;
}
mem_inline node()
{
ptr
=
NULL;
next
=
NULL;
prev
=
NULL;
g_next
=
NULL;
g_prev
=
NULL;
}
mem_inline
~
node()
{
void
*
p
=
NULL;
stream_out( p,
0
);
}
mem_inline time_type get_last_use_time()
{
if
( ptr )
return
ptr
->
last_use_time;
else
return
0
;
}
mem_inline
bool
is_locked()
{
if
( ptr )
return
ptr
->
is_locked();
else
return
false
;
}
mem_inline
bool
stream_out(
void
*
&
p, size_type size )
{
if
( ptr )
{
bool
bret
=
ptr
->
stream_out( p, size );
if
( bret )
ptr
->
node_ptr
=
NULL;
return
bret;
}
else
return
false
;
}
mem_inline
void
detach()
{
if
( prev )
prev
->
next
=
next;
if
( next )
next
->
prev
=
prev;
if
( g_prev )
g_prev
->
g_next
=
g_next;
if
( g_next )
g_next
->
g_prev
=
g_prev;
}
public
:
entry
*
ptr;
node
*
next,
*
prev;
node
*
g_next,
*
g_prev;
}
;
class
page
{
public
:
mem_inline page( size_type _size, page
*
old )
{
size
=
_size;
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
num_nodes
=
0
;
}
mem_inline
~
page()
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
detach();
delete p;
p
=
head.next;
}
}
mem_inline
void
recycle( page
*
old )
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
detach();
delete p;
p
=
head.next;
}
head.next
=
NULL;
size
=
get_size();
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
num_nodes
=
0
;
}
mem_inline
byte
*
get_base()
{
return
(
byte
*
)
this
+
sizeof
(page);
}
mem_inline size_type get_size()
{
return
static_cast
<
size_type
>
(
base
-
get_base()
+
size );
}
mem_inline size_type available()
{
return
size;
}
mem_inline
void
*
alloc( size_type req_size )
{
void
*
ptr
=
(
void
*
)
base
;
base
+=
req_size;
size
-=
req_size;
return
ptr;
}
mem_inline time_type priority()
const
{
time_type last_use_time
=
0
;
node
*
p
=
head.next;
while
( p )
{
last_use_time
+=
p
->
get_last_use_time();
p
=
p
->
next;
}
if
( num_nodes
!=
0
)
last_use_time
/=
static_cast
<
time_type
>
( num_nodes );
return
last_use_time;
}
mem_inline
bool
operator
<
(
const
page
&
right )
const
{
return
( priority()
<
right.priority() );
}
public
:
mem_align union
{
struct
{
byte
*
base
;
page
*
next;
page
*
prev;
size_type size;
node head;
size_type num_nodes;
}
;
byte
pad[mem_page_pad];
}
;
}
;
class
chunk
{
public
:
mem_inline chunk( size_type _size, chunk
*
old )
{
size
=
_size;
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline size_type available()
{
return
size;
}
public
:
chunk
*
next;
chunk
*
prev;
size_type size;
}
;
public
:
mem_inline cache()
{
current_time
=
0
;
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
}
mem_inline
~
cache()
{
destory();
}
mem_inline time_type get_current_time()
{
return
(
++
current_time );
}
mem_inline
void
*
alloc( size_type size, entry
*
obj )
{
void
*
ptr
=
NULL;
++
allocated;
obj
->
node_ptr
=
NULL;
if
( search_chunk( ptr, size ) )
return
ptr;
else
if
( search_page( ptr, size, obj ) )
return
ptr;
else
if
( (size
+
sizeof
(page))
>
al.available() )
{
if
( search_entry( ptr, size, obj ) )
return
ptr;
else
{
recycle_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
else
{
allocate_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size, entry
*
obj )
{
--
allocated;
if
( obj
->
node_ptr )
{
obj
->
node_ptr
->
detach();
obj
->
node_ptr
->~
node();
node_pool.dealloc( obj
->
node_ptr,
sizeof
(node) );
obj
->
node_ptr
=
NULL;
}
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
private
:
mem_inline
void
destory()
{
page
*
p
=
pages;
while
( p )
{
pages
=
p
->
next;
p
->~
page();
al.dealloc( p, p
->
get_size() );
p
=
pages;
}
chunks
=
NULL;
}
mem_inline
bool
search_chunk(
void
*
&
ptr, size_type size )
{
chunk
*
p
=
chunks;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
(
void
*
) p;
if
( p
->
prev )
p
->
prev
->
next
=
p
->
next;
if
( p
->
next )
p
->
next
->
prev
=
p
->
prev;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_page(
void
*
&
ptr, size_type size, entry
*
obj )
{
page
*
p
=
pages;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
p
->
alloc( size );
new
(node_pool.alloc(
sizeof
(node) )) node( obj, p
->
head.next, g_head.g_next,
&
p
->
head,
&
g_head );
++
p
->
num_nodes;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline node
*
node_sort( node
*
p )
{
return
p;
}
mem_inline
bool
search_entry(
void
*
&
ptr, size_type size, entry
*
obj )
{
g_head.g_next
=
node_sort( g_head.g_next );
node
*
p
=
g_head.g_next;
while
( p )
{
if
(
!
p
->
is_locked()
&&
p
->
stream_out( ptr, size ) )
{
p
->
ptr
=
obj;
obj
->
node_ptr
=
p;
return
true
;
}
p
=
p
->
g_next;
}
return
false
;
}
mem_inline
void
recycle_page( size_type size )
{
if
( pages )
{
page
*
p,
*
old;
old
=
pages;
p
=
pages
->
next;
while
( p )
{
if
(
*
p
<
*
old )
old
=
p;
p
=
p
->
next;
}
if
( old
!=
pages )
{
if
( old
->
prev )
old
->
prev
->
next
=
old
->
next;
if
( old
->
next )
old
->
next
->
prev
=
old
->
prev;
old
->
recycle( pages );
pages
=
old;
}
}
}
mem_inline
void
allocate_page( size_type size )
{
size_type asize
=
mem_min( mem_max(
sizeof
(page)
+
size, mem_page_size ), al.available() );
pages
=
new
(al.alloc( asize )) page( asize
-
sizeof
(page), pages );
}
private
:
time_type current_time;
time_type allocated;
ALLOC al;
node g_head;
page
*
pages;
chunk
*
chunks;
pool
<
ALLOC
>
node_pool;
}
;
class
man
{
public
:
mem_inline man()
{
m_heap
=
NULL;
upl
=
NULL;
apl
=
NULL;
}
mem_inline
~
man()
{
if
( apl )
delete apl;
if
( upl )
delete upl;
if
( m_heap )
delete m_heap;
}
mem_inline
void
begin( size_type heap_size )
{
m_heap
=
new
heap( heap_size );
upl
=
new
pool
<
allocator
>
;
apl
=
new
pool
<
aligned_allocator
>
;
}
mem_inline
void
end()
{
delete apl;
apl
=
NULL;
delete upl;
upl
=
NULL;
delete m_heap;
m_heap
=
NULL;
}
mem_inline
void
*
alloc( size_type size )
{
return
upl
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
return
upl
->
dealloc( ptr, size );
}
mem_inline
void
*
aligned_alloc( size_type size )
{
return
apl
->
alloc( size );
}
mem_inline
void
aligned_dealloc(
void
*
ptr, size_type size )
{
return
apl
->
dealloc( ptr, size );
}
public
:
static
heap
*
m_heap;
public
:
class
allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
dealloc( ptr, size );
}
mem_inline size_type available()
{
return
m_heap
->
available();
}
}
;
class
aligned_allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
aligned_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
aligned_dealloc( ptr, size );
}
mem_inline size_type available()
{
return
m_heap
->
available();
}
}
;
public
:
pool
<
allocator
>
*
upl;
pool
<
aligned_allocator
>
*
apl;
}
;
typedef cache
<
man::allocator
>
::entry resource;
typedef cache
<
man::aligned_allocator
>
::entry aligned_resource;
}
//
namespace mem
extern
mem::man memman;
#pragma pack(pop)
#endif
//
__MEMMAN__
查看全文
相关阅读:
SDUT 2109 找女朋友
Instant Complexity(模拟,递归)
Lucky and Good Months by Gregorian Calendar(模拟)
Wall(Graham算法)
Beauty Contest(graham求凸包算法)
A Round Peg in a Ground Hole(判断是否是凸包,点是否在凸包内,圆与多边形的关系)
Pie(二分)
Expanding Rods(二分)
Fishnet(计算几何)
Building a Space Station(kruskal,说好的数论呢)
原文地址:https://www.cnblogs.com/len3d/p/990867.html
最新文章
Maya Calendar
hdu 5055 Bob and math problem
codeforces C. Booking System
codeforces D.Mashmokh and ACM
codeforces C. Mashmokh and Numbers
codeforces D. Long Path
codeforces Toy Sum
codeforces Minesweeper 1D
codeforces C. Triangle
codeforces Unusual Product
热门文章
codeforces C. Restore Graph
POJ3080 Blue Jeans
POJ 3687 Labeling Balls
POJ 3041 Asteroids
POJ 3026 Borg Maze 普利姆 + BFS
POJ1789 Truck History 最小生成树 + 路径压缩
POJ2253 Frogger
POJ 1062 昂贵的聘礼
BFS + 状态压缩 POJ 2965 The Pilots Brothers' refrigerator
Poj 1753 Flip Game 状态压缩 + DFS
Copyright © 2011-2022 走看看