鸿 记5d13.cn

a programer log.

Home work python

一个用python写类unix进程id分配器

一个用python写类unix进程id分配器

By 鸿记

可用于一些需要在有限的号码区间内分配唯一ID的应用,如游戏里的房间号、在线客户ID等

firePhoenix项目里需要给连接的客户端分配一个唯一的客户ID,类似socketid、系统进程ID(pid),于是模拟linux PID的分配算法实现一个ID分配器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
class IDAllocor(object):
    '''分配一个唯一的ID,如clientID,pid'''

<span class="c">#上次分配的ID</span>
<span class="n">_lastID</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>

<span class="c">#map页,用于指示某个ID是否分配</span>
<span class="n">_page</span> <span class="o">=</span> <span class="s">""</span>

<span class="c">#最大可分配的ID</span>
<span class="n">_maxID</span> <span class="o">=</span> <span class="mi">32767</span>

<span class="n">_free</span> <span class="o">=</span> <span class="mi">0</span>

<span class="c">#是否第一遍扫描</span>
<span class="n">_first</span> <span class="o">=</span> <span class="mi">1</span>

<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">maxid</span><span class="o">=</span><span class="mi">32767</span><span class="p">,</span><span class="n">page</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_maxID</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_free</span> <span class="o">=</span> <span class="n">maxid</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_lastID</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
    <span class="k">if</span> <span class="n">page</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_page</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">_maxID</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">32</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_page</span> <span class="o">=</span> <span class="n">page</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_first</span> <span class="o">=</span> <span class="mi">1</span>

<span class="k">def</span> <span class="nf">_setBit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">offset</span><span class="p">,</span><span class="n">value</span><span class="p">):</span>
    <span class="s">'''设置offset位值,0或1'''</span>
    <span class="n">bit_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&amp;</span> <span class="mh">0x1f</span>
    <span class="n">int_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&gt;&gt;</span> <span class="mi">5</span>

    <span class="k">if</span> <span class="n">value</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">|</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">bit_off</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">&amp;</span> <span class="p">(</span><span class="o">~</span><span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">bit_off</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">offset</span><span class="p">):</span>
    <span class="s">'''取offset的位的状态'''</span>
    <span class="n">bit_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&amp;</span> <span class="mh">0x1f</span>
    <span class="n">int_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&gt;&gt;</span> <span class="mi">5</span>

    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">bit_off</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">_findFree</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">offset</span><span class="p">):</span>
    <span class="s">'''扫描map,返回一个为0的位'''</span>
    <span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_maxID</span>
    <span class="n">page</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_page</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">offset</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">):</span>
        <span class="n">bit_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&amp;</span> <span class="mh">0x1f</span>
        <span class="n">int_off</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">&gt;&gt;</span> <span class="mi">5</span>

        <span class="k">if</span> <span class="n">page</span><span class="p">[</span><span class="n">int_off</span><span class="p">]</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">bit_off</span><span class="p">):</span>
            <span class="n">offset</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">continue</span>

        <span class="k">return</span> <span class="n">offset</span>

    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span>

<span class="k">def</span> <span class="nf">alloc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="s">'''分配一个ID,如果没有可分配的ID 了,就返回-1'''</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_free</span><span class="p">:</span>
        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">_lastID</span> <span class="o">+=</span> <span class="mi">1</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_free</span> <span class="o">-=</span> <span class="mi">1</span>

    <span class="c">#if self._first:</span>
    <span class="c">#    #如果还没有将整个区间分配过一遍,就先顺序分配</span>
    <span class="c">#    if self._lastID &lt;= self._maxID:</span>
    <span class="c">#        self._setBit(self._lastID,1)</span>
    <span class="c">#        return self._lastID</span>

    <span class="c">#    self._first = 0</span>
    <span class="c">#    self._lastID = 0</span>

    <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lastID</span> <span class="o">&amp;</span> <span class="bp">self</span><span class="o">.</span><span class="n">_maxID</span>

    <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_findFree</span><span class="p">(</span><span class="n">offset</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">offset</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
        <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_findFree</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">offset</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
            <span class="k">return</span> <span class="o">-</span><span class="mi">1</span>

    <span class="bp">self</span><span class="o">.</span><span class="n">_setBit</span><span class="p">(</span><span class="n">offset</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_lastID</span> <span class="o">=</span> <span class="n">offset</span>

    <span class="k">return</span> <span class="n">offset</span>

<span class="k">def</span> <span class="nf">free</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">offset</span><span class="p">):</span>
    <span class="s">'''回收ID'''</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_setBit</span><span class="p">(</span><span class="n">offset</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_free</span> <span class="o">+=</span> <span class="mi">1</span>

if name == 'main': import random,codecs

<span class="n">alloc</span> <span class="o">=</span> <span class="n">IDAllocor</span><span class="p">(</span><span class="mi">32767</span><span class="p">)</span>

<span class="n">f</span> <span class="o">=</span> <span class="n">codecs</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="s">'d:</span><span class="se">\\</span><span class="s">testallocid.csv'</span> <span class="p">,</span> <span class="s">"a"</span><span class="p">,</span> <span class="s">"utf-8"</span><span class="p">)</span>
<span class="n">co</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">100000</span><span class="p">):</span>
    <span class="n">id0</span> <span class="o">=</span> <span class="n">alloc</span><span class="o">.</span><span class="n">alloc</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">id0</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
        <span class="k">break</span>

    <span class="k">print</span> <span class="n">id0</span>
    <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'insert into ids (id) value (</span><span class="si">%</span><span class="s">s);'</span> <span class="o">%</span> <span class="p">(</span><span class="n">id0</span><span class="p">))</span>
    <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>

    <span class="n">co</span> <span class="o">+=</span> <span class="mi">1</span>
    <span class="k">if</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">100</span><span class="p">)</span> <span class="o">&lt;</span><span class="mi">50</span><span class="p">:</span>
        <span class="n">alloc</span><span class="o">.</span><span class="n">free</span><span class="p">(</span><span class="n">id0</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'delete from ids where id=</span><span class="si">%</span><span class="s">s;'</span> <span class="o">%</span> <span class="p">(</span><span class="n">id0</span><span class="p">))</span>

<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">print</span> <span class="n">alloc</span><span class="o">.</span><span class="n">_free</span>
<span class="k">print</span> <span class="s">'co = '</span><span class="p">,</span><span class="n">co</span><span class="w">

孙铭鸿logo
by 鸿记

声明:本站文章除注明转载外,均为本站原创或者翻译。
本文采用 署名-非商业性使用-相同方式共享(BY-NC-SA) 协议进行授权。
转载请注明转自: 【鸿记】一个用python写类unix进程id分配器

Fork me on GitHub