InfiniSQL  v0.1.2-alpha
Massive Scale Transaction Processing
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Table Class Reference

create new Table object More...

#include <Table.h>

Collaboration diagram for Table:

Public Member Functions

 Table (int64_t idarg)
 
virtual ~Table ()
 
void setname (string namearg)
 set name More...
 
std::string * getname ()
 get name More...
 
int64_t addfield (fieldtype_e type, int64_t length, std::string name, indextype_e indextype)
 add field/column More...
 
bool makerow (vector< fieldValue_s > *fieldVal, std::string *res)
 assemble row string from fields More...
 
bool unmakerow (std::string *rowstring, vector< fieldValue_s > *resultFields)
 extract fields from row string More...
 
void getrows (vector< int64_t > rowids, locktype_e locktype, int64_t subtransactionid, int64_t pendingcmdid, vector< returnRow_s > *returnRows, vector< int64_t > *lockPendingRowids, int64_t tacmdentrypoint)
 orphan? More...
 
int64_t getnextrowid ()
 generate unique, ever-increasing row identifier More...
 
void newrow (int64_t newrowid, int64_t subtransactionid, string &row)
 create new row More...
 
int64_t updaterow (int64_t rowid, int64_t subtransactionid, string *row)
 modify row More...
 
int64_t deleterow (int64_t rowid, int64_t subtransactionid)
 delete row More...
 
int64_t deleterow (int64_t rowid, int64_t subtransactionid, int64_t forward_rowid, int64_t forward_engineid)
 delete row part of replacement More...
 
void selectrows (vector< int64_t > *rowids, locktype_e locktype, int64_t subtransactionid, int64_t pendingcmdid, vector< returnRow_s > *returnRows, int64_t tacmdentrypoint)
 return rows for select based on index hits More...
 
locktype_e assignToLockQueue (int64_t rowid, locktype_e locktype, int64_t subtransactionid, int64_t pendingcmdid, int64_t tacmdentrypoint)
 add subtransactionid to queue waiting to acquire lock on row More...
 
void commitRollbackUnlock (int64_t rowid, int64_t subtransactionid, enginecmd_e cmd)
 

Public Attributes

int64_t id
 
std::string name
 
int64_t nextindexid
 
std::vector< class Fieldfields
 
boost::unordered_map< int64_t,
std::queue< lockQueueRowEntry > > 
lockQueue
 
class TableshadowTable
 
boost::unordered_map
< std::string, int64_t > 
columnaNameToFieldMap
 
boost::unordered_map< int64_t,
rowdata_s * > 
rows
 
int64_t rowsize
 
int64_t nextrowid
 
boost::unordered_map< int64_t,
forwarderEntry
forwarderMap
 

Friends

class ApiInterface
 
class TransactionAgent
 
class Engine
 
class Transaction
 
class SubTransaction
 
class UserSchemaMgr
 

Detailed Description

create new Table object

Parameters
idargtableid

Definition at line 75 of file Table.h.

Constructor & Destructor Documentation

Table::Table ( int64_t  idarg)

Definition at line 31 of file Table.cc.

References name, rowsize, and shadowTable.

31  : id(idarg)
32 {
33  if (id) // if a real table, create a shadow table with id 0
34  {
35  shadowTable = new class Table(0);
36  }
37 
38  name = "";
39  rowsize = 0;
40 }
virtual Table::~Table ( )
inlinevirtual

Definition at line 79 of file Table.h.

References shadowTable.

80  {
81  if (id)
82  {
83  delete shadowTable;
84  }
85  }

Member Function Documentation

int64_t Table::addfield ( fieldtype_e  type,
int64_t  length,
std::string  name,
indextype_e  indextype 
)

add field/column

Parameters
typefield type
lengthlength (for CHARX)
namefield name
indextypeindex type
Returns
fieldid

Definition at line 52 of file Table.cc.

References BOOL, CHAR, CHARX, columnaNameToFieldMap, fields, FLOAT, INT, Field::length, logfile, name, rowsize, UINT, and VARCHAR.

Referenced by TransactionAgent::TAaddcolumn().

54 {
55  class Field newfield(type, length, indextype, name);
56 
57  fields.push_back(newfield);
58  columnaNameToFieldMap[name] = fields.size() - 1;
59 
60  if (rowsize != -1)
61  {
62  rowsize += sizeof(bool);
63 
64  switch (type)
65  {
66  case INT:
67  rowsize += sizeof(int64_t);
68  break;
69 
70  case UINT:
71  rowsize += sizeof(uint64_t);
72  break;
73 
74  case BOOL:
75  rowsize += sizeof(bool);
76  break;
77 
78  case FLOAT:
79  rowsize += sizeof(long double);
80 
81  case CHAR:
82  rowsize += sizeof(char);
83  break;
84 
85  case CHARX:
86  rowsize += length;
87  break;
88 
89  case VARCHAR:
90  rowsize = -1;
91  break;
92 
93  default:
94  fprintf(logfile, "anomaly: %i %s %i\n", type, __FILE__, __LINE__);
95  }
96  }
97 
98  return fields.size() - 1;
99 }

Here is the caller graph for this function:

locktype_e Table::assignToLockQueue ( int64_t  rowid,
locktype_e  locktype,
int64_t  subtransactionid,
int64_t  pendingcmdid,
int64_t  tacmdentrypoint 
)

add subtransactionid to queue waiting to acquire lock on row

Parameters
rowidrowid
locktypelock type
subtransactionidsubtransactionid
pendingcmdidpending command by calling Transaction
tacmdentrypointentry point back to pending Transaction command
Returns

Definition at line 1047 of file Table.cc.

References getinsertflag(), lockQueue, lockQueueRowEntry::locktype, NOTFOUNDLOCK, lockQueueRowEntry::pendingcmdid, rows, lockQueueRowEntry::subtransactionid, and lockQueueRowEntry::tacmdentrypoint.

Referenced by selectrows().

1049 {
1050  if (getinsertflag(rows[rowid]->flags)==true)
1051  {
1052  return NOTFOUNDLOCK;
1053  }
1054 
1055  lockQueueRowEntry entry;
1056  entry.tacmdentrypoint = tacmdentrypoint;
1057  entry.locktype = locktype;
1058  entry.pendingcmdid = pendingcmdid;
1059  entry.subtransactionid = subtransactionid;
1060 
1061  lockQueue[rowid].push(entry);
1062 
1063  return locktype;
1064 }

Here is the call graph for this function:

Here is the caller graph for this function:

void Table::commitRollbackUnlock ( int64_t  rowid,
int64_t  subtransactionid,
enginecmd_e  cmd 
)

Definition at line 651 of file Table.cc.

References cleardeleteflag(), clearlockedflag(), clearreplacedeleteflag(), COMMITCMD, rowdata_s::flags, forwarderMap, getdeleteflag(), getinsertflag(), getlocktype(), getreplacedeleteflag(), logfile, rowdata_s::previoussubtransactionid, READLOCK, rowdata_s::readlockHolders, REVERTCMD, ROLLBACKCMD, rows, setreadlock(), shadowTable, UNLOCKCMD, WRITELOCK, and rowdata_s::writelockHolder.

Referenced by SubTransaction::commitRollbackUnlock(), and SubTransaction::processTransactionMessage().

653 {
654  switch (cmd)
655  {
656  case COMMITCMD:
657  {
658  rowdata_s &currentRowRef = *rows[rowid];
659 
660  if (getlocktype(currentRowRef.flags)==READLOCK) // just unlock
661  {
662  if (!currentRowRef.readlockHolders->count(subtransactionid))
663  {
664  printf("%s %i anomaly subtransactionid %li\n", __FILE__,
665  __LINE__, subtransactionid);
666  return; // bogus request
667  }
668 
669  currentRowRef.readlockHolders->erase(subtransactionid);
670 
671  if (currentRowRef.readlockHolders->empty()==true)
672  {
673  clearlockedflag(&currentRowRef.flags);
674  delete currentRowRef.readlockHolders;
675  currentRowRef.readlockHolders = NULL;
676  }
677 
678  return;
679  }
680 
681  if ((getlocktype(currentRowRef.flags) != WRITELOCK) ||
682  (currentRowRef.writelockHolder != subtransactionid))
683  {
684  printf("%s %i anomaly flags %i subtransactionid %li writelockHolder %li rowid %li cmd %i flags %i\n", __FILE__, __LINE__, (int)currentRowRef.flags,
685  subtransactionid, currentRowRef.writelockHolder, rowid, cmd,
686  (int)currentRowRef.flags);
687  return; // bogus request
688  }
689 
690  if (getdeleteflag(currentRowRef.flags)==true)
691  {
692  if (getreplacedeleteflag(currentRowRef.flags)==true)
693  {
694  forwarderMap.erase(rowid);
695  }
696 
697  delete &currentRowRef;
698  rows.erase(rowid);
699 
700  if (shadowTable->rows.count(rowid))
701  {
702  delete shadowTable->rows[rowid];
703  shadowTable->rows.erase(rowid);
704  }
705 
706  return;
707  }
708 
709  if (currentRowRef.readlockHolders != NULL)
710  {
711  printf("%s %i anomaly: readlockHolders\n", __FILE__, __LINE__);
712  boost::unordered_set<int64_t>::const_iterator it;
713 
714  for (it = currentRowRef.readlockHolders->begin();
715  it != currentRowRef.readlockHolders->end(); ++it)
716  {
717  printf("%s %i readlockHolder %li\n", __FILE__, __LINE__, *it);
718  }
719 
720  delete currentRowRef.readlockHolders;
721  currentRowRef.readlockHolders=NULL;
722  }
723 
724  // only change the row if changes have been made, this covers in case a
725  // locked row didn't get modified, but still part of a commit
726  if (shadowTable->rows.count(rowid))
727  {
728  rowdata_s &shadowRowRef = *shadowTable->rows[rowid];
729  shadowRowRef.previoussubtransactionid=currentRowRef.writelockHolder;
730  shadowRowRef.flags=0;
731  shadowRowRef.writelockHolder=0;
732  shadowRowRef.readlockHolders=NULL;
733 
734  if (rows[rowid]==shadowTable->rows[rowid]) // insert
735  {
736  shadowTable->rows.erase(rowid);
737  }
738  else // update
739  {
740  delete &currentRowRef;
741  rows[rowid]=&shadowRowRef;
742  shadowTable->rows.erase(rowid);
743  }
744  }
745  else
746  {
747  printf("%s %i anomaly\n", __FILE__, __LINE__);
748  currentRowRef.flags=0;
749  currentRowRef.writelockHolder=0;
750  }
751 
752  /*
753  if (shadowTable->rows.count(rowid))
754  {
755  if (currentRowRef.previoussubtransactionid==0)
756  {
757  currentRowRef.previoussubtransactionid = currentRowRef.writelockHolder;
758  currentRowRef.row = shadowTable->rows[rowid].row;
759  }
760  else
761  { // if update row uses string::copy() then the container's memory will be consumed
762  currentRowRef.previoussubtransactionid = currentRowRef.writelockHolder;
763  memcpy(&currentRowRef.row[0], &shadowTable->rows[rowid].row[0],
764  currentRowRef.row.size());
765  }
766  shadowTable->rows.erase(rowid);
767  }
768  currentRowRef.flags = 0;
769  currentRowRef.writelockHolder = 0;
770  */
771  }
772  break;
773 
774  case ROLLBACKCMD:
775  {
776  if (!rows.count(rowid))
777  {
778  return;
779  }
780 
781  rowdata_s &currentRowRef = *rows[rowid];
782 
783  if ((currentRowRef.writelockHolder != subtransactionid) &&
784  (getlocktype(currentRowRef.flags) == WRITELOCK))
785  {
786  fprintf(logfile, "anomaly: %s %i\n", __FILE__, __LINE__);
787  return; // bogus request
788  }
789 
790  if (getinsertflag(currentRowRef.flags)==true)
791  {
792  delete &currentRowRef;
793  rows.erase(rowid);
794  shadowTable->rows.erase(rowid);
795  // drain Q
796  return;
797  }
798 
799  if (getdeleteflag(currentRowRef.flags)==true)
800  {
801  if (getreplacedeleteflag(currentRowRef.flags)==true)
802  {
803  clearreplacedeleteflag(&currentRowRef.flags);
804  forwarderMap.erase(rowid);
805  }
806 
807  cleardeleteflag(&currentRowRef.flags);
808 
809  if (shadowTable->rows.count(rowid))
810  {
811  printf("%s %i anomaly rowid %li\n", __FILE__, __LINE__, rowid);
812  delete shadowTable->rows[rowid];
813  shadowTable->rows.erase(rowid);
814  }
815  }
816 
817  currentRowRef.writelockHolder = 0;
818 
819  if (getlocktype(currentRowRef.flags)==READLOCK)
820  {
821  currentRowRef.readlockHolders->erase(subtransactionid);
822 
823  if (currentRowRef.readlockHolders->empty()==true)
824  {
825  delete currentRowRef.readlockHolders;
826  currentRowRef.readlockHolders = NULL;
827  }
828  }
829 
830  currentRowRef.flags = 0;
831 
832  if (currentRowRef.readlockHolders != NULL)
833  {
834  setreadlock(&currentRowRef.flags);
835  }
836 
837  if (shadowTable->rows.count(rowid))
838  {
839  delete shadowTable->rows[rowid];
840  shadowTable->rows.erase(rowid);
841  }
842 
843  // process Q
844  }
845  break;
846 
847  case UNLOCKCMD:
848  {
849  rowdata_s &currentRowRef = *rows[rowid];
850 
851  if (getlocktype(currentRowRef.flags) != READLOCK)
852  {
853  fprintf(logfile, "anomaly: %s %i\n", __FILE__, __LINE__);
854  return; // bogus request
855  }
856 
857  if (!currentRowRef.readlockHolders->count(subtransactionid))
858  {
859  fprintf(logfile, "anomaly: %s %i\n", __FILE__, __LINE__);
860  return; // bogus request
861  }
862 
863  currentRowRef.readlockHolders->erase(subtransactionid);
864 
865  if (currentRowRef.readlockHolders->empty()==true)
866  {
867  clearlockedflag(&currentRowRef.flags);
868  delete currentRowRef.readlockHolders;
869  currentRowRef.readlockHolders = NULL;
870  }
871  }
872  break;
873 
874  // REVERTCMD likely broken somehow
875  case REVERTCMD:
876  {
877  // do what rollback does, but don't unlock
878  if (!rows.count(rowid))
879  {
880  return;
881  }
882 
883  rowdata_s &currentRowRef = *rows[rowid];
884 
885  if ((currentRowRef.writelockHolder != subtransactionid) ||
886  (getlocktype(currentRowRef.flags) != WRITELOCK))
887  {
888  fprintf(logfile, "anomaly: %s %i\n", __FILE__, __LINE__);
889  return; // bogus request
890  }
891 
892  if (getinsertflag(currentRowRef.flags)==true)
893  {
894  rows.erase(rowid);
895  }
896  else
897  {
898  currentRowRef.flags = 0;
899  }
900 
901  forwarderMap.erase(rowid);
902  shadowTable->rows.erase(rowid);
903  }
904  break;
905 
906  default:
907  fprintf(logfile, "anomaly %i %s %i\n", cmd, __FILE__, __LINE__);
908  }
909 }

Here is the call graph for this function:

Here is the caller graph for this function:

int64_t Table::deleterow ( int64_t  rowid,
int64_t  subtransactionid 
)

delete row

Parameters
rowidrowid
subtransactionidsubtransactionid
Returns

Definition at line 1026 of file Table.cc.

References rowdata_s::flags, getlocktype(), logfile, rows, setdeleteflag(), STATUS_NOTOK, STATUS_OK, WRITELOCK, and rowdata_s::writelockHolder.

Referenced by SubTransaction::deleterow(), and deleterow().

1027 {
1028  if (!rows.count(rowid))
1029  {
1030  return STATUS_NOTOK;
1031  }
1032 
1033  rowdata_s &currentRowRef = *rows[rowid];
1034 
1035  if ((getlocktype(currentRowRef.flags) != WRITELOCK) ||
1036  (currentRowRef.writelockHolder != subtransactionid))
1037  {
1038  fprintf(logfile, "anomaly %i %li %s %i\n", currentRowRef.flags,
1039  currentRowRef.writelockHolder, __FILE__, __LINE__);
1040  return STATUS_NOTOK;
1041  }
1042 
1043  setdeleteflag(&currentRowRef.flags);
1044  return STATUS_OK;
1045 }

Here is the call graph for this function:

Here is the caller graph for this function:

int64_t Table::deleterow ( int64_t  rowid,
int64_t  subtransactionid,
int64_t  forward_rowid,
int64_t  forward_engineid 
)

delete row part of replacement

Parameters
rowidrowid
subtransactionidsubtransactionid
forward_rowidrowid to forward index hits to
forward_engineidengineid to forward index hits to
Returns

Definition at line 428 of file Table.cc.

References deleterow(), forwarderEntry::engineid, rowdata_s::flags, forwarderMap, forwarderEntry::rowid, rows, setreplacedeleteflag(), and STATUS_OK.

430 {
431  int64_t status = deleterow(rowid, subtransactionid);
432 
433  if (status)
434  {
435  return status;
436  }
437 
438  rowdata_s &currentRowRef = *rows[rowid];
439 
440  setreplacedeleteflag(&currentRowRef.flags);
441  forwarderEntry forwarder;
442  forwarder.rowid = forward_rowid;
443  forwarder.engineid = forward_engineid;
444  forwarderMap[rowid] = forwarder;
445  return STATUS_OK;
446 }

Here is the call graph for this function:

string * Table::getname ( )

get name

Returns
name

Definition at line 47 of file Table.cc.

References name.

48 {
49  return &name;
50 }
int64_t Table::getnextrowid ( )

generate unique, ever-increasing row identifier

Returns
next rowid

Definition at line 1006 of file Table.cc.

References nextrowid.

Referenced by SubTransaction::newrow().

1007 {
1008  return ++nextrowid;
1009 }

Here is the caller graph for this function:

void Table::getrows ( vector< int64_t >  rowids,
locktype_e  locktype,
int64_t  subtransactionid,
int64_t  pendingcmdid,
vector< returnRow_s > *  returnRows,
vector< int64_t > *  lockPendingRowids,
int64_t  tacmdentrypoint 
)

orphan?

Parameters
rowids
locktype
subtransactionid
pendingcmdid
returnRows
lockPendingRowids
tacmdentrypoint

Definition at line 253 of file Table.cc.

References rowdata_s::flags, getinsertflag(), getlocktype(), lockQueue, lockQueueRowEntry::locktype, logfile, NOLOCK, lockQueueRowEntry::pendingcmdid, READLOCK, rowdata_s::readlockHolders, rowdata_s::row, returnRow_s::row, returnRow_s::rowid, rows, setreadlock(), setwritelock(), lockQueueRowEntry::subtransactionid, lockQueueRowEntry::tacmdentrypoint, WRITELOCK, and rowdata_s::writelockHolder.

258 {
259  if (locktype != NOLOCK)
260  {
261  lockPendingRowids->clear();
262  }
263 
264  rowdata_s *currentRowPtr;
265 
266  for (size_t n=0; n < rowids.size(); n++)
267  {
268  int64_t rid = rowids[n];
269 
270  if (rows.count(rid))
271  {
272  currentRowPtr = rows[rid];
273 
274  switch (locktype)
275  {
276  case NOLOCK:
277  {
278  if (getinsertflag(currentRowPtr->flags)==false)
279  {
280  returnRow_s r = {};
281  r.rowid = rid;
282  r.row = currentRowPtr->row;
283  returnRows->push_back(r);
284  }
285  }
286  break;
287 
288  case READLOCK:
289  {
290  switch (getlocktype(currentRowPtr->flags))
291  {
292  case NOLOCK: // lock it and add create readlockHolders
293  {
294  returnRow_s r = {};
295  r.rowid = rid;
296  r.row = currentRowPtr->row;
297  returnRows->push_back(r);
298  setreadlock(&currentRowPtr->flags);
299  currentRowPtr->readlockHolders =
300  new boost::unordered_set<int64_t>;
301  printf("%s %i ROWID %li READLOCKHOLDERS->insert %li\n",
302  __FILE__, __LINE__, rid, subtransactionid);
303  currentRowPtr->readlockHolders->insert(subtransactionid);
304  }
305  break;
306 
307  case READLOCK:
308  {
309  printf("%s %i ROWID %li READLOCKHOLDERS->insert %li\n",
310  __FILE__, __LINE__, rid, subtransactionid);
311  currentRowPtr->readlockHolders->insert(subtransactionid);
312  returnRow_s r = {};
313  r.rowid = rid;
314  r.row = currentRowPtr->row;
315  returnRows->push_back(r);
316  }
317  break;
318 
319  case WRITELOCK:
320  {
321  // make it pending
322  lockQueueRowEntry qEntry = {};
323  // populate qEntry, d'accord
324  qEntry.pendingcmdid = pendingcmdid;
325  qEntry.tacmdentrypoint = tacmdentrypoint;
326  qEntry.subtransactionid = subtransactionid;
327  qEntry.locktype = READLOCK;
328  lockQueue[rid].push(qEntry);
329  lockPendingRowids->push_back(rid);
330  }
331  break;
332 
333  default:
334  fprintf(logfile, "anomaly: %i %s %i\n",
335  getlocktype(currentRowPtr->flags), __FILE__,
336  __LINE__);
337  }
338  }
339  break;
340 
341  case WRITELOCK:
342  {
343  switch (getlocktype(currentRowPtr->flags))
344  {
345  case NOLOCK:
346  {
347  // lock it & return
348  setwritelock(&currentRowPtr->flags);
349  currentRowPtr->writelockHolder = subtransactionid;
350  returnRow_s r = {};
351  r.rowid = rid;
352  r.row = currentRowPtr->row;
353  returnRows->push_back(r);
354  }
355  break;
356 
357  case READLOCK:
358  {
359  // lock pending
360  lockQueueRowEntry qEntry = {};
361  // populate qEntry, d'accord
362  qEntry.pendingcmdid = pendingcmdid;
363  qEntry.tacmdentrypoint = tacmdentrypoint;
364  qEntry.subtransactionid = subtransactionid;
365  qEntry.locktype = WRITELOCK;
366  lockQueue[rid].push(qEntry);
367  lockPendingRowids->push_back(rid);
368  }
369  break;
370 
371  case WRITELOCK:
372  {
373  // lock pending
374  lockQueueRowEntry qEntry = {};
375  // populate qEntry, d'accord
376  qEntry.pendingcmdid = pendingcmdid;
377  qEntry.tacmdentrypoint = tacmdentrypoint;
378  qEntry.subtransactionid = subtransactionid;
379  qEntry.locktype = WRITELOCK;
380  lockQueue[rid].push(qEntry);
381  lockPendingRowids->push_back(rid);
382  }
383  break;
384 
385  default:
386  fprintf(logfile, "anomaly: %i %s %i\n",
387  getlocktype(currentRowPtr->flags), __FILE__,
388  __LINE__);
389  }
390  }
391  break;
392 
393  default:
394  fprintf(logfile, "anomaly: %i %s %i\n", locktype, __FILE__,
395  __LINE__);
396  }
397  }
398  }
399 }

Here is the call graph for this function:

bool Table::makerow ( vector< fieldValue_s > *  fieldVal,
std::string *  res 
)

assemble row string from fields

Parameters
fieldValfields
resresulting string
Returns
success or failure

Definition at line 101 of file Table.cc.

References BOOL, CHAR, CHARX, fields, FLOAT, INT, Field::length, logfile, rowsize, Field::type, UINT, and VARCHAR.

Referenced by Statement::branchtotype(), Statement::continueUpdate(), and Transaction::updateRow().

102 {
103  vector<fieldValue_s> &fieldValRef = *fieldVal;
104 
105  if (fieldValRef.size() != fields.size())
106  {
107  fprintf(logfile, "%s %i anomaly fieldValRef.size() %lu fields.size() %lu\n", __FILE__, __LINE__, (unsigned long)fieldValRef.size(),
108  (unsigned long)fields.size());
109  return false;
110  }
111 
112  if (rowsize != -1)
113  {
114  res->assign(rowsize, 0);
115  }
116  else
117  {
118  int64_t rsize = 0;
119  bool hasvarchar=false;
120 
121  for (size_t n=0; n<fieldValRef.size(); n++)
122  {
123  rsize += sizeof(bool);
124  rowsize += sizeof(bool);
125 
126  switch (fields[n].type)
127  {
128  case INT:
129  rsize += sizeof(int64_t);
130  break;
131 
132  case UINT:
133  rsize += sizeof(uint64_t);
134  break;
135 
136  case BOOL:
137  rsize += sizeof(bool);
138  break;
139 
140  case FLOAT:
141  rsize += sizeof(long double);
142  break;
143 
144  case CHAR:
145  rsize += sizeof(char);
146  break;
147 
148  case CHARX:
149  rsize += fields[n].length;
150  break;
151 
152  case VARCHAR:
153  rsize += sizeof(int64_t);
154  rsize += fieldValRef[n].str.length();
155  hasvarchar=true;
156  break;
157 
158  default:
159  fprintf(logfile, "anomaly: %i %s %i\n", fields[n].type, __FILE__,
160  __LINE__);
161  }
162 
163  }
164 
165  if (hasvarchar==true)
166  {
167  rowsize=-1;
168  }
169 
170  res->assign(rsize, 0);
171  }
172 
173  int64_t pos = 0;
174 
175  for (size_t n=0; n<fields.size(); n++)
176  {
177  if (fieldValRef[n].isnull==false)
178  {
179  res->operator [](pos++)=0;
180  }
181  else
182  {
183  res->operator[](pos++)=1;
184  continue;
185  }
186 
187  switch (fields[n].type)
188  {
189  case INT:
190  memcpy(&res->operator [](pos), &fieldValRef[n].value.integer,
191  sizeof(fieldValRef[n].value.integer));
192  pos += sizeof(fieldValRef[n].value.integer);
193  break;
194 
195  case UINT:
196  memcpy(&res->operator [](pos), &fieldValRef[n].value.uinteger,
197  sizeof(fieldValRef[n].value.uinteger));
198  pos += sizeof(fieldValRef[n].value.uinteger);
199  break;
200 
201  case BOOL:
202  memcpy(&res->operator [](pos), &fieldValRef[n].value.boolean,
203  sizeof(fieldValRef[n].value.boolean));
204  pos += sizeof(fieldValRef[n].value.boolean);
205  break;
206 
207  case FLOAT:
208  memcpy(&res->operator [](pos), &fieldValRef[n].value.floating,
209  sizeof(fieldValRef[n].value.floating));
210  pos += sizeof(fieldValRef[n].value.floating);
211  break;
212 
213  case CHAR:
214  memcpy(&res->operator [](pos), &fieldValRef[n].value.character,
215  sizeof(fieldValRef[n].value.character));
216  pos += sizeof(fieldValRef[n].value.character);
217  break;
218 
219  case CHARX:
220 
221  // pad if necessary
222  if (fieldValRef[n].str.length() < (size_t)fields[n].length)
223  {
224  fieldValRef[n].str.append(fields[n].length-
225  fieldValRef[n].str.length(), ' ');
226  }
227 
228  fieldValRef[n].str.copy(&res->operator [](pos), fields[n].length, 0);
229  pos += fields[n].length;
230  break;
231 
232  case VARCHAR:
233  {
234  int64_t varcharlength = fieldValRef[n].str.length();
235  memcpy(&res->operator [](pos),
236  &varcharlength, sizeof(varcharlength));
237  pos += sizeof(varcharlength);
238  memcpy(&res->operator [](pos), fieldValRef[n].str.c_str(),
239  varcharlength);
240  pos += varcharlength;
241  }
242  break;
243 
244  default:
245  fprintf(logfile, "anomaly: %i %s %i\n", fields[n].type, __FILE__,
246  __LINE__);
247  }
248  }
249 
250  return true;
251 }

Here is the caller graph for this function:

void Table::newrow ( int64_t  newrowid,
int64_t  subtransactionid,
string &  row 
)

create new row

Parameters
newrowidrowid
subtransactionidsubtransactionid
rowrow

Definition at line 1011 of file Table.cc.

References rowdata_s::flags, rowdata_s::row, rows, setinsertflag(), setwritelock(), shadowTable, and rowdata_s::writelockHolder.

Referenced by SubTransaction::newrow().

1012 {
1013  rowdata_s *nrow = new rowdata_s();
1014  // nrow->flags = 0;
1015  setwritelock(&nrow->flags);
1016  nrow->writelockHolder = subtransactionid;
1017  setinsertflag(&nrow->flags);
1018  // nrow.previoussubtransactionid = 0;
1019  nrow->row = row;
1020  // nrow.readlockHolders=NULL;
1021 
1022  rows[newrowid] = nrow;
1023  shadowTable->rows[newrowid] = nrow;
1024 }

Here is the call graph for this function:

Here is the caller graph for this function:

void Table::selectrows ( vector< int64_t > *  rowids,
locktype_e  locktype,
int64_t  subtransactionid,
int64_t  pendingcmdid,
vector< returnRow_s > *  returnRows,
int64_t  tacmdentrypoint 
)

return rows for select based on index hits

Parameters
rowidslist of rowids
locktypelock type
subtransactionidsubtransactionid
pendingcmdidpending command by calling Transaction
returnRowsreturn rows
tacmdentrypointentry point back to pending Transaction command

Definition at line 448 of file Table.cc.

References assignToLockQueue(), getlocktype(), returnRow_s::locktype, logfile, NOLOCK, NOTFOUNDLOCK, PENDINGLOCK, READLOCK, returnRow_s::row, returnRow_s::rowid, rows, setreadlock(), setwritelock(), and WRITELOCK.

Referenced by SubTransaction::selectrows().

451 {
452  vector<returnRow_s> &returnRowsRef = *returnRows;
453  size_t numrowids = rowids->size();
454  returnRowsRef.reserve(numrowids);
455  returnRow_s workrow;
456  int64_t rowid;
457 
458  switch (locktype)
459  {
460  case NOLOCK:
461  {
462  for (size_t n=0; n<numrowids; n++)
463  {
464  rowid = rowids->at(n);
465  workrow.rowid = rowid;
466 
467  if (!rows.count(rowid))
468  {
469  workrow.row.clear();
470  workrow.locktype = NOTFOUNDLOCK;
471  }
472  else
473  {
474  switch (getlocktype(rows[rowid]->flags))
475  {
476  case NOLOCK:
477  break;
478 
479  case READLOCK:
480  if (rows[rowid]->readlockHolders->count(subtransactionid))
481  {
482  continue;
483  }
484 
485  break;
486 
487  case WRITELOCK:
488  if (rows[rowid]->writelockHolder==subtransactionid)
489  {
490  continue;
491  }
492 
493  break;
494 
495  default:
496  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
497  getlocktype(rows[rowid]->flags));
498  continue;
499  }
500 
501  workrow.row = rows[rowid]->row;
502  workrow.locktype = NOLOCK;
503  }
504 
505  returnRowsRef.push_back(workrow);
506  }
507  }
508  break;
509 
510  case READLOCK:
511  {
512  for (size_t n=0; n<numrowids; n++)
513  {
514  rowid = rowids->at(n);
515  workrow.rowid = rowid;
516 
517  if (!rows.count(rowid))
518  {
519  workrow.row.clear();
520  workrow.locktype = NOTFOUNDLOCK;
521  }
522  else
523  {
524  switch (getlocktype(rows[rowid]->flags))
525  {
526  case NOLOCK: // lock it & return row
527  setreadlock(&rows[rowid]->flags);
528  rows[rowid]->readlockHolders =
529  new boost::unordered_set<int64_t>;
530  rows[rowid]->readlockHolders->insert(subtransactionid);
531  workrow.row = rows[rowid]->row;
532  workrow.locktype = READLOCK;
533  break;
534 
535  case READLOCK:
536  if (rows[rowid]->readlockHolders->count(subtransactionid))
537  {
538  continue;
539  }
540  else
541  {
542  rows[rowid]->readlockHolders->insert(subtransactionid);
543  workrow.row = rows[rowid]->row;
544  workrow.locktype = READLOCK;
545  }
546 
547  break;
548 
549  case WRITELOCK: // pending
550  {
551  if (rows[rowid]->writelockHolder==subtransactionid)
552  {
553  continue;
554  }
555 
556  if (assignToLockQueue(rowid, READLOCK, subtransactionid,
557  pendingcmdid,
558  tacmdentrypoint)==NOTFOUNDLOCK)
559  {
560  continue;
561  }
562 
563  workrow.row.clear();
564  workrow.locktype = PENDINGLOCK;
565  }
566  break;
567 
568  default:
569  fprintf(logfile, "anomaly: %i %s %i\n",
570  getlocktype(rows[rowid]->flags), __FILE__, __LINE__);
571  }
572  }
573 
574  returnRowsRef.push_back(workrow);
575  }
576  }
577  break;
578 
579  case WRITELOCK:
580  {
581  for (size_t n=0; n<numrowids; n++)
582  {
583  rowid = rowids->at(n);
584  workrow.rowid = rowid;
585 
586  if (!rows.count(rowid))
587  {
588  workrow.row.clear();
589  workrow.locktype = NOTFOUNDLOCK;
590  }
591  else
592  {
593  switch (getlocktype(rows[rowid]->flags))
594  {
595  case NOLOCK: // lock it & return row
596  setwritelock(&rows[rowid]->flags);
597  rows[rowid]->writelockHolder = subtransactionid;
598  workrow.row = rows[rowid]->row;
599  workrow.locktype = WRITELOCK;
600  break;
601 
602  case READLOCK: // pending
603  if (assignToLockQueue(rowid, WRITELOCK, subtransactionid,
604  pendingcmdid,
605  tacmdentrypoint)==NOTFOUNDLOCK)
606  {
607  continue;
608  }
609 
610  workrow.row.clear();
611  workrow.locktype = PENDINGLOCK;
612  break;
613 
614  case WRITELOCK: // pending
615  if (subtransactionid == rows[rowid]->writelockHolder)
616  {
617  workrow.row = rows[rowid]->row;
618  workrow.locktype = WRITELOCK;
619  }
620  else
621  {
622  if (assignToLockQueue(rowid, WRITELOCK, subtransactionid,
623  pendingcmdid,
624  tacmdentrypoint)==NOTFOUNDLOCK)
625  {
626  continue;
627  }
628 
629  workrow.row.clear();
630  workrow.locktype = PENDINGLOCK;
631  }
632 
633  break;
634 
635  default:
636  fprintf(logfile, "anomaly: %i %s %i\n",
637  getlocktype(rows[rowid]->flags), __FILE__, __LINE__);
638  }
639  }
640 
641  returnRowsRef.push_back(workrow);
642  }
643  }
644  break;
645 
646  default:
647  fprintf(logfile, "anomaly: %i %s %i\n", locktype, __FILE__, __LINE__);
648  }
649 }

Here is the call graph for this function:

Here is the caller graph for this function:

void Table::setname ( string  namearg)

set name

Parameters
nameargname

Definition at line 42 of file Table.cc.

References name.

43 {
44  name = namearg;
45 }
bool Table::unmakerow ( std::string *  rowstring,
vector< fieldValue_s > *  resultFields 
)

extract fields from row string

Parameters
rowstringinput row
resultFieldsresulting fields
Returns
success or failure

Definition at line 911 of file Table.cc.

References BOOL, CHAR, CHARX, fields, FLOAT, INT, Field::length, logfile, rowsize, Field::type, UINT, and VARCHAR.

Referenced by Statement::andPredicate(), Transaction::continueCommitTransaction(), Statement::continueSelect(), Transaction::continueSqlReplace(), Statement::continueUpdate(), TransactionAgent::handledispatch(), ApiInterface::insertRow(), Statement::stagedPredicate(), and Transaction::updateRow().

912 {
913  vector<fieldValue_s> &resultFieldsRef = *resultFields;
914  string &rowstringRef = *rowstring;
915 
916  size_t pos = 0;
917  size_t numfields = fields.size();
918  resultFieldsRef.resize(numfields, fieldValue_s());
919  size_t rowsize = rowstringRef.size();
920 
921  for (size_t n=0; n < numfields; n++)
922  {
923  if (pos >= rowsize-1) // remember the bool for isnull or not
924  {
925  return false;
926  }
927 
928  if (rowstringRef[pos++] == 0)
929  {
930  resultFieldsRef[n].isnull = false;
931  }
932  else
933  {
934  resultFieldsRef[n].isnull = true;
935  continue;
936  }
937 
938  switch (fields[n].type)
939  {
940  case INT:
941  memcpy(&resultFieldsRef[n].value.integer, &rowstringRef[pos],
942  sizeof(resultFieldsRef[n].value.integer));
943  pos += sizeof(resultFieldsRef[n].value.integer);
944  break;
945 
946  case UINT:
947  memcpy(&resultFieldsRef[n].value.uinteger, &rowstringRef[pos],
948  sizeof(resultFieldsRef[n].value.uinteger));
949  pos += sizeof(resultFieldsRef[n].value.uinteger);
950  break;
951 
952  case BOOL:
953  memcpy(&resultFieldsRef[n].value.boolean, &rowstringRef[pos],
954  sizeof(resultFieldsRef[n].value.boolean));
955  pos += sizeof(resultFieldsRef[n].value.boolean);
956  break;
957 
958  case FLOAT:
959  memcpy(&resultFieldsRef[n].value.floating, &rowstringRef[pos],
960  sizeof(resultFieldsRef[n].value.floating));
961  pos += sizeof(resultFieldsRef[n].value.floating);
962  break;
963 
964  case CHAR:
965  memcpy(&resultFieldsRef[n].value.character, &rowstringRef[pos],
966  sizeof(resultFieldsRef[n].value.character));
967  pos += sizeof(resultFieldsRef[n].value.character);
968  break;
969 
970  case CHARX: // makerow() already padded this field to the length of the
971  // char(x)
972  resultFieldsRef[n].str.assign(rowstringRef, pos, fields[n].length);
973 
974  if (resultFieldsRef[n].str.size() < fields[n].length)
975  {
976  // this should not be, but pad it anyway
977  printf("%s %i rowstring.size() %lu field %lu resultFieldsRef[n].str.size() %lu fields[n].length %lu\n", __FILE__, __LINE__,
978  (unsigned long)rowstring->size(), (unsigned long)n,
979  resultFieldsRef[n].str.size(), fields[n].length);
980  resultFieldsRef[n].str.append(fields[n].length -
981  resultFieldsRef[n].str.size(), 0);
982  }
983 
984  pos += fields[n].length;
985  break;
986 
987  case VARCHAR:
988  {
989  int64_t varcharlength;
990  memcpy(&varcharlength, &rowstringRef[pos], sizeof(varcharlength));
991  pos += sizeof(varcharlength);
992  resultFieldsRef[n].str.assign(rowstringRef, pos, varcharlength);
993  pos += varcharlength;
994  }
995  break;
996 
997  default:
998  fprintf(logfile, "anomaly: %i %s %i\n", fields[n].type, __FILE__,
999  __LINE__);
1000  }
1001  }
1002 
1003  return true;
1004 }

Here is the caller graph for this function:

int64_t Table::updaterow ( int64_t  rowid,
int64_t  subtransactionid,
string *  row 
)

modify row

Parameters
rowidrowid
subtransactionidsubtransactionid
rownew row
Returns
status

Definition at line 401 of file Table.cc.

References rowdata_s::flags, getlocktype(), logfile, rowdata_s::row, rows, shadowTable, STATUS_NOTOK, STATUS_OK, WRITELOCK, and rowdata_s::writelockHolder.

Referenced by SubTransaction::updaterow().

402 {
403  if (!rows.count(rowid))
404  {
405  return STATUS_NOTOK;
406  }
407 
408  rowdata_s &currentRowRef = *rows[rowid];
409 
410  if ((getlocktype(currentRowRef.flags) != WRITELOCK) ||
411  (currentRowRef.writelockHolder != subtransactionid))
412  {
413  fprintf(logfile, "anomaly %i %li %s %i\n", currentRowRef.flags,
414  currentRowRef.writelockHolder, __FILE__, __LINE__);
415  return STATUS_NOTOK;
416  }
417 
418  // should probably validate the row is not garbage, but o well
419  rowdata_s *nrow=new rowdata_s();
420  nrow->row=*row;
421  shadowTable->rows[rowid]=nrow;
422 
423  return STATUS_OK;
424 }

Here is the call graph for this function:

Here is the caller graph for this function:

Friends And Related Function Documentation

friend class ApiInterface
friend

Definition at line 87 of file Table.h.

friend class Engine
friend

Definition at line 89 of file Table.h.

friend class SubTransaction
friend

Definition at line 91 of file Table.h.

friend class Transaction
friend

Definition at line 90 of file Table.h.

friend class TransactionAgent
friend

Definition at line 88 of file Table.h.

friend class UserSchemaMgr
friend

Definition at line 92 of file Table.h.

Member Data Documentation

boost::unordered_map<std::string, int64_t> Table::columnaNameToFieldMap

Definition at line 247 of file Table.h.

Referenced by addfield().

boost::unordered_map<int64_t, forwarderEntry> Table::forwarderMap

Definition at line 254 of file Table.h.

Referenced by commitRollbackUnlock(), and deleterow().

int64_t Table::id

Definition at line 241 of file Table.h.

boost::unordered_map< int64_t, std::queue<lockQueueRowEntry> > Table::lockQueue

Definition at line 245 of file Table.h.

Referenced by assignToLockQueue(), SubTransaction::drainRowLockQueue(), and getrows().

std::string Table::name

Definition at line 242 of file Table.h.

Referenced by UserSchemaMgr::addcolumn(), addfield(), getname(), setname(), and Table().

int64_t Table::nextindexid

Definition at line 243 of file Table.h.

int64_t Table::nextrowid

Definition at line 252 of file Table.h.

Referenced by getnextrowid().

int64_t Table::rowsize

Definition at line 251 of file Table.h.

Referenced by addfield(), makerow(), Table(), and unmakerow().

class Table* Table::shadowTable

Definition at line 246 of file Table.h.

Referenced by commitRollbackUnlock(), newrow(), Table(), updaterow(), and ~Table().


The documentation for this class was generated from the following files: