reorx
10/28/2011 - 4:17 AM

os_memory

os_memory

#!/usr/bin/python
#coding=utf8

import sys
from utils import directSelectSort, col_decorate, BaseError

class MEMStoreError(BaseError):
    pass

class InputError(BaseError):
    pass


class Elem(object):
    def __init__(self, name, s, e):
        self.name = name
        self.s = s
        self.e = e

    def __gt__(self, o):
        return self.s > o.s

    def __lt__(self, o):
        return self.s < o.s

    def __str__(self):
        return '<%s, %s>' % (self.s, self.e)

class MEM(object):
    size = 128

    def __init__(self):
        self.blocks = []

    def get_frees(self):
        b = self.blocks
        frees = []
        if 1 == len(b):
            frees.append(
                    (0, b[0].s-0))
            frees.append(
                    (b[0].e+1, self.size-1-b[0].e))
            pass
        elif 2 == len(b):
            frees.append(
                    (0, b[0].s-0))
            frees.append(
                    (b[0].e+1, b[1].s-1-b[0].e))
            frees.append(
                    (b[1].e+1, self.size-1-b[1].e))
            pass
        elif 3 <= len(b):
            frees.append(
                    (0, b[0].s-0))
            for i in range(len(b)):
                if not i == len(b)-1:
                    frees.append(
                            (b[i].e+1, b[i+1].s-1-b[i].e))
                else:
                    frees.append(
                            (b[i].e+1, self.size-1-b[i].e))
        else:
            frees.append(
                    (0, self.size))
        return frees

    def insert(self, n, l):
        b = self.blocks

        # initial insert
        if not b:
            if l <= self.size:
                elem = Elem(n, 0, l-1)
                b.append(elem)
            else:
                raise MEMStoreError('Too large to insert')

        # normal insert
        else:
            # calculate frees
            able = False
            frees = self.get_frees()
            for start, length in frees:
                if length >= l:
                    print 'insert'
                    self.blocks.append(Elem(n, start, start+l-1))
                    able = True
                    break
            if not able:
                raise MEMStoreError('Storage overflow, unable to insert')

        # sort
        directSelectSort(self.blocks, 's-b')

    def release(self, name):
        for loop, i in enumerate(self.blocks):
            if name == i.name:
                self.blocks.pop(loop)
                do_release = True
                break

    class Display:
        fmt = '| {0:<12}| {1:<12}| {2:<12}| {3:<12}|'
        sepline = ('+'+'-'*13)*4+'+'
        solidline = '|'+' '*55+'|'

    def list(self):
        print ''
        print col_decorate('Storage list', 'blue')
        print self.Display.sepline
        print self.Display.fmt.format('Name', 'Size', 'Start Point', 'End Point')
        print self.Display.sepline
        for i in self.blocks:
            print self.Display.fmt.format(i.name, i.e-i.s, i.s, i.e)
            print self.Display.sepline

    def present(self, row=8):
        size = self.size
        col = size/row
        op = ''
        avaliables = []
        for start, length in self.get_frees():
            for i in range(length):
                avaliables.append(start+i)
        for j in range(size):
            if j in avaliables:
                op += '0 '
            else:
                op += '1 '
            if (j+1)%col == 0 and j != size-1:
                op += '\n'
        print ''
        print col_decorate('Memory usage present', 'blue')
        print op


if '__main__' == __name__:

    def mode_input():
        try:
            print ''
            print col_decorate('Menu choices', 'blue')
            print '1 :: insert into mem'
            print '2 :: release from mem'
            print '3 :: list data name & size'
            print '4 :: output memory presentation'
            print '0 :: exit'
            print 'Select:',
            return int(raw_input())
        except ValueError:
            raise InputError('Mode input error')


    def name_input(mode, mem):
        while True:
            print 'input name:',
            name = raw_input()
            InputError.assertTrue(name, 'Could not be None')
            if 1 == mode:
                if name in [i.name for i in mem.blocks]:
                    raise InputError('Name dumplicated')
            if 2 == mode:
                if not name in [i.name for i in mem.blocks]:
                    raise InputError('Name does not exist')
            return name

    def length_input():
        while True:
            print 'input length:',
            length = int(raw_input())
            InputError.assertTrue(length >= 1, 'Lenght should be >= 1')
            return length

    # start
    mem = MEM()

    while True:
        try:
            mode = mode_input()

            if 1 == mode:
                name = name_input(mode, mem)
                length = length_input()

                mem.insert(name, length)
            elif 2 == mode:
                name = name_input(mode, mem)

                mem.release(name)
            elif 3 == mode:
                mem.list()
            elif 4 == mode:
                mem.present()
            elif 0 == mode:
                print 'exit'
                sys.exit()
            else:
                raise InputError('No that mode')

        except BaseError as e:
            print e
        except KeyboardInterrupt:
            print col_decorate('\nexit', 'blue')
            sys.exit()