示例#1
0
void MemoryTablePrivate::updateValue(const value_type &value, quint32 valueSize, quint32 offset, TableMetadata *table)
{
    Allocation *allocation = allocationAt(offset, table);
    Q_ASSERT(allocation->size >= requiredSpace(valueSize));

    allocation->dataSize = valueSize;
    insertData(allocation->data, allocation->dataSize, value);
}
示例#2
0
quint32 MemoryTablePrivate::allocate(quint32 size, TableMetadata *table, bool indexRequired)
{
    const quint32 availableSpace = freeSpace(table);
    if (indexRequired) {
        // Even if satisfied from the free list, this allocation requires there to be space for expanded index
        if (availableSpace < sizeof(IndexElement)) {
            return 0;
        }
    }

    // Align the allocation so that the header is directly accessible
    quint32 allocationSize = static_cast<quint32>(requiredSpace(size));
    allocationSize = roundUp(allocationSize, sizeof(quint32));

    if (table->freeList) {
        // Try to reuse a freed block
        quint32 *bestOffset = 0;
        Allocation *bestBlock = 0;

        quint32 *freeOffset = &table->freeList;
        while (*freeOffset) {
            Allocation *freeBlock = allocationAt(*freeOffset, table);
            if (freeBlock->size >= allocationSize) {
                // This block is large enough
                if (!bestBlock || bestBlock->size > freeBlock->size) {
                    // It's our best fit so far
                    bestBlock = freeBlock;
                    bestOffset = freeOffset;
                }
            }

            freeOffset = &freeBlock->nextOffset;
        }

        if (bestOffset) {
            // TODO: if this block is too large, should it be partitioned?
            quint32 rv = *bestOffset;
            *bestOffset = bestBlock->nextOffset;
            return rv;
        }
    }

    // Is there enough space for this allocation?
    if (availableSpace < (allocationSize + (indexRequired ? sizeof(IndexElement) : 0))) {
        return 0;
    }

    // Allocate the space immediately below the already-allocated space
    table->freeOffset -= allocationSize;

    Allocation *allocation = allocationAt(table->freeOffset, table);
    allocation->size = allocationSize;

    return table->freeOffset;
}
示例#3
0
MemoryTablePrivate::Error MemoryTablePrivate::insert(const key_type &key, const value_type &value, TableMetadata *table)
{
    const quint32 valueSize = dataSize(value);

    IndexElement *tableEnd = end(table);
    IndexElement *position = std::lower_bound(begin(table), tableEnd, key);
    if (position != tableEnd && position->key == key) {
        // This is a replacement - the item has an allocation already
        Allocation *allocation = allocationAt(position->offset, table);
        if (allocation->size < requiredSpace(valueSize)) {
            // Replace the existing allocation with a bigger one
            quint32 newOffset = allocate(valueSize, table, false);
            if (!newOffset)
                return MemoryTable::InsufficientSpace;

            deallocate(position->offset, table);
            position->offset = newOffset;
        } else {
            // Reuse this allocation
            // TODO: swap with a better fit from the free list?
        }
    } else {
        // This item needs to be added to the index
        if (table->count == std::numeric_limits<quint32>::max())
            return MemoryTable::InsufficientSpace;

        quint32 offset = allocate(valueSize, table, true);
        if (!offset)
            return MemoryTable::InsufficientSpace;

        // For index insertion, move the displaced elements of the index
        if (position != tableEnd)
            std::memmove(position + 1, position, (tableEnd - position) * sizeof(IndexElement));

        ++(table->count);
        position->key = key;
        position->offset = offset;
    }

    Q_ASSERT(contains(key, table));

    // Ensure that the data allocation does not overlap the index space
    Q_ASSERT((reinterpret_cast<char *>(table) + table->freeOffset) >= reinterpret_cast<char *>(end(table)));

    // Update the value stored at the position
    updateValue(value, valueSize, position->offset, table);

    return MemoryTable::NoError;
}
示例#4
0
VRectanglef VArabicSupport_cl::GetCharacterDimension( wchar_t wcChar, VisFont_cl * pFont )
{
  VASSERT_MSG(pFont!=NULL, "Specified font is NULL");

  VRectanglef requiredSpace(0,0,0,0);

  // Convert to UTF8
  const wchar_t singleCharacter[2] = {wcChar, 0};
  char utf8Representation[8];

  int iSize = VString::ConvertWCharToUTF8String(singleCharacter, 1, NULL, 0);
  VString::ConvertWCharToUTF8String(singleCharacter, 1, utf8Representation, iSize);
  utf8Representation[iSize] = '\0';

  //check if the end-representation is present
  if(pFont!=NULL) pFont->GetTextDimension(utf8Representation,requiredSpace,1);

  return requiredSpace;
}