实现了一个关系型数据库。主要功能: Database Index, B+ Tree, Query Optimization, Locks
Table的实现:
数据库Table 一般要告诉他你能储存什么样的值,比如说Age int, Name String 之类的。
所以先定义一下Table Schema:
fields就是col names。 fieldTypes是与col对应的数据类型
比如说Age 对应Int。
数据在Database里是以Byte的形式存在的:
我们要把给的数据变成byte,存起来。所以实现了一个Encoding的函数。
在读取的时候,用户当然不希望读到Byte,所以还要给一个Decoding成原样的方法:
这个时候可以看出来Field_type的原因了,我们把数据变成Byte以后谁也不知道这里col里的东西是个啥。但是Field-Type记录了这里放的是比如说String,到时候我们就以String的方式来读取这个Byte。
Table:
首先要有一个Page的概念,因为数据是存放在一个Page 一个Page里的。 然后我们会用一个Head-Page 它知道哪个Page现在有空余位置。
添加Record:
首先看看要加的数据类型是对的。然后找第一张Free Page。
B+ Tree:
算是一个索引,方便查找东西。
两个部分: Node的实现和 Tree本身的实现
B+ tree class里主要实现了一个Iterator.
锁:【设计了很多多线程, 这个主要为了模拟并发情况】
为了管理锁的优先问题,我们做了一个锁管理员类,负责哪个线程/进程该拿到锁access 某个Table。
Lock Object,这里运用到了很多的多线程!!!!
Lock 知道自己的Owner是谁,以及有一个TransactionQueue
排队有人等lock。
如果当前Lock object里是空的话, owner设置为新的这个transNum, 类型设置为Transnum要的类型。
如果Lock里有人占了,是Exclusive的话, 那你就不能干啥。
如果Lock有人占了,但是只是shared lock的话。那你还可以去排队看看。如果当前Lock里占用的是Shared Lock, 你也要申请share,但是队列之前有一个exclusive在排队,你就不能。
while(!notifyLocks)
{
this.wait();
}
这里实现了两种锁,share和Exclusive。并且管理员有着一个Graph,可以判断现在有没有出现dead lock。
判断有没有dead lock的办法就是判断这个directed Graph有没有组成cycle:
首先建一个Graph:
当年真是菜的不行,我还记得这个cycle DFS detection还是我去Greeks网上copy paste的。
处理Potential Deadlock:
每当有进程要来要锁,我们都会确认一下这个Process拿到锁的话不会导致出现deadlock. 所以我们就是把这个Transaction加入Graph里,看看它和别的Transaction的edge 情况。如果发现导致cycle了,我们就抛出异常。【并且我们并没有加入这个Transaction进入Graph组成edge】这边有一个很Tricky的地方,对于Share Lock.因为share的lock可以被多个共享。我们要check每一种情况,比如说1 和 2如果有edge会不会有cycle。 1和3有edge 会不会有cycle。。。