浏览 1181 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2016-04-29
最后修改:2016-04-29
内存表是多行数据的存储,一般访问内存表时,都是通过遍历方式对内存表进行访问,然后逐行进行判断和处理。这种方式一般情况下都是遍历完整个内存表的数据后,才返回退出。 但是某些情况下,我们可能只需要找到某一列的值为特定的值时做相应的处理,这种情况下遍历太消耗性能。 因此我们可以事先为这个内存表指定某个列作为关键字建立索引。下次访问时,可以先根据关键字找到对应的行。然后进行处理。索引采用HashMap进行实现,会极大的提高性能。 根据实际的需要,我们将索引设计成三种类型:分为唯一索引、链表多索引、key-value多索引。这三种实现可以在一个内存表中同时存在,但是同一种实现,只能存在一种。 一种是单个关键字的唯一索引,唯一索引是有点项主键的意思,某列的值是唯一的。采用HashMap<Object,int>来存储索引,int为行号。使用这种类型的索引,主要有以下的方法: resetKeyMap 创建唯一索引,传入参数为关键字所在的列号 moveToKey 查找并定位根据唯一索引找到的行: 传入参数为需要匹配的值。 根据这个方法就能定位到关键字所在行,然后进行修改 以下的方法中,如果该字段设置了唯一关键字会调用: findFirstByKey 相当于map来使用,找第一列为传入值的,返回第二列的值。没有关键字初始化的话,则遍历 exitsKey 是否在指定的列,存在等于传入值的行。没有关键字唯一索引初始化的话,则遍历 getValueByKey 和findFirstByKey类似,只是第二个参数传入了指定的关键字所在列和返回值所在列 updateFirstByKey 将指定的关键字为第一传入值的行的指定列的值,变更为第二传入值,第三参数为指定了关键字所在列和返回值所在列。如果存在关键字唯一索引,则从索引中取,否则遍历。 第二种索引实现是单一关键字的多索引,可以将多列拼接成一个字符串,作为单一关键字。这种索引在建立索引时,需要使用initKeyListMap方法指定那几列是索引项,并且指定拼接字符。索引会将这些列的值转成字符串然后用拼接字符得到一个字符串后,作为key值放到HashMap<String,List>中。下次要使用时,必须将需要访问的值也采用拼接字符,拼接成一个新的字符串后,使用findKeyList方法进行调用。 initKeyListMap(int):传入值为索引所在的列号,根据该列创建多索引 initKeyListMap(string,string):传入值为关键字所在的列,以及拼接使用的连接符。关键字所在列可以多个,用,隔开,可以使列号或者列名 findKeyList(string),根据传入的值,找到关键字为传入值的,多个索引 nextKeyList():根据索引找到了多行之后,可以依次取得下一行 第三种索引实现了多关键字的多索引。这种方式的关键字,是采用HashMap<Object,HashMap>方式存储的,也就是索引下面再找索引 multiKeyReset(int):根据传入的列号,建立该号的索引 multiKeyReset(int,int):根据传入的列号,建立两个列的索引 multiKeyReset(int,int,int):根据传入的列号,建立三个列的索引 dynamicKeyReset2(int[]):根据传入的列,建立多个列的索引 multiKeyFind(Object):根据设置的一个列的索引,查找满足的行,与multiKeyReset(int)相对应 multiKeyFind(Object,Object):根据设置的两个列的索引,查找满足的行,与multiKeyReset(int,int)相对应 multiKeyFind(Object,Object,Object):根据设置的三个列的索引,查找满足的行,与multiKeyReset(int,int,int)相对应 dynamicKeyFind2(Object[]):根据设置的多个列的索引,查找满足的行,与dynamicKeyReset2(int[])相对应 nextKeyList(): 根据索引找到了多行之后,可以依次取得下一行。 注意,当某个内存表采用共享内存方式存储时,如果子线程需要采用复制方式或者引用方式来访问这个共享内存时。子线程的内存表都是采用引用的方式来或者原先共享内存中的索引。 2.2. 内存表的主线程与子线程间共享 当主线程创建好一个内存表后,可以将其传给子线程进行访问。缺省情况下,为了线程安全,都是会复制一份新的内存表,传给子线程。但是如果希望节约内存开支,采用引用的方式来访问,就需要做一些特定的操作。 Sheet.setThreadType(int)可以指定当前内存表传给子线程时的共享方式。 其中getThreadType() == 1时,是直接传入引用,此时特别需要注意线程共享问题。不能对内存表进行逐行的读写操作。只能做批量添加等操作。除了以下设置成线程安全的方法可供访问,其他的方法都会存在线程安全问题: initFromSheet:将{arg1}中的数据根据设定的列对应关系全部导入到表格中 appendFromSheet:将{arg1}中的数据根据设定的列对应关系,追加导入到表格中 loadFromSheet:将{arg1}中数据全部导入表格 loadFromList:将导出列表{arg1}的数据重新导入到表格中 loadFromExcelFile:从Excel中导入数据到内存表 appendFromResult:将查询结果({arg1})中的数据根据设定的列对应关系追加导入到表格中 loadFromResult:将查询结果({arg1})中的数据根据设定的列对应关系全部导入到表格中 loadFromResult:将查询结果({arg1})中的数据根据设定的列对应关系全部导入到表格中 loadFromView:将查询结果({arg1})中的数据全部导入表格 getThreadType() == 2:采用共享数据的方式访问。此时会有一个新的内存表,但是指向同一个数组。此时当进行读取时,是线程安全的。但是当需要写入数据时,是线程不安全的。 因此,getThreadType() == 2用于如果需要逐条读取的,只读不写; 否则使用getThreadType() == 1,只能通过批量导入写入数据。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |