mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
reorganizing repo
git-svn-id: svn://ultimatepp.org/upp/trunk@9206 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
7d17505cfe
commit
e3e8d627f5
3840 changed files with 0 additions and 1161578 deletions
|
|
@ -1,144 +0,0 @@
|
|||
// Solution to our pre-interview test.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Macros I can't do without anymore.
|
||||
|
||||
#define hope(x) while ( ! (x) ) { onIllegalOperation() ; }
|
||||
#define require(x) typedef char require[ (x) ? 1 : -1 ] ;
|
||||
|
||||
// Error handlers.
|
||||
|
||||
#define onOutOfMemory() do{ fprintf( stderr, "Out of memory!\n" ) ; exit( EXIT_FAILURE ) ; } while( 0 )
|
||||
#define onIllegalOperation() do{ fprintf( stderr, "Illegal Operation!\n" ) ; exit( EXIT_FAILURE ) ; } while( 0 )
|
||||
|
||||
// Typedefs.
|
||||
|
||||
typedef unsigned char byte ;
|
||||
typedef unsigned int uint ;
|
||||
|
||||
struct Q {
|
||||
uint first ;
|
||||
uint last ;
|
||||
} ;
|
||||
|
||||
// Constants.
|
||||
|
||||
const uint BLOCK_SIZE = 8 ;
|
||||
const uint BLOCK_MASK = BLOCK_SIZE - 1 ;
|
||||
const uint BLOCK_LAST = BLOCK_SIZE - 1 ;
|
||||
const uint TOTAL_SIZE = 2048 ;
|
||||
const uint BLOCK_COUNT = TOTAL_SIZE / BLOCK_SIZE ;
|
||||
|
||||
// The provided memory, and appropriate aliasing.
|
||||
//
|
||||
// Everything is split to 256 8byte blocks.
|
||||
//
|
||||
// Blocks 1-255 are used for both queues and data, block 0 for book-keeping of free blocks.
|
||||
// data[ 0 ] maintains single linked list of free blocks, while
|
||||
// data[ 1 ] keeps the index of the last block ever allocated.
|
||||
// Both used and free blocks are linked via their last byte.
|
||||
//
|
||||
// Note that array requires alignment to uint on some architectures,
|
||||
// which is simple to achieve with "aligned" attribute if necessary.
|
||||
// The alternative would be to use aligned memory within it ourselves.
|
||||
|
||||
byte data[ TOTAL_SIZE ] ;
|
||||
|
||||
#define queues ((Q *)(data))
|
||||
|
||||
require( sizeof( Q ) == BLOCK_SIZE ) ;
|
||||
|
||||
// Block management.
|
||||
|
||||
static byte allocate_block( void )
|
||||
{
|
||||
// Use one of the freed blocks, if possible.
|
||||
|
||||
byte block = data[ 0 ] ;
|
||||
if ( block ) {
|
||||
data[ 0 ] = data[ block * BLOCK_SIZE + BLOCK_LAST ] ;
|
||||
return block ;
|
||||
}
|
||||
|
||||
// Otherwise grab new block from the array, if possible.
|
||||
//
|
||||
// We can use an arguable trick that it will overflow in case we run out of blocks.
|
||||
// This may be considered either cool or entirely intorelable, depending on the point of view.
|
||||
|
||||
require( BLOCK_COUNT == 256 ) ;
|
||||
|
||||
block = ++data[ 1 ] ;
|
||||
if ( block ) {
|
||||
return block ;
|
||||
}
|
||||
|
||||
// Well, bad luck.
|
||||
|
||||
onOutOfMemory() ;
|
||||
}
|
||||
|
||||
static void free_block( const byte block )
|
||||
{
|
||||
hope( block > 0 ) ;
|
||||
hope( block < BLOCK_COUNT ) ;
|
||||
|
||||
data[ block * BLOCK_SIZE + BLOCK_LAST ] = data[ 0 ] ;
|
||||
data[ 0 ] = block ;
|
||||
}
|
||||
|
||||
// Queue methods themselves, each O(1).
|
||||
|
||||
Q * createQ( void )
|
||||
{
|
||||
Q * const q = queues + allocate_block() ;
|
||||
q->first = q->last = allocate_block() * BLOCK_SIZE ;
|
||||
return q ;
|
||||
}
|
||||
|
||||
void destroyQ( Q * q )
|
||||
{
|
||||
hope( q ) ;
|
||||
|
||||
data[ q->last | BLOCK_MASK ] = data[ 0 ] ;
|
||||
data[ 0 ] = q->first / BLOCK_SIZE ;
|
||||
|
||||
free_block( q - queues ) ;
|
||||
}
|
||||
|
||||
void enQ( Q * q, byte n )
|
||||
{
|
||||
hope( q ) ;
|
||||
|
||||
if ( q->last & BLOCK_MASK == BLOCK_LAST ) {
|
||||
const byte block = allocate_block() ;
|
||||
data[ q->last ] = block ;
|
||||
q->last = block * BLOCK_SIZE ;
|
||||
}
|
||||
data[ q->last++ ] = n ;
|
||||
}
|
||||
|
||||
byte deQ( Q * q )
|
||||
{
|
||||
hope( q ) ;
|
||||
|
||||
if ( q->first == q->last ) {
|
||||
onIllegalOperation() ;
|
||||
}
|
||||
if ( q->first & BLOCK_MASK == BLOCK_LAST ) {
|
||||
const byte block = data[ q->first ] ;
|
||||
free_block( q->first / BLOCK_SIZE ) ;
|
||||
q->first = block * BLOCK_SIZE ;
|
||||
}
|
||||
return data[ q->first++ ] ;
|
||||
}
|
||||
|
||||
void TestPatrik()
|
||||
{
|
||||
Q *q0 = createQ();
|
||||
for(int i = 0; i < 3000; i++) {
|
||||
DDUMP(i);
|
||||
enQ(q0, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
#include <Core/Core.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
// Note that it is totally MT broken.... (can only be used in single thread)
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
class Queue {
|
||||
struct Qitem {
|
||||
byte next;
|
||||
byte value[15];
|
||||
};
|
||||
static Qitem buffer[128];
|
||||
static int freelist;
|
||||
|
||||
byte head_q;
|
||||
byte head_i;
|
||||
byte tail_q;
|
||||
byte tail_i;
|
||||
|
||||
enum { NIL = 255 };
|
||||
|
||||
void Nil() { head_q = tail_i = NIL; }
|
||||
static void Free(int q);
|
||||
|
||||
public:
|
||||
bool IsEmpty() const { return head_q == NIL; }
|
||||
void Put(byte value);
|
||||
byte Get();
|
||||
|
||||
Queue();
|
||||
~Queue();
|
||||
};
|
||||
|
||||
Queue::Qitem Queue::buffer[128];
|
||||
int Queue::freelist = -1;
|
||||
|
||||
void Queue::Free(int q)
|
||||
{
|
||||
buffer[q].next = freelist;
|
||||
freelist = q;
|
||||
}
|
||||
|
||||
Queue::Queue()
|
||||
{
|
||||
if(freelist < 0) {
|
||||
buffer[0].next = NIL;
|
||||
for(int i = 1; i < 128; i++)
|
||||
buffer[i].next = i - 1;
|
||||
freelist = 127;
|
||||
}
|
||||
Nil();
|
||||
}
|
||||
|
||||
Queue::~Queue()
|
||||
{
|
||||
int q = head_q;
|
||||
while(q != NIL) {
|
||||
int w = q;
|
||||
q = buffer[q].next;
|
||||
Free(w);
|
||||
}
|
||||
}
|
||||
|
||||
void Queue::Put(byte value)
|
||||
{
|
||||
Qitem *m;
|
||||
if(tail_i >= 15) {
|
||||
if(freelist == NIL)
|
||||
Panic("Out of memory");
|
||||
int q = freelist;
|
||||
freelist = buffer[freelist].next;
|
||||
if(IsEmpty()) {
|
||||
head_q = q;
|
||||
head_i = 0;
|
||||
}
|
||||
else
|
||||
buffer[tail_q].next = q;
|
||||
tail_q = q;
|
||||
tail_i = 0;
|
||||
m = &buffer[q];
|
||||
m->next = NIL;
|
||||
}
|
||||
else
|
||||
m = &buffer[tail_q];
|
||||
m->value[tail_i++] = value;
|
||||
}
|
||||
|
||||
byte Queue::Get()
|
||||
{
|
||||
ASSERT(!IsEmpty());
|
||||
if(head_i >= 15) {
|
||||
int q = head_q;
|
||||
head_q = buffer[head_q].next;
|
||||
head_i = 0;
|
||||
Free(q);
|
||||
}
|
||||
int val = buffer[head_q].value[head_i++];
|
||||
if(head_q == tail_q && head_i == tail_i) {
|
||||
Free(head_q);
|
||||
Nil();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
{
|
||||
BiVector<byte> ref[16];
|
||||
Queue q[16];
|
||||
int total = 0;
|
||||
for(int i = 0; i < 100000000; i++) {
|
||||
if(i % 1000000 == 0)
|
||||
Cout() << i << '\n';
|
||||
int ii = Random() & 15;
|
||||
if((Random() & 65535) < 32900 && total < 128 * 10) {
|
||||
total++;
|
||||
byte v = (byte)Random();
|
||||
q[ii].Put(v);
|
||||
ref[ii].AddTail(v);
|
||||
DDUMP(total);
|
||||
}
|
||||
else
|
||||
if(!q[ii].IsEmpty()) {
|
||||
total--;
|
||||
ASSERT(q[ii].Get() == ref[ii].Head());
|
||||
ref[ii].DropHead();
|
||||
if(q[ii].IsEmpty())
|
||||
LOG("Empty!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
Queue a, b;
|
||||
for(int i = 0; i < 500; i++) {
|
||||
a.Put(i);
|
||||
for(int j = 0; j < 500; j++)
|
||||
b.Put(j);
|
||||
for(int j = 0; j < 500; j++)
|
||||
ASSERT((byte)j == b.Get());
|
||||
}
|
||||
for(int i = 0; i < 500; i++)
|
||||
ASSERT(a.Get() == (byte)i);
|
||||
}
|
||||
Queue a1;
|
||||
for(int i = 0; i < 128 * 15; i++)
|
||||
a1.Put(i);
|
||||
for(int i = 0; i < 128 * 15; i++)
|
||||
DUMP((int)a1.Get());
|
||||
for(int i = 0; i < 128 * 15; i++)
|
||||
a1.Put(i);
|
||||
for(int i = 0; i < 128 * 15; i++)
|
||||
DUMP((int)a1.Get());
|
||||
}
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
Patrik.cpp,
|
||||
Queue.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#ifndef _Queue_icpp_init_stub
|
||||
#define _Queue_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue