public override object VisitScientific([NotNull] MiniSQLParser.ScientificContext context) { AtomValue value = new AtomValue(); if (context.INT_NUMBER() != null) { value.Type = AttributeTypes.Int; value.IntegerValue = int.Parse(context.INT_NUMBER().GetText()); } else if (context.DECIMAL_NUMBER() != null) { value.Type = AttributeTypes.Float; value.FloatValue = float.Parse(context.DECIMAL_NUMBER().GetText()); } else if (context.SINGLE_QUOTED_TEXT() != null) { value.Type = AttributeTypes.Char; string withQuotes = context.SINGLE_QUOTED_TEXT().GetText(); value.StringValue = withQuotes.Substring(1, withQuotes.Length - 2); value.CharLimit = Encoding.UTF8.GetByteCount(value.StringValue); } else if (context.DOUBLE_QUOTED_TEXT() != null) { value.Type = AttributeTypes.Char; string withQuotes = context.DOUBLE_QUOTED_TEXT().GetText(); value.StringValue = withQuotes.Substring(1, withQuotes.Length - 2); value.CharLimit = Encoding.UTF8.GetByteCount(value.StringValue); } else { throw new System.NotImplementedException(); } return(value); }
private static void TestFullCalculate() { Expression exp = GetAndsExpression(); List <AttributeValue> nameValuePairs = new List <AttributeValue>(); nameValuePairs.Add(new AttributeValue("a", new AtomValue { Type = AttributeTypes.Int, IntegerValue = 33 })); nameValuePairs.Add(new AttributeValue("b", new AtomValue { Type = AttributeTypes.Char, CharLimit = 5, StringValue = "stc" })); nameValuePairs.Add(new AttributeValue("c", new AtomValue { Type = AttributeTypes.Float, FloatValue = 6.0 })); AtomValue result = exp.Calculate(nameValuePairs); Assert.True(result.BooleanValue); nameValuePairs[1].Value.StringValue = "stz"; result = exp.Calculate(nameValuePairs); Assert.False(result.BooleanValue); }
private SelectResult HandleSelectStatement(ShowStatement statement) { List <SchemaRecord> tableSchemas = _catalogManager.GetTablesSchemaRecord(); SelectResult result = new SelectResult(); result.ColumnDeclarations = new List <AttributeDeclaration>() { new AttributeDeclaration() { AttributeName = "Table", Type = AttributeTypes.Char, CharLimit = 80 } }; result.Rows = new List <List <AtomValue> >(); foreach (SchemaRecord tableSchema in tableSchemas) { List <AtomValue> row = new List <AtomValue>(); AtomValue col = new AtomValue(); col.Type = AttributeTypes.Char; col.CharLimit = 80; col.StringValue = tableSchema.Name; row.Add(col); result.Rows.Add(row); } return(result); }
static void TestInternalIndexCell() { // init record DBRecord record = GetTestBRecord(); // init key List <AtomValue> keyValues = new List <AtomValue>(); AtomValue key = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 8, StringValue = "114514" }; keyValues.Add(key); DBRecord keyRecord = new DBRecord(keyValues); // make raw bytes List <byte> rawNode = new List <byte>(); rawNode.AddRange(new byte[30]); // build cell InternalIndexCell internalIndexCell = new InternalIndexCell(record, 114514, keyRecord); byte[] raw = internalIndexCell.Pack(); rawNode.AddRange(raw); // clone InternalIndexCell clone = new InternalIndexCell(rawNode.ToArray(), 30); // assert AssertCell(internalIndexCell, clone); Assert.Equal(internalIndexCell.ChildPage, clone.ChildPage); AssertDBRecords(internalIndexCell.PrimaryKey, clone.PrimaryKey); }
public int CreateIndex(int tableRootPage, string indexedColumnName, List <AttributeDeclaration> attributeDeclarations) { BTreeNode indexRoot = _bTree.OccupyNewTableNode(); BTreeNode tableRoot = BTreeNodeHelper.GetBTreeNode(_pager, tableRootPage); int indexedColumnIndex = attributeDeclarations.FindIndex(x => x.AttributeName == indexedColumnName); foreach (BTreeCell tableCell in _bTree.LinearSearch(tableRoot)) { AtomValue indexedValue = ((LeafTableCell)tableCell).DBRecord.GetValues()[indexedColumnIndex]; AtomValue primaryKey = ((LeafTableCell)tableCell).Key.GetValues()[0]; // List<AtomValue> indexPrimaryKeyPair = new List<AtomValue>() { indexedValue, primaryKey }; List <AtomValue> wrappedPrimaryKey = new List <AtomValue>() { primaryKey }; DBRecord wrappedKey = new DBRecord(new List <AtomValue>() { indexedValue }); // DBRecord wrappedValues = new DBRecord(indexPrimaryKeyPair); DBRecord wrappedValues = new DBRecord(wrappedPrimaryKey); indexRoot = _bTree.InsertCell(indexRoot, wrappedKey, wrappedValues); } return(indexRoot.RawPage.PageNumber); }
static void TestLeafTableCell() { // init record DBRecord record = GetTestBRecord(); // init key List <AtomValue> keyValues = new List <AtomValue>(); AtomValue key = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 8, StringValue = "114514" }; keyValues.Add(key); DBRecord keyRecord = new DBRecord(keyValues); // make raw bytes List <byte> rawNode = new List <byte>(); rawNode.AddRange(new byte[30]); // build cell LeafTableCell leafTableCell = new LeafTableCell(keyRecord, record); byte[] raw = leafTableCell.Pack(); rawNode.AddRange(raw); // clone LeafTableCell leafTableCellClone = new LeafTableCell(rawNode.ToArray(), 30); // assert AssertDBRecords(leafTableCell.DBRecord, leafTableCellClone.DBRecord); AssertCell(leafTableCell, leafTableCellClone); }
public static AtomValue operator +(AtomValue leftValue, AtomValue rightValue) { ThrowErrorIfNotSameType(leftValue, rightValue); AtomValue result = new AtomValue(); result.Type = leftValue.Type; switch (leftValue.Type) { case AttributeTypes.Char: result.StringValue = leftValue.StringValue + rightValue.StringValue; break; case AttributeTypes.Float: result.FloatValue = leftValue.FloatValue + rightValue.FloatValue; break; case AttributeTypes.Int: result.IntegerValue = leftValue.IntegerValue + rightValue.IntegerValue; break; case AttributeTypes.Null: throw new System.NullReferenceException(); } return(result); }
static DBRecord GetTestBRecord(int key = 222) { // init record List <AtomValue> values = new List <AtomValue>(); AtomValue value1 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = key }; AtomValue value2 = new AtomValue() { Type = AttributeTypes.Null }; AtomValue value3 = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 5, StringValue = "222" }; values.Add(value1); values.Add(value2); values.Add(value3); DBRecord record = new DBRecord(values); DBRecord cloneRecord = new DBRecord(record.Pack(), 0); AssertDBRecords(record, cloneRecord); return(record); }
static void AssertAtomValue(AtomValue v1, AtomValue v2) { Assert.Equal(v1.Type, v2.Type); Assert.Equal(v1.CharLimit, v2.CharLimit); Assert.Equal(v1.FloatValue, v2.FloatValue); Assert.Equal(v1.IntegerValue, v2.IntegerValue); Assert.Equal(v1.StringValue, v2.StringValue); }
private static void ThrowErrorIfNotSameType(AtomValue leftValue, AtomValue rightValue) { // make sure the types of children are the same if (leftValue?.Type != rightValue?.Type) { throw new System.Exception("Operands type not matched!"); } }
static void AssertAtomValue(AtomValue v1, AtomValue v2) { Debug.Assert(v1.Type == v2.Type); Debug.Assert(v1.CharLimit == v2.CharLimit); Debug.Assert(v1.FloatValue == v2.FloatValue); Debug.Assert(v1.IntegerValue == v2.IntegerValue); Debug.Assert(v1.StringValue == v2.StringValue); }
public override bool Equals(AtomValue other) { IntValue o = (IntValue)other; if (o != null) { return(this.value == o.value); } return(false); }
private static void TestCalculateSingleValue() { Expression andsExpression = GetAndsExpression(); string attributeName = "b"; AtomValue attributeValue = new AtomValue(); attributeValue.Type = AttributeTypes.Char; attributeValue.CharLimit = 10; attributeValue.StringValue = "aaa"; Assert.True(andsExpression.CheckKey(attributeName, attributeValue)); }
// return new root page number public int InsertRecord(List <AtomValue> values, AtomValue key, int rootPage) { BTreeNode node = BTreeNodeHelper.GetBTreeNode(_pager, rootPage); DBRecord wrappedKey = new DBRecord(new List <AtomValue>() { key }); DBRecord wrappedValues = new DBRecord(values); BTreeNode newRoot = _bTree.InsertCell(node, wrappedKey, wrappedValues); return(newRoot.RawPage.PageNumber); }
public static AtomValue operator <(AtomValue leftValue, AtomValue rightValue) { AtomValue result = new AtomValue(); result.Type = AttributeTypes.Int; switch (leftValue.Type) { case AttributeTypes.Char: ThrowErrorIfNotSameType(leftValue, rightValue); result.IntegerValue = string.Compare(leftValue.StringValue, rightValue.StringValue) < 0 ? 1 : 0; break; case AttributeTypes.Float: switch (rightValue.Type) { case AttributeTypes.Int: result.IntegerValue = leftValue.FloatValue < rightValue.IntegerValue ? 1 : 0; break; case AttributeTypes.Float: result.IntegerValue = leftValue.FloatValue < rightValue.FloatValue ? 1 : 0; break; default: ThrowErrorIfNotSameType(leftValue, rightValue); break; } break; case AttributeTypes.Int: switch (rightValue.Type) { case AttributeTypes.Int: result.IntegerValue = leftValue.IntegerValue < rightValue.IntegerValue ? 1 : 0; break; case AttributeTypes.Float: result.IntegerValue = leftValue.IntegerValue < rightValue.FloatValue ? 1 : 0; break; default: ThrowErrorIfNotSameType(leftValue, rightValue); break; } result.IntegerValue = leftValue.IntegerValue < rightValue.IntegerValue ? 1 : 0; break; case AttributeTypes.Null: throw new System.NullReferenceException(); } return(result); }
private static DBRecord GetTestKey_expression(int value_1) { List <AtomValue> values = new List <AtomValue>(); AtomValue value1 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = value_1 }; values.Add(value1); DBRecord record = new DBRecord(values); return(record); }
// return null if not found public List <AtomValue> SelectRecord(AtomValue key, int rootPage) { List <AtomValue> wrapper = new List <AtomValue> { key }; DBRecord keyDBRecord = new DBRecord(wrapper); BTreeNode node = BTreeNodeHelper.GetBTreeNode(_pager, rootPage); BTreeCell cell = _bTree.FindCell(keyDBRecord, node); List <AtomValue> result = null; result = ((LeafTableCell)cell)?.DBRecord.GetValues(); return(result); }
private static void TestAtomValueOperators() { AtomValue left = new AtomValue(); AtomValue right = new AtomValue(); left.StringValue = "abedeb"; left.IntegerValue = 114; left.FloatValue = 14.14; right.StringValue = "abeceb"; right.IntegerValue = 514; right.FloatValue = 14.14; left.Type = AttributeTypes.Char; right.Type = AttributeTypes.Char; Debug.Assert((left < right).BooleanValue == false); Debug.Assert((left > right).BooleanValue == true); Debug.Assert((left == right).BooleanValue == false); Debug.Assert((left != right).BooleanValue == true); Debug.Assert((left <= right).BooleanValue == false); Debug.Assert((left >= right).BooleanValue == true); Debug.Assert((left + right).StringValue == "abedebabeceb"); left.Type = AttributeTypes.Int; right.Type = AttributeTypes.Int; Debug.Assert((left < right).BooleanValue == true); Debug.Assert((left > right).BooleanValue == false); Debug.Assert((left == right).BooleanValue == false); Debug.Assert((left != right).BooleanValue == true); Debug.Assert((left <= right).BooleanValue == true); Debug.Assert((left >= right).BooleanValue == false); Debug.Assert((left + right).IntegerValue == 628); Debug.Assert((left - right).IntegerValue == -400); Debug.Assert((left * right).IntegerValue == 114 * 514); Debug.Assert((left / right).IntegerValue == 114 / 514); left.Type = AttributeTypes.Float; right.Type = AttributeTypes.Float; Debug.Assert((left < right).BooleanValue == false); Debug.Assert((left > right).BooleanValue == false); Debug.Assert((left == right).BooleanValue == true); Debug.Assert((left != right).BooleanValue == false); Debug.Assert((left <= right).BooleanValue == true); Debug.Assert((left >= right).BooleanValue == true); Debug.Assert((left + right).FloatValue == 28.28); Debug.Assert((left - right).FloatValue == 0.0); Debug.Assert((left * right).FloatValue == 14.14 * 14.14); Debug.Assert((left / right).FloatValue == 1); }
private static void TestAtomValueOperators() { AtomValue left = new AtomValue(); AtomValue right = new AtomValue(); left.StringValue = "abedeb"; left.IntegerValue = 114; left.FloatValue = 14.14; right.StringValue = "abeceb"; right.IntegerValue = 514; right.FloatValue = 14.14; left.Type = AttributeTypes.Char; right.Type = AttributeTypes.Char; Assert.False((left < right).BooleanValue); Assert.True((left > right).BooleanValue); Assert.False((left == right).BooleanValue); Assert.True((left != right).BooleanValue); Assert.False((left <= right).BooleanValue); Assert.True((left >= right).BooleanValue); Assert.Equal("abedebabeceb", (left + right).StringValue); left.Type = AttributeTypes.Int; right.Type = AttributeTypes.Int; Assert.True((left < right).BooleanValue); Assert.False((left > right).BooleanValue); Assert.False((left == right).BooleanValue); Assert.True((left != right).BooleanValue); Assert.True((left <= right).BooleanValue); Assert.False((left >= right).BooleanValue); Assert.Equal(628, (left + right).IntegerValue); Assert.Equal(-400, (left - right).IntegerValue); Assert.Equal(114 * 514, (left * right).IntegerValue); Assert.Equal(114 / 514, (left / right).IntegerValue); left.Type = AttributeTypes.Float; right.Type = AttributeTypes.Float; Assert.False((left < right).BooleanValue); Assert.False((left > right).BooleanValue); Assert.True((left == right).BooleanValue); Assert.False((left != right).BooleanValue); Assert.True((left <= right).BooleanValue); Assert.True((left >= right).BooleanValue); Assert.Equal(28.28, (left + right).FloatValue); Assert.Equal(0.0, (left - right).FloatValue); Assert.Equal(14.14 * 14.14, (left * right).FloatValue); Assert.Equal(1, (left / right).FloatValue); }
private static void TestInsertRandomRecord(int maxCell) { string dbPath = "./testdbfile.minidb"; File.Delete(dbPath); Pager pager = new Pager(dbPath); FreeList freeList = new FreeList(pager); BTreeController controller = new BTreeController(pager, freeList); RecordContext recordManager = new RecordContext(pager, controller); // create new table CreateStatement createStatement = GetCreateStatement(); int newRoot = recordManager.CreateTable(); // insert BTreeNode node; InsertStatement insertStatement; int key; int newRootAfterInsert = newRoot; int i; for (i = 0; i < maxCell; i++) { (insertStatement, key) = GetInsertStatement(1); AtomValue atomValue = GetAtomValue(key); newRootAfterInsert = recordManager.InsertRecord(insertStatement.Values, atomValue, newRootAfterInsert); Console.WriteLine(key); Debug.Assert(newRoot == newRootAfterInsert); } node = BTreeNodeHelper.GetBTreeNode(pager, newRootAfterInsert); BTreeNodeHelper.VisualizeIntegerTree(pager, node); Console.WriteLine(); for (i = 0; i < maxCell; i++) { (insertStatement, key) = GetInsertStatement(1); AtomValue atomValue = GetAtomValue(key); newRootAfterInsert = recordManager.InsertRecord(insertStatement.Values, atomValue, newRootAfterInsert); Console.WriteLine(key); } node = BTreeNodeHelper.GetBTreeNode(pager, newRootAfterInsert); BTreeNodeHelper.VisualizeIntegerTree(pager, node); pager.Close(); }
static void TestDBRecord() { // init record List <AtomValue> values = new List <AtomValue>(); AtomValue value1 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = 222 }; AtomValue value2 = new AtomValue() { Type = AttributeTypes.Null }; AtomValue value3 = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 5, StringValue = "222" }; values.Add(value1); values.Add(value2); values.Add(value3); DBRecord record = new DBRecord(values); // make raw bytes List <byte> rawNode = new List <byte>(); rawNode.AddRange(new byte[30]); // clone List <AtomValue> valuesOut1 = record.GetValues(); // clone byte[] raw = record.Pack(); rawNode.AddRange(raw); record.Unpack(rawNode.ToArray(), 30); List <AtomValue> valuesOut2 = record.GetValues(); int i; for (i = 0; i < valuesOut2.Count; i++) { AssertAtomValue(values[i], valuesOut2[i]); AssertAtomValue(valuesOut1[i], valuesOut2[i]); } }
private void HandleStatement(InsertStatement statement) { _catalogManager.CheckValidation(statement); // get table schema SchemaRecord schema = _catalogManager.GetTableSchemaRecord(statement.TableName); // adjust inlined type in insert statement if (schema.SQL.AttributeDeclarations.Count != statement.Values.Count) { throw new Exception("number of columns between \"create table\" and \"insert statement\' do not match"); } int i; for (i = 0; i < statement.Values.Count; i++) { statement.Values[i].CharLimit = schema.SQL.AttributeDeclarations[i].CharLimit; } // find out primary key from insert values AtomValue primaryKey = statement.Values[schema.SQL.AttributeDeclarations.FindIndex(x => x.AttributeName == schema.SQL.PrimaryKey)]; // insert into index trees List <SchemaRecord> indexSchemas = _catalogManager.GetIndicesSchemaRecord(statement.TableName); foreach (SchemaRecord indexSchema in indexSchemas) { // find indexed value from insert values AtomValue indexedValue = statement.Values[schema.SQL.AttributeDeclarations.FindIndex(x => x.AttributeName == indexSchema.SQL.AttributeName)]; // wrap up indexed value and primary key List <AtomValue> indexPrimaryKeyPair = new List <AtomValue>() { indexedValue, primaryKey }; // insert into index trees int newIndexRoot = _recordManager.InsertRecord(indexPrimaryKeyPair, indexedValue, indexSchema.RootPage); _catalogManager.TryUpdateSchemaRecord(indexSchema.Name, newIndexRoot); } // insert into table tree int newRoot = _recordManager.InsertRecord(statement.Values, primaryKey, schema.RootPage); _catalogManager.TryUpdateSchemaRecord(statement.TableName, newRoot); }
public static AtomValue operator !(AtomValue leftValue) { AtomValue result = new AtomValue(); result.Type = AttributeTypes.Int; switch (leftValue.Type) { case AttributeTypes.Char: throw new System.InvalidOperationException("String could not Not"); case AttributeTypes.Float: case AttributeTypes.Int: result.IntegerValue = leftValue.BooleanValue ? 0 : 1; break; case AttributeTypes.Null: throw new System.NullReferenceException(); } return(result); }
// get stored values in models (objects) public List <AtomValue> GetValues() { List <AtomValue> values = new List <AtomValue>(); int i; for (i = 0; i < this.HeaderList.Count; i++) { AtomValue value = new AtomValue(); uint headerValue = this.HeaderList[i]; if (headerValue == (int)HeaderValue.INTEGER) { value.Type = AttributeTypes.Int; value.IntegerValue = BitConverter.ToInt32(this.FieldData, this.FieldOffsets[i]); } else if (headerValue == (int)HeaderValue.FloatingPoint) { value.Type = AttributeTypes.Float; value.FloatValue = BitConverter.ToDouble(this.FieldData, this.FieldOffsets[i]); } else if (headerValue == (int)HeaderValue.NULL) { value.Type = AttributeTypes.Null; } else if ((headerValue - (int)HeaderValue.TEXT) % 2 == 0) { value.Type = AttributeTypes.Char; int stringLength = (int)(headerValue - (uint)HeaderValue.TEXT) / 2; value.CharLimit = stringLength; value.StringValue = Encoding.UTF8.GetString(this.FieldData, this.FieldOffsets[i], stringLength).TrimEnd('\0'); } else { throw new Exception($"Header value {headerValue} does not exists"); } values.Add(value); } return(values); }
private static DBRecord GetTestRecord_expression(int value_1, string value_2, float value_3) { List <AtomValue> values = new List <AtomValue>(); AtomValue value1 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = value_1 }; AtomValue value2 = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 5, StringValue = value_2 }; AtomValue value3 = new AtomValue() { Type = AttributeTypes.Float, FloatValue = value_3 }; values.Add(value1); values.Add(value2); values.Add(value3); DBRecord record = new DBRecord(values); return(record); }
public static AtomValue operator -(AtomValue leftValue) { AtomValue result = new AtomValue(); result.Type = leftValue.Type; switch (leftValue.Type) { case AttributeTypes.Char: throw new System.InvalidOperationException("String could not Subtract"); case AttributeTypes.Float: result.FloatValue = -leftValue.FloatValue; break; case AttributeTypes.Int: result.IntegerValue = -leftValue.IntegerValue; break; case AttributeTypes.Null: throw new System.NullReferenceException(); } return(result); }
public override object VisitAtom([NotNull] MiniSQLParser.AtomContext context) { Expression obj = new Expression(); // TODO: review if (context.scientific() != null) { AtomValue atomValue = (AtomValue)Visit(context.scientific()); obj.Operator = Operator.AtomConcreteValue; obj.ConcreteValue = atomValue; } else if (context.variable() != null) { string variableName = context.variable().GetText(); obj.Operator = Operator.AtomVariable; obj.AttributeName = variableName; } else { throw new System.NotImplementedException(); } return(obj); }
static DBRecord GetTestBRecord(double height, int pid, string name, string identity, int age) { // init record List <AtomValue> values = new List <AtomValue>(); AtomValue value1 = new AtomValue() { Type = AttributeTypes.Float, FloatValue = height }; AtomValue value2 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = pid }; AtomValue value3 = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 32, StringValue = name }; AtomValue value4 = new AtomValue() { Type = AttributeTypes.Char, CharLimit = 128, StringValue = identity }; AtomValue value5 = new AtomValue() { Type = AttributeTypes.Int, IntegerValue = age }; values.Add(value1); values.Add(value2); values.Add(value3); values.Add(value4); values.Add(value5); DBRecord record = new DBRecord(values); DBRecord cloneRecord = new DBRecord(record.Pack(), 0); BTreeNodeHelper.AssertDBRecords(record, cloneRecord); return(record); }
public AttributeValue(string attributeName, AtomValue value) { this.Value = value; this.AttributeName = attributeName; }
// `keyName` := primary key in table tree; indexed value in index tree public List <BTreeCell> FindCells(BTreeNode root, Expression condition, string keyName, List <AttributeDeclaration> attributeDeclarations) { if (condition == null) { return(LinearSearch(root, condition, attributeDeclarations)); } else if (condition.SimpleMinterms.ContainsKey(keyName)) { List <BTreeCell> result = new List <BTreeCell>(); List <AtomValue> values = new List <AtomValue>(); BTreeNode startNode; BTreeCell cell; int startIndexOfCellInStartNode; AtomValue bound = condition.SimpleMinterms[keyName].RightOperand.ConcreteValue; values.Add(bound); DBRecord keyFind = new DBRecord(values); switch (condition.SimpleMinterms[keyName].Operator) { case Operator.NotEqual: return(LinearSearch(root, condition, attributeDeclarations)); case Operator.Equal: LeafTableCell tmpCell = (LeafTableCell)FindCell(keyFind, root); if (tmpCell == null) { break; } else if (condition.Calculate(attributeDeclarations, tmpCell.DBRecord.GetValues()).BooleanValue == true) { result.Add(tmpCell); } break; case Operator.LessThan: startNode = FindMin(root); return(FindCells(startNode, condition, attributeDeclarations, bound, false)); case Operator.LessThanOrEqualTo: startNode = FindMin(root); return(FindCells(startNode, condition, attributeDeclarations, bound, true)); case Operator.MoreThan: startNode = FindNode(keyFind, root, true); // nothing is equal or more than the value of `keyFind` in the tree if (startNode == null) { return(result); } (cell, _, startIndexOfCellInStartNode) = startNode.FindBTreeCell(keyFind); // 2 possible situations for `cell == null`: // 1: The `keyFind` is bigger than all the key in `startNode` // 2: The `keyFind` is just between the bigest one in `startNode` and the smallest one in next node if (cell == null) { if (startNode.RightPage == 0) { return(result); } else { startIndexOfCellInStartNode = 0; MemoryPage nextpage = _pager.ReadPage((int)startNode.RightPage); startNode = new BTreeNode(nextpage); } } return(FindCells(startNode, startIndexOfCellInStartNode, condition, attributeDeclarations, false)); case Operator.MoreThanOrEqualTo: startNode = FindNode(keyFind, root, true); // nothing is equal or more than the value of `keyFind` in the tree if (startNode == null) { return(result); } (cell, _, startIndexOfCellInStartNode) = startNode.FindBTreeCell(keyFind); if (cell == null) { if (startNode.RightPage == 0) { return(result); } else { startIndexOfCellInStartNode = 0; MemoryPage nextpage = _pager.ReadPage((int)startNode.RightPage); startNode = new BTreeNode(nextpage); } } return(FindCells(startNode, startIndexOfCellInStartNode, condition, attributeDeclarations, true)); default: throw new Exception("The Operand is not supported!"); } //This step may not need? return(result); } else { return(LinearSearch(root, condition, attributeDeclarations)); } }