[pypy-commit] pypy gc-incminimark-pinning: added sort() to AddressStack using fijal's work in gc-minimark-pinning
groggi
noreply at buildbot.pypy.org
Mon Jun 2 17:23:53 CEST 2014
Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning
Changeset: r71815:cc3d72cc6edb
Date: 2014-05-12 16:04 +0200
http://bitbucket.org/pypy/pypy/changeset/cc3d72cc6edb/
Log: added sort() to AddressStack using fijal's work in gc-minimark-
pinning
This was implemented by Maciej Fijalkowski in the gc-minimark-
pinning branch. See commits:
* 3ada686cfd218cac6f08e857c9cb4ec43cd68102
* d4a2fdd9a4ac012675a7a29b10364cb0db079954
diff --git a/rpython/memory/support.py b/rpython/memory/support.py
--- a/rpython/memory/support.py
+++ b/rpython/memory/support.py
@@ -58,7 +58,30 @@
unused_chunks = FreeList()
cache[chunk_size] = unused_chunks, null_chunk
- return unused_chunks, null_chunk
+
+ def partition(array, left, right):
+ last_item = array[right]
+ pivot = last_item
+ storeindex = left
+ for i in range(left, right):
+ if array[i] >= pivot:
+ array[i], array[storeindex] = array[storeindex], array[i]
+ storeindex += 1
+ # Move pivot to its final place
+ array[storeindex], array[right] = last_item, array[storeindex]
+ return storeindex
+
+ def quicksort(array, left, right):
+ # sort array[left:right+1] (i.e. bounds included)
+ if right > left:
+ pivotnewindex = partition(array, left, right)
+ quicksort(array, left, pivotnewindex - 1)
+ quicksort(array, pivotnewindex + 1, right)
+
+ def sort_chunk(chunk, size):
+ quicksort(chunk.items, 0, size - 1)
+
+ return unused_chunks, null_chunk, sort_chunk
def get_address_stack(chunk_size=DEFAULT_CHUNK_SIZE, cache={}):
@@ -67,7 +90,7 @@
except KeyError:
pass
- unused_chunks, null_chunk = get_chunk_manager(chunk_size)
+ unused_chunks, null_chunk, sort_chunk = get_chunk_manager(chunk_size)
class AddressStack(object):
_alloc_flavor_ = "raw"
@@ -174,6 +197,13 @@
chunk.items[count] = got
got = next
+ def sort(self):
+ """Sorts the items in the AddressStack. They must not be more
+ than one chunk of them. This results in a **reverse** order,
+ so that the first pop()ped items are the smallest ones."""
+ ll_assert(self.chunk.next == null_chunk, "too big for sorting")
+ sort_chunk(self.chunk, self.used_in_last_chunk)
+
cache[chunk_size] = AddressStack
return AddressStack
diff --git a/rpython/memory/test/test_support.py b/rpython/memory/test/test_support.py
--- a/rpython/memory/test/test_support.py
+++ b/rpython/memory/test/test_support.py
@@ -3,9 +3,11 @@
from rpython.memory.support import get_address_deque
from rpython.rtyper.test.test_llinterp import interpret
-from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper.lltypesystem import lltype, llmemory, llarena
from rpython.rtyper.lltypesystem.llmemory import raw_malloc, raw_free, NULL
+import random
+
class TestAddressStack(object):
def test_simple_access(self):
AddressStack = get_address_stack()
@@ -106,6 +108,23 @@
assert b == a
assert ll.length() == i
+ def test_sort(self):
+ AddressStack = get_address_stack(chunk_size=15)
+ lla = llarena.arena_malloc(10, 2)
+ addrs = [lla + i for i in range(10)]
+ for _ in range(13):
+ ll = AddressStack()
+ addr_copy = addrs[:]
+ random.shuffle(addr_copy)
+ for i in addr_copy:
+ ll.append(i)
+ ll.sort()
+ expected = range(10)
+ for i in expected:
+ a = ll.pop()
+ assert a == addrs[i]
+
+
class TestAddressDeque:
def test_big_access(self):
More information about the pypy-commit
mailing list