Timestamp Approach

code

import random, simpy


RUNTIME = 1        #simulation times
DATA_BLOCK = 30
INTERVAL = 3    #the maximum interval of adjacent two operations is 3
MAXTIME = 5     #the maximum execution time of a single operation is 5
SIM_TIME = 1000

processQueue = []    #the process waiting queue, set max size 4

global writeNum
global invalidWrite
writeNum = 0
invalidWrite = 0
datablocks = []

class DataBlock(object):
    def __init__(self, id, lock_mode, readersNum,timestamp):
        self.id = id
        self.lock_mode = lock_mode
        self.readersNum = readersNum
        self.timestamp = timestamp

class Operation(object):
    def __init__(self,maxtime):
        self.maxtime = maxtime
        #self.env = env

    def read(self, env, name, datablock):    #read operation method
        print("%s is reading datablock No.%s at %s" %(name,datablock.id,env.now))
        operateTime = random.randint(1,MAXTIME)
        datablock.timestamp = env.now + operateTime            #update corresponding datablock's timestamp to the time the read operation would stop

        yield env.timeout(operateTime)
        print("%s has finished reading datablock No.%s at %s" %(name,datablock.id,env.now))
        processQueue.remove(name)

    def write(self, env, name, datablock):    #write operation method
        global writeNum
        global invalidWrite
        writeNum = writeNum+1                        #increment writenum
        if datablock.timestamp > env.now:        #last operation of this datablock has not ended yet, it is a invalid dirty write operation, reattempt
            invalidWrite = invalidWrite + 1     #increment the number of invalidWrite
            print('Operation %s is an invalid dirty write on datablock %d at time %.2f, reattempted.' % (name, datablock.id, env.now))
            #while datablock.timestamp > env.now:
            #    yield env.timeout(1)
            curTime = env.now
            while datablock.timestamp > curTime:
                curTime = curTime + 1
                #wait last operation end



        operateTime = random.randint(1,MAXTIME)
        datablock.timestamp = env.now + operateTime
        print("%s is writing datablock No.%s at %s" %(name,datablock.id,env.now))
        yield env.timeout(operateTime)
        print("%s has finished writing datablock No.%s at %s" %(name,datablock.id,env.now))


def setup(env, maxtime, interval, datablocks):
    operation = Operation(maxtime)
    i = 0
    while  True:
        yield env.timeout(random.randint(0,interval))    #stop for next operation
        blockNum = random.randint(0,DATA_BLOCK-1)                    #generate block number randomly
        mode = "";
        if random.random()<0.25:                        #according possibility to specify the mode 
            mode = "W"
        else:
            mode = "R"

        if len(processQueue) == 4:                        #if the queue is full, wait
            yield env.timeout(maxtime*3)
        processQueue.append('Operation %d' %i)            #push current operate into the queue
        print('the blockNum is %d' %blockNum)
        db = datablocks[blockNum]                        #get corresponding datablock object
        if mode == "R":                                    #execute corresponding operation 
            env.process(operation.read(env,'Operation %d' % i,db))    
        else:
            env.process(operation.write(env,'Operation %d' % i,db))
        i = i+1


for i in range(DATA_BLOCK):                #initialize datablocks
    datablocks.append(DataBlock(i, '', 0,0))

env = simpy.Environment()
env.process(setup(env, MAXTIME, INTERVAL,datablocks))
i = 0
while i < RUNTIME:
    env.run(until=SIM_TIME)
    SIM_TIME += 10000
    i = i + 1

percent = (invalidWrite/writeNum)*100
print('When we run %d times, total write number: %d, invalid write number: %d. The percent of invalid write is %.3f %%.' %(RUNTIME,writeNum,invalidWrite,percent))

results matching ""

    No results matching ""