Ejemplo n.º 1
0
/**
* 随机构造总大小为dataSize的记录插入到table中,
* 记录ID从在[minidx, minid]之间随机生成
* @param table 数据表
* @param dataSize 记录总大小
* @param maxid 最大id 
* @param minid 最小id
* @return 记录数
*/
uint TNTCountTable::populate(Session *session, TNTTable *table, TNTOpInfo *opInfo, u64 *dataSize, u64 maxId, u64 minId) {
	assert(session->getTrans() != NULL);
	u64 volumnCnt = *dataSize;
	uint recCnt = 0;
	uint dupIdx;
	int startId = 0;
	Record *rec;
	RowId rid;
	while (true) {
		// 创建记录
		u64 id = (u64)RandomGen::nextInt((u32)minId, (u32)maxId);
		rec = createRecord((u64)recCnt, (int)startId++);
		if (volumnCnt < getRecordSize()) {
			freeRecord(rec);
			break;
		}
		// 插入记录
		rid = table->insert(session, rec->m_data, &dupIdx, opInfo);
		if (rid != INVALID_ROW_ID) {
			recCnt++;
			volumnCnt -= getRecordSize();
		}
		freeRecord(rec);
	}

	*dataSize -= volumnCnt;
	return recCnt;
}
Ejemplo n.º 2
0
RC updateRecord(RM_TableData *rel, Record *record) {
	RID *rid = &record->id;
	RM_TableMgmtData *tableMgmtData = rel->mgmtData;
	RM_Page *page;

	//  Check to see if feasible record
	if (rid->page == NO_PAGE || rid->slot == NO_SLOT) {
		return RC_RM_NO_RECORD;
	}

	RC pinPageResult;
	if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, rid->page) != RC_OK) {
		return pinPageResult;
	}
	page = (RM_Page*)tableMgmtData->pageHandle.data;

	char *slotOffset = ((char*)&page->data) + (rid->slot * getRecordSize(rel->schema));


	int recordSize = getRecordSize(rel->schema);
	memcpy(slotOffset + 1, record->data, recordSize);

	RC markDirtyResult;
	if (markDirtyResult = markDirty(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return markDirtyResult;
	}

	RC unpinPageResult;
	if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return unpinPageResult;
	}

	return RC_OK;
}
Ejemplo n.º 3
0
int findFreeSlot(RM_Page *page, Schema *schema) {
	int totalSlots = ((int)(PAGE_SIZE - ((&((RM_Page*)0)->data) - ((char*)0)))) / getRecordSize(schema);
	char *slotOffset = (char*)&page->data;
	int recordSize = getRecordSize(schema);

	int slot;
	for (slot = 0; slot < totalSlots; slot++) {
		// Do we have a tombstone?
		if ((*(char*)slotOffset) <= 0) {
			return slot;
		}
		slotOffset = slotOffset + recordSize;
	}
	return NO_SLOT;
}
Ejemplo n.º 4
0
// Simply marks tombstones, doesn't physically delete or allow for records to overwrite
RC deleteRecord(RM_TableData *rel, RID id) {
	RM_TableMgmtData *tableMgmtData = rel->mgmtData;
	RM_Page *page;

	RC pinPageResult;
	if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, id.page) != RC_OK) {
		return pinPageResult;
	}

	page = (RM_Page*)tableMgmtData->pageHandle.data;
	char *slotOffset = ((char*)&page->data) + (id.slot*getRecordSize(rel->schema));


	// Update tombstone
	*(char*)slotOffset = -1;

	RC markDirtyResult;
	if (markDirtyResult = markDirty(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return markDirtyResult;
	}

	RC unpinPageResult;
	if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return unpinPageResult;
	}

	tableMgmtData->numTuples--;

	return RC_OK;
}
Ejemplo n.º 5
0
/*
 * Creates a new Record and allocates memmory for record & its data
 */
RC createRecord (Record **record, Schema *schema)
{
	*record = (Record*)malloc(sizeof(Record));
	(*record)->data = (char*)malloc(getRecordSize(schema));

	return RC_OK;
}
/**
 * Creates and returns the record handle to be used by client
 *
 * record = record handle to be initialized
 * schema = schema on which record is to be based
 */
RC createRecord(Record **record, Schema *schema) {

	//Sanity Checks
	if (schema == NULL) {
		THROW(RC_INVALID_HANDLE, "Schema handle is invalid");
	}

	*record = (Record *) malloc(sizeof(Record));

	if (record == NULL) {
		THROW(RC_NOT_ENOUGH_MEMORY,
				"Not enough memory available for resource allocation");
	}

	int recordLen = getRecordSize(schema);

	//Reset the NULL map
	(*record)->nullMap = 0x0000;
	(*record)->data = (char*) malloc(recordLen);
	memset((*record)->data, '\0', recordLen);

	if ((*record)->data == NULL) {
		THROW(RC_NOT_ENOUGH_MEMORY,
				"Not enough memory available for resource allocation");
	}

	//All OK
	return RC_OK;
}
Ejemplo n.º 7
0
/**
Implementation of scanner.h
**/
void update(int pageno,Schema *sch,TableManager *tableManager, Pager *dp){
    int i;
    int slotId =-1;
    int _rSize= getRecordSize(sch)+1;
    char *slotAddr= ((char*) &dp->data);
    int totalSlots= ( ((int)(PAGE_SIZE - ((&((Pager*)0)->data) - ((char*)0)) )/(getRecordSize(sch)+1) ));
    for (i=0; i<totalSlots; i++){
        if (!(*(char*)slotAddr)>0){
            slotId = i;
            break;
        }
        slotAddr= _rSize+slotAddr;
    }
    if (slotId <= 0){
          pop(tableManager, dp, pageno);}
    else{
      push(tableManager, dp, pageno);
    }

}
Ejemplo n.º 8
0
RC getRecord(RM_TableData *rel, RID id, Record *record) {
	RM_TableMgmtData *tableMgmtData = rel->mgmtData;
	RM_Page *page;

	if (id.page == NO_PAGE || id.slot == NO_SLOT) {
		return RC_RM_NO_RECORD;
	}

	RC pinPageResult;
	if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, id.page) != RC_OK) {
		return pinPageResult;
	}

	page = (RM_Page *)tableMgmtData->pageHandle.data;
	char *slotOffset = ((char*)&page->data) + (id.slot * getRecordSize(rel->schema));
	memcpy(record->data, slotOffset + 1, getRecordSize(rel->schema) - 1);

	RC unpinPageResult;
	if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return unpinPageResult;
	}

	return RC_OK;
}
Ejemplo n.º 9
0
// Khush started working on this
// dealing with records and attribute values
RC createRecord(Record **record, Schema *schema) {
	int recordSize;
	Record *newRecord;

	//  Assign default record values
	newRecord = MAKE_RECORD();
	recordSize = getRecordSize(schema);
	newRecord->data = MAKE_RECDATA(recordSize);
	memset(newRecord->data, 0, recordSize);
	newRecord->id.page = NO_PAGE;
	newRecord->id.slot = NO_SLOT;
	
	//  Save record to pointer
	*record = newRecord;

	return RC_OK;
}
/**
 * Fetch next matching record satisfying condition expression
 *
 * scan = scan handle
 * record = next matching record returned
 */
RC next(RM_ScanHandle *scan, Record *record) {
	RM_ScanIterator* iter = (RM_ScanIterator*) scan->mgmtData;
	Record* r = iter->records[iter->lastRecordRead + 1];

	if ((iter->lastRecordRead + 1) < iter->totalRecords && r != NULL) {
		record->id.page = r->id.page;
		record->id.slot = r->id.slot;
		record->nullMap = r->nullMap;
		memcpy(record->data, r->data, getRecordSize(scan->rel->schema));

		iter->lastRecordRead++;

		return RC_OK;
	}

	return RC_RM_NO_MORE_TUPLES;
}
void testScansTwo (void)
{
  RM_TableData *table = (RM_TableData *) malloc(sizeof(RM_TableData));
  TestRecord inserts[] = { 
    {1, "aaaa", 3}, 
    {2, "bbbb", 2},
    {3, "cccc", 1},
    {4, "dddd", 3},
    {5, "eeee", 5},
    {6, "ffff", 1},
    {7, "gggg", 3},
    {8, "hhhh", 3},
    {9, "iiii", 2},
    {10, "jjjj", 5},
  };
  bool foundScan[] = {
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE,
    FALSE
  };
  int numInserts = 10, i;
  Record *r;
  RID *rids;
  Schema *schema;
  RM_ScanHandle *sc = (RM_ScanHandle *) malloc(sizeof(RM_ScanHandle));
  Expr *sel, *left, *right, *first, *se;
  int rc;

  testName = "test creating a new table and inserting tuples";
  schema = testSchema();
  rids = (RID *) malloc(sizeof(RID) * numInserts);
  
  TEST_CHECK(initRecordManager(NULL));
  TEST_CHECK(createTable("test_table_r",schema));
  TEST_CHECK(openTable(table, "test_table_r"));
  
  // insert rows into table
  for(i = 0; i < numInserts; i++)
  {
    r = fromTestRecord(schema, inserts[i]);
    TEST_CHECK(insertRecord(table,r)); 
    rids[i] = r->id;
  }

  TEST_CHECK(closeTable(table));
  TEST_CHECK(openTable(table, "test_table_r"));

  // Select 1 record with INT in condition a=2.
  MAKE_CONS(left, stringToValue("i2"));
  MAKE_ATTRREF(right, 0);
  MAKE_BINOP_EXPR(sel, left, right, OP_COMP_EQUAL);
  createRecord(&r, schema);
  TEST_CHECK(startScan(table, sc, sel));
  while((rc = next(sc, r)) == RC_OK)
  {
     ASSERT_EQUALS_RECORDS(fromTestRecord(schema, inserts[1]), r, schema, "compare records");
  }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  // Select 1 record with STRING in condition b='ffff'.
  MAKE_CONS(left, stringToValue("sffff"));
  MAKE_ATTRREF(right, 1);
  MAKE_BINOP_EXPR(sel, left, right, OP_COMP_EQUAL);
  createRecord(&r, schema);
  TEST_CHECK(startScan(table, sc, sel));
  while((rc = next(sc, r)) == RC_OK)
  {
     ASSERT_EQUALS_RECORDS(fromTestRecord(schema, inserts[5]), r, schema, "compare records");
     serializeRecord(r, schema);
  }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  // Select all records, with condition being false
  MAKE_CONS(left, stringToValue("i4"));
  MAKE_ATTRREF(right, 2);
  MAKE_BINOP_EXPR(first, right, left, OP_COMP_SMALLER);
  MAKE_UNOP_EXPR(se, first, OP_BOOL_NOT);
  TEST_CHECK(startScan(table, sc, se));
    while((rc = next(sc, r)) == RC_OK)
    {
     serializeRecord(r, schema);
     for(i = 0; i < numInserts; i++)
     {
       if (memcmp(fromTestRecord(schema, inserts[i])->data,r->data,getRecordSize(schema)) == 0)
	     foundScan[i] = TRUE;
     }
    }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  
  ASSERT_TRUE(!foundScan[0], "not greater than four");
  ASSERT_TRUE(foundScan[4], "greater than four");
  ASSERT_TRUE(foundScan[9], "greater than four");

  // clean up
  TEST_CHECK(closeTable(table));
  TEST_CHECK(deleteTable("test_table_r"));
  TEST_CHECK(shutdownRecordManager());

  freeRecord(r);
  free(table);
  free(sc);
  freeExpr(sel);
  TEST_DONE();
}
void testScans (void)
{
  RM_TableData *table = (RM_TableData *) malloc(sizeof(RM_TableData));
  TestRecord inserts[] = { 
    {1, "aaaa", 3}, 
    {2, "bbbb", 2},
    {3, "cccc", 1},
    {4, "dddd", 3},
    {5, "eeee", 5},
    {6, "ffff", 1},
    {7, "gggg", 3},
    {8, "hhhh", 3},
    {9, "iiii", 2},
    {10, "jjjj", 5},
  };
  TestRecord scanOneResult[] = { 
    {3, "cccc", 1},
    {6, "ffff", 1},
  };
  bool foundScan[] = {
    FALSE,
    FALSE
  };
  int numInserts = 10, scanSizeOne = 2, i;
  Record *r;
  RID *rids;
  Schema *schema;
  RM_ScanHandle *sc = (RM_ScanHandle *) malloc(sizeof(RM_ScanHandle));
  Expr *sel, *left, *right;
  int rc;

  testName = "test creating a new table and inserting tuples";
  schema = testSchema();
  rids = (RID *) malloc(sizeof(RID) * numInserts);
  
  TEST_CHECK(initRecordManager(NULL));
  TEST_CHECK(createTable("test_table_r",schema));
  TEST_CHECK(openTable(table, "test_table_r"));
  
  // insert rows into table
  for(i = 0; i < numInserts; i++)
  {
      r = fromTestRecord(schema, inserts[i]);
      TEST_CHECK(insertRecord(table,r)); 
      rids[i] = r->id;
  }

  TEST_CHECK(closeTable(table));
  TEST_CHECK(openTable(table, "test_table_r"));

  // run some scans
  MAKE_CONS(left, stringToValue("i1"));
  MAKE_ATTRREF(right, 2);
  MAKE_BINOP_EXPR(sel, left, right, OP_COMP_EQUAL);

  TEST_CHECK(startScan(table, sc, sel));
  while((rc = next(sc, r)) == RC_OK)
  {
      for(i = 0; i < scanSizeOne; i++)
      {
          if (memcmp(fromTestRecord(schema, scanOneResult[i])->data,r->data,getRecordSize(schema)) == 0)
              foundScan[i] = TRUE;
      }
  }
  if (rc != RC_NO_TUPLES)
    TEST_CHECK(rc);
  TEST_CHECK(closeScan(sc));
  for(i = 0; i < scanSizeOne; i++)
    ASSERT_TRUE(foundScan[i], "check for scan result");
  
  // clean up
  TEST_CHECK(closeTable(table));
  TEST_CHECK(deleteTable("test_table_r"));
  TEST_CHECK(shutdownRecordManager());

  free(table);
  free(sc);
  freeExpr(sel);
  TEST_DONE();
}
Ejemplo n.º 13
0
RC next(RM_ScanHandle *scan, Record *record) {
	// Setup mgmt data
	RM_ScanHandleMgmtData *shMgmtData = scan->mgmtData;
	RM_TableMgmtData *tableMgmtData = scan->rel->mgmtData;
	Value *result = (Value *)malloc(sizeof(Value));


	// Do we have any tuples in the table to scan?
	if (tableMgmtData->numTuples == 0) {
		return RC_RM_NO_MORE_TUPLES;
	}

	do {
		// Have we already started a scan?
		if (shMgmtData->numScans == 0) {
			shMgmtData->rid.page = 1;
			shMgmtData->rid.slot = 0;

			RC pinPageResult;
			if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &shMgmtData->pageHandle, shMgmtData->rid.page) != RC_OK) {
				return pinPageResult;
			}

			shMgmtData->page = (RM_Page*)shMgmtData->pageHandle.data;
		}
		// Scan until reach last tuple
		else if (shMgmtData->numScans < tableMgmtData->numTuples) {
			
			int pageSize = (int)(PAGE_SIZE - ((&((RM_Page*)0)->data) - ((char*)0)));
			int totalSlots = pageSize / getRecordSize(scan->rel->schema);
			shMgmtData->rid.slot++;

			if (shMgmtData->rid.slot == totalSlots)
			{
				shMgmtData->rid.page++;
				shMgmtData->rid.slot = 0;

				RC pinPageResult;
				if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &shMgmtData->pageHandle, shMgmtData->rid.page) != RC_OK) {
					return pinPageResult;
				}

				shMgmtData->page = (RM_Page*)shMgmtData->pageHandle.data;
			}
			
		}
		// Scan over and nothing found
		else {

			return RC_RM_NO_MORE_TUPLES;
		}

		char *slotOffset = ((char*)&(shMgmtData->page)->data) + shMgmtData->rid.slot * getRecordSize(scan->rel->schema);

		int recordSize = getRecordSize(scan->rel->schema) - 1;
		memcpy(record->data, slotOffset + 1, recordSize);
		record->id.page = shMgmtData->rid.page;
		record->id.slot = shMgmtData->rid.slot;
		shMgmtData->numScans++;

		if (shMgmtData->cond != NULL) {
			evalExpr(record, (scan->rel)->schema, shMgmtData->cond, &result);
		} 

	} while (!result->v.boolV);

	return RC_OK;
}
Ejemplo n.º 14
0
// Bulk of work will be here 
// handling records in a table
RC insertRecord(RM_TableData *rel, Record *record) {
	RM_TableMgmtData *tableMgmtData = rel->mgmtData;
	BM_MgmtData *bufferMgmtData = tableMgmtData->bufferPool.mgmtData;
	RID *rid = &record->id;
	RM_Page *page;
	char *slotOffset;

	//  Do we have a free slot?
	if (tableMgmtData->nextFreeSlot > 0) {
		// We have a free slot for the record
		rid->page = tableMgmtData->nextFreeSlot;
		// Pin page to insert record
		RC pinPageResult;
		if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, rid->page) != RC_OK) {
			return pinPageResult;
		}

		page = (RM_Page*)tableMgmtData->pageHandle.data;

		// Find the free slot for the record and save it
		rid->slot = findFreeSlot(page, rel->schema);

		if (rid->slot == NO_SLOT) { // Append new page, out of space
			RC unpinPageResult;
			if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
				return unpinPageResult;
			}

			if (appendEmptyBlock(&bufferMgmtData->fh) != RC_OK) {
				return RC_RM_INSERT_RECORD_FAIL;
			}

			rid->page = bufferMgmtData->fh.totalNumPages - 1;

			RC pinPageResult;
			if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, rid->page) != RC_OK) {
				return pinPageResult;
			}
			
			//new page, set slot to 0 (first slot)
			page = (RM_Page*)tableMgmtData->pageHandle.data;
			rid->slot = 0;
		}
	}
	else {
	// No free slot so make new page for record
		RC appendEmptyBlockResult;
		if (appendEmptyBlock(&bufferMgmtData->fh) != RC_OK) {
			return RC_RM_INSERT_RECORD_FAIL;
		}

		rid->page = bufferMgmtData->fh.totalNumPages - 1;

		RC pinPageResult;
		if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, rid->page) != RC_OK) {
			return pinPageResult;
		}
		page = (RM_Page*)tableMgmtData->pageHandle.data;

		rid->slot = 0;
	
	}

	// Finish writing the record now that we have slot information
	RC markDirtyResult;
	if (markDirtyResult = markDirty(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return markDirtyResult;
	}
	
	// Add header offset to slot position for slot offset
	slotOffset = ((char*)&page->data) + (rid->slot * getRecordSize(rel->schema));

	int recordSize = getRecordSize(rel->schema);
	memcpy(slotOffset + 1, record->data, recordSize);

	// Mark first byte of slot with tombstone information info
	*(char*)slotOffset = 1;

	// Update free slot information
	if (findFreeSlot(page, rel->schema) != NO_SLOT) {
		int pageNum = rid->page;
		addFreeSlot(tableMgmtData, page, rid->page);
	}

	RC unpinPageResult;
	if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) {
		return unpinPageResult;
	}
	tableMgmtData->numTuples++;

	return RC_OK;
}
Ejemplo n.º 15
0
char *MultiPartHeader::data()
{
    char *p=new char[getRecordSize()];
    char *i = p;

	quint16 serverNumItems, serverId;
	quint64 artNum;
	quint16 sz16 = sizeof(quint16);
	quint16 sz32 = sizeof(quint32);
	quint16 sz64 = sizeof(quint64);

	*i = headerType;
	i++;

	memcpy(i, &postingDate, sz32);
	i +=sz32;

	memcpy(i, &downloadDate, sz32);
	i +=sz32;

	memcpy(i, &numParts, sz16);
	i+=sz16;

	serverNumItems=serverLowest.count();
	memcpy(i, &serverNumItems, sz16);
	i+=sz16;

	for (lowestit=serverLowest.begin(); lowestit != serverLowest.end(); ++lowestit)
	{
		serverId=lowestit.key();
		artNum=lowestit.value();
		memcpy(i, &serverId, sz16);
		i+=sz16;
		memcpy(i, &artNum, sz64);
		i+=sz64;
	}

	memcpy(i, &multiPartKey, sz64);
	i +=sz64;

    memcpy(i, &missingParts, sz16);
    i+=sz16;

    memcpy(i, &status, sz16);
    i+=sz16;

    memcpy(i, &lines, sz32);
    i+=sz32;

    memcpy(i, &size, sz64);
    i+=sz64;

    // This is the area that maps the number of parts on each server
	quint16 serverPartItems=serverPart.count();

	memcpy(i, &serverPartItems, sz16);
	i+=sz16;
	for (spmit=serverPart.begin() ; spmit != serverPart.end(); ++spmit)
	{
		serverId=spmit.key();
		serverNumItems=spmit.value();
		memcpy(i, &serverId, sz16);
		i+=sz16;
		memcpy(i, &serverNumItems, sz16);
		i+=sz16;
	}

    return p;
}