Exemple #1
0
void SemiTable::Remove(int index)
{
    const SemiConnection& s = m_entries[index];
    if (s.m_group_id != -1) {
        m_groups->GetGroupById(s.m_group_id)
            ->BreakConnection(index, s.m_con_type);
    }
    m_end_table[SlotIndex(HashEndpoints(s))].Exclude(index);
    m_hash_table[SlotIndex(s.m_hash)].Exclude(index);
    m_freelist.PushBack(index);
    m_usedlist.Exclude(index);
}
Exemple #2
0
void SemiTable::TransferEndpoints(cell_t from, cell_t to)
{
    for (int i = 0; i < m_usedlist.Length(); ++i) {
        const int index = m_usedlist[i];
        SemiConnection& s = m_entries[index];
        if (s.m_p1 == from || s.m_p2 == from) {
            m_end_table[SlotIndex(HashEndpoints(s))].Exclude(index);
            m_hash_table[SlotIndex(s.m_hash)].Exclude(index);
            s.ReplaceEndpoint(from, to);
            m_end_table[SlotIndex(HashEndpoints(s))].Include(index);
            m_hash_table[SlotIndex(s.m_hash)].Include(index);
        }
    }
}
Exemple #3
0
int32_t SemiTable::HashToIndex(uint32_t hash) const
{
    int hslot = SlotIndex(hash);        
    for (int i = 0; i < m_hash_table[hslot].Length(); ++i)
        if (m_entries[ m_hash_table[hslot][i] ].m_hash == hash)
            return m_hash_table[hslot][i];
    assert(false);
    return -1;
}
Exemple #4
0
const SemiConnection& SemiTable::LookupHash(uint32_t hash) const
{
    int hslot = SlotIndex(hash);        
    for (int i = 0; i < m_hash_table[hslot].Length(); ++i) {
        const SemiConnection& s = m_entries[ m_hash_table[hslot][i] ];
        if (s.m_hash == hash)
            return s;
    }
    throw YException() << "Lookup failed on hash!! (" << hash << ")\n";
    return m_entries[0];  // to avoid compilation error
}
Exemple #5
0
void SemiTable::RemoveAllBetween(cell_t a, cell_t b)
{
    int eslot = SlotIndex(Hash(a) ^ Hash(b));
    SlotSizeList m_worklist(m_end_table[eslot]);
    for (int i = 0; i < m_worklist.Length(); ++i) {
        const int index = m_worklist[i];
        const SemiConnection& s = m_entries[ index ];
        if (s.SameEndpoints(a, b)) {
            Remove(index);
        }
    }
}
Exemple #6
0
/**************************************************************
  NAME         : BsaveTemplateSlots
  DESCRIPTION  : Writes class instance template binary data
  INPUTS       : 1) The defclass
                 2) The binary file pointer
  RETURNS      : Nothing useful
  SIDE EFFECTS : Defclass instance template binary data written
  NOTES        : None
 **************************************************************/
static void BsaveTemplateSlots(
  struct constructHeader *theDefclass,
  void *buf)
  {
   DEFCLASS *cls = (DEFCLASS *) theDefclass;
   register unsigned i;
   long tsp;

   for (i = 0 ; i < cls->instanceSlotCount ; i++)
     {
      tsp = SlotIndex(cls->instanceTemplate[i]);
      GenWrite((void *) &tsp,(UNLN) sizeof(long),(FILE *) buf);
     }
  }
Exemple #7
0
void SemiTable::Include(const SemiConnection& s)
{
    // Abort include if s is a superset of an existing connection.
    // Make a list of all existing connections that are supsersets of s.
    BEGIN_USING_WORKLIST;
    m_worklist.Clear();
    int eslot = SlotIndex(HashEndpoints(s));
    for (int i = 0; i < m_end_table[eslot].Length(); ++i) {
        const int index = m_end_table[eslot][i];
        const SemiConnection& other = m_entries[ index ];
        if (other.SameEndpoints(s)) {
            if (other.IsCarrierSubsetOf(s)) {
                // YTrace() << "############### SKIPPING SUPERSET ####\n";
                // YTrace() << "s: " << s.ToString() << '\n';
                // YTrace() << "o: " << other.ToString() << '\n';
                FINISH_USING_WORKLIST;
                return;
            }
            else if (s.IsCarrierSubsetOf(other)) {
                m_worklist.PushBack(index);
            }
        }
    }

    // If an existing superset of s is used in a group we can replace
    // it with s; otherwise, just free all supersets.
    int replace_index = -1;
    for (int i = 0; i < m_worklist.Length(); ++i) {
        const int index = m_worklist[i];
        SemiConnection& other = m_entries[ index ];
        if (other.m_group_id != -1) {
            // Only be possible to do this once: If a semi from
            // this list is used in a group connection, then the
            // endpoints of this list are in the same group, hence,
            // there are exactly two disjoint semis from this list
            // used in the group connection. Hence if s is a subset of
            // semi1 it cannot be a subset of semi2 (and vice versa).
            assert(replace_index == -1);
            replace_index = index;
        } else {
            Remove(index);
            m_newlist.Exclude(&other);
        }
    }
    FINISH_USING_WORKLIST;

    // Replace an existing semi
    if (replace_index != -1) 
    {
        SemiConnection& other = m_entries[ replace_index ];

        // Move it into its new hash slot
        m_hash_table[SlotIndex(other.m_hash)].Exclude(replace_index);
        int hslot = SlotIndex(s.m_hash);
        if (m_hash_table[hslot].Length() >= MAX_ENTRIES_PER_SLOT)
            throw YException("Hash list is full!");
        m_hash_table[hslot].PushBack(replace_index);

        int group_id = other.m_group_id;
        cell_t type = other.m_con_type;
        
        // YTrace() << "Replacing SemiConnection!\n"
        //           << "gid: " << group_id << " type: " << type << '\n' 
        //           << "old: " << other.ToString() << '\n'
        //           << "new: " << s.ToString() << '\n';
        
        m_entries[replace_index] = s;
        m_entries[replace_index].m_group_id = group_id;
        m_entries[replace_index].m_con_type = type;

        // FIXME: add it to the new list of semis??!

        // Shrink all groups above g
        // FIXME: Is this okay? Should I really allow SemiTable
        // access to private stuff in Groups?
        Group* g = m_groups->GetGroupById(group_id);
        m_groups->ComputeConnectionCarrier(g, type);
        m_groups->RecomputeFromChildrenToTop(g);

        // YTrace() << "index=" << replace_index << '\n';
        // YTrace() << "REPLACED: " << s.ToString() << ' ' 
        //           << YUtil::HashString(s.m_hash) << '\n';

    }
    // Find room for s
    else 
    {
        if (m_freelist.IsEmpty())
            throw YException("SemiTable is full!!!");
        if (m_end_table[eslot].Length() >= MAX_ENTRIES_PER_SLOT)
            throw YException("Endpoint list is full!");
        int hslot = SlotIndex(s.m_hash);
        if (m_hash_table[hslot].Length() >= MAX_ENTRIES_PER_SLOT)
            throw YException("Hash list is full!");
        
        int index = m_freelist.Last();
        m_freelist.PopBack();
        m_usedlist.PushBack(index);
        m_end_table[eslot].PushBack(index);
        m_hash_table[hslot].PushBack(index);

        m_entries[index] = s;
        if (m_newlist.Length() >= 128)
            throw YException("New list is full (>=128)!!");
        m_newlist.PushBack(&m_entries[index]);
    }
}
 oSlotEntry PendingChainState::slot_lookup_by_timestamp( const time_point_sec timestamp )const
 {
     const auto iter = _slot_timestamp_to_delegate.find( timestamp );
     if( iter != _slot_timestamp_to_delegate.end() ) return _slot_index_to_entry.at( SlotIndex( iter->second, timestamp ) );
     const ChainInterfacePtr prev_state = _prev_state.lock();
     if( !prev_state ) return oSlotEntry();
     const oSlotEntry entry = prev_state->lookup<SlotEntry>( timestamp );
     if( entry.valid() && _slot_index_remove.count( entry->index ) == 0 ) return *entry;
     return oSlotEntry();
 }