static int doAddRecord()

in hfs/btree.c [1043:1121]


static int doAddRecord(BTree* tree, uint32_t root, BTKey* searchKey, size_t length, unsigned char* content) {
  BTNodeDescriptor* descriptor;
  BTKey* key;
  off_t recordOffset;
  off_t recordDataOffset;
  off_t lastRecordDataOffset;

  uint16_t offset;

  int res;
  int i;
  
  descriptor = readBTNodeDescriptor(root, tree);
   
  if(descriptor == NULL)
    return FALSE;
    
  lastRecordDataOffset = 0;
  
  for(i = 0; i < descriptor->numRecords; i++) {
    recordOffset = getRecordOffset(i, root, tree);
    key = READ_KEY(tree, recordOffset, tree->io);
    recordDataOffset = recordOffset + key->keyLength + sizeof(key->keyLength);
    
    res = COMPARE(tree, key, searchKey);
    if(res == 0) {
      free(key);
      free(descriptor);
      
      return FALSE;
    } else if(res > 0) {
      free(key);
      
      break;
    }
    
    free(key);
    
    lastRecordDataOffset = recordDataOffset;
  }
   
  if(i != descriptor->numRecords) {
    // first, move everyone else down
    
    moveRecordsDown(tree, descriptor, i, root, sizeof(searchKey->keyLength) + searchKey->keyLength + length, 1);
        
    // then insert ourself
    ASSERT(WRITE_KEY(tree, recordOffset, searchKey, tree->io), "WRITE_KEY");
    ASSERT(WRITE(tree->io, recordOffset + sizeof(searchKey->keyLength) + searchKey->keyLength, length, content), "WRITE");
    
    offset = recordOffset - (root * tree->headerRec->nodeSize);
    FLIPENDIAN(offset);
    ASSERT(WRITE(tree->io, (root * tree->headerRec->nodeSize) + tree->headerRec->nodeSize - (sizeof(uint16_t) * (i + 1)),
                  sizeof(uint16_t), &offset), "WRITE");
  } else {
    // just insert ourself at the end
    recordOffset = getRecordOffset(i, root, tree);
    ASSERT(WRITE_KEY(tree, recordOffset, searchKey, tree->io), "WRITE_KEY");
    ASSERT(WRITE(tree->io, recordOffset + sizeof(uint16_t) + searchKey->keyLength, length, content), "WRITE");
    
    // write the new free offset
    offset = (recordOffset + sizeof(searchKey->keyLength) + searchKey->keyLength + length) - (root * tree->headerRec->nodeSize);
    FLIPENDIAN(offset);
    ASSERT(WRITE(tree->io, (root * tree->headerRec->nodeSize) + tree->headerRec->nodeSize - (sizeof(uint16_t) * (descriptor->numRecords + 2)),
                  sizeof(uint16_t), &offset), "WRITE");
  }
  
  descriptor->numRecords++;
  
  if(descriptor->height == 1) {
    tree->headerRec->leafRecords++;
  }

  ASSERT(writeBTNodeDescriptor(descriptor, root, tree), "writeBTNodeDescriptor");
  ASSERT(writeBTHeaderRec(tree), "writeBTHeaderRec");
  
  free(descriptor);
  return TRUE;
}