示例#1
0
 def __del_entry(self, s, quot):
     '''
     Remove the entry in QF[s] and slide the rest of the cluster forward.
     '''
     orig = s
     curr = self[s]
     sp = self.inc_index(s)
     while True:
         _next = self[sp]
         curr_occupied = is_occupied(curr)
         if is_empty(_next) or isElementClusterStart(_next) or sp == orig:
             self[s] = 0
             return
         # Fix entries which slide into canonical slots.
         updated_next = _next
         if isElementRunStart(_next):
             do = True
             while do:
                 quot = self.inc_index(quot)
                 do = not is_occupied(self[quot])
             if curr_occupied and quot == s:
                 updated_next = is_shifted_clear(_next)
             self[s] = is_occupied_set(updated_next) if curr_occupied else is_occupied_clear(updated_next)
             s = sp
             sp = self.inc_index(sp)
             curr = _next
示例#2
0
    def insert(self, val, hashed=False):
        if self.entries >= self.MAX_INSERTIONS or self.overflowed:
            # Can't safely process an after overflow
            # Only a buggy program would attempt it
            if self.overflowed:
                raise OverflowError
            #Can still resize if we have enough remainder bits
            if self.REMAINDER_BITS > 1:
                self.double_size()
            else:
                self.overflowed = True
                raise OverflowError
        if hashed:
            _hash = val
        else:
            _hash = self.hash_fn(val)
        fq = self.hash_to_quotient(_hash)
        fr = self.hash_to_remainder(_hash)
        T_fq = self[fq]
        entry = (fr << 3) & ~7
        #Special-case filling canonical slots to simplify insert_into()
        if is_empty(T_fq):
            entry = is_occupied_set(entry)
            self[fq] = entry
            self.entries += 1
            return
        if not is_occupied(T_fq):
            self[fq] = is_occupied_set(T_fq)

        start = self.find_run_Index(fq)
        s = start
        if is_occupied(T_fq):
            do = True
            while do:
                rem = get_remainder(self[s])
                if rem >= fr:
                    break
                s = self.inc_index(s)
                do = is_continuation(self[s])

            if s == start: # The old start-of-run becomes a continuation.
                old_head = self[start]
                old_head = is_continuation_set(old_head)
                self[start] = old_head
            else: # The new element becomes a continuation.
                entry = is_continuation_set(entry)
        #Set the shifted bit if we can't use the canonical slot.
        if s != fq:
            entry = is_shifted_set(entry)

        self.insert_into(s, entry)
        self.entries += 1
示例#3
0
 def __delitem__(self, val):
     if self.overflowed:
         #Can't safely process a remove after overflow
         #Only a buggy program would attempt it
         raise OverflowError
     _hash = self.hash_fn(val)
     fq = self.hash_to_quotient(_hash)
     fr = self.hash_to_remainder(_hash)
     T_fq = self[fq]
     if self.entries == 0 or not is_occupied(T_fq  ):
         #If you remove things that don't exist it's possible you will clobber
         #somethign on a collision, your program is buggy
         raise KeyError('Element not exist')
     start = self.find_run_Index(fq)
     s = start
     #Find the offending table index (or give up)
     do = True
     while do:
         rem = get_remainder(self[s])
         if rem == fr:
             break
         elif rem > fr:
             return
         s = self.inc_index(s)
         do = is_continuation(self[s])
     if rem != fr:
         #If you remove things that don't exist it's possible you will clobber
         #somethign on a collision, your program is buggy
         raise KeyError('Element not exist')
     kill = T_fq if s == fq else self[s]
     replace_run_start = isElementRunStart(kill)
     #If we're deleting the last entry in a run, clear `is_occupied'.
     if replace_run_start:
         _next = self[self.inc_index(s)]
         if not is_continuation(_next):
             T_fq = is_occupied_clear(T_fq)
             self[fq] = T_fq
     self.__del_entry(s, fq)
     if replace_run_start:
         _next = self[s]
         updated_next = _next
         if is_continuation(_next):# The new start-of-run is no longer a continuation.
             updated_next = is_continuation_clear(updated_next)
         if s == fq and isElementRunStart(updated_next):
             # The new start-of-run is in the canonical slot.
             updated_next = is_shifted_clear(updated_next)
         if updated_next != _next:
             self[s] = updated_next
     self.entries -= 1
示例#4
0
 def insert_into(self, s, elt):
     curr = elt
     do = True
     while do:
         prev = self[s]
         empty = is_empty(prev)
         if not empty:# Fix up `is_shifted' and `is_occupied'.
             prev = is_shifted_set(prev)
             if is_occupied(prev):
                 curr = is_occupied_set(curr)
                 prev = is_occupied_clear(prev)
         self[s]=curr
         curr = prev
         s = self.inc_index(s)
         do = not empty
示例#5
0
 def find_run_Index(self, fq):
     '''
     Find the start index of the run for fq (given that the run exists)
     '''
     # Find the start of the cluster.
     b= fq
     while is_shifted(self[b]):
         b= self.dec_index(b)
     # Find the start of the run for fq
     s = b
     while b != fq:
         s = self.inc_index(s)
         while is_continuation(self[s]):
             s = self.inc_index(s)
         b = self.inc_index(b)
         while not is_occupied(self[b]):
             b = self.inc_index(b)
     return s
示例#6
0
 def __next__(self):
     while self.entries != self.visited:
         elt = self[self.index]
         #Keep track of the current run.
         if isElementClusterStart(elt):
             self.quotient = self.index
         elif isElementRunStart(elt):
             quot = self.quotient
             do = True
             while do:
                 quot = self.inc_index(quot)
                 do = not is_occupied(self[quot])
             self.quotient = quot
         self.index = self.inc_index(self.index)
         if not is_empty(elt):
             quot = self.quotient
             rem = get_remainder(elt)
             _hash = (quot << self.REMAINDER_BITS) | rem
             self.visited += 1
             return _hash
     raise StopIteration()