├── .gitignore
├── LICENSE
├── README.md
├── code
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── garychenc
│ │ │ └── filemap
│ │ │ ├── AbstractFileMap.java
│ │ │ ├── FileMap.java
│ │ │ ├── RepeatableKeyFileMap.java
│ │ │ ├── UniqueKeyFileMap.java
│ │ │ ├── store
│ │ │ ├── Store.java
│ │ │ ├── StoreEntry.java
│ │ │ ├── StoreException.java
│ │ │ ├── StoreIsFullException.java
│ │ │ ├── StoreReader.java
│ │ │ ├── StoreReaderException.java
│ │ │ ├── StoreWriter.java
│ │ │ ├── StoreWriterException.java
│ │ │ ├── VersionConflictedException.java
│ │ │ └── filestore
│ │ │ │ ├── AddExceededMaxBucketsNumberException.java
│ │ │ │ ├── BinaryFileStore.java
│ │ │ │ ├── BinaryFileStoreConvertor.java
│ │ │ │ ├── BinaryFileStoreKey.java
│ │ │ │ ├── BinaryFileStoreValue.java
│ │ │ │ ├── ContentStoreBlock.java
│ │ │ │ ├── ContentStoreBlockException.java
│ │ │ │ ├── ContentStoreBlockLengthExceedException.java
│ │ │ │ ├── ContentStoreMaster.java
│ │ │ │ ├── ContentStoreMasterException.java
│ │ │ │ ├── ContentStoreSlave.java
│ │ │ │ ├── ContentStoreSlaveException.java
│ │ │ │ ├── ContentStoreSlaveIndex.java
│ │ │ │ ├── ContentStoreSlaveStoreFile.java
│ │ │ │ ├── ErrorEntryRemovedListener.java
│ │ │ │ ├── ExceededMaxAllowedContentStoreSlavesNumber.java
│ │ │ │ ├── FileBaseBinaryFileStoreConvertorImpl.java
│ │ │ │ ├── FileBaseBinaryFileStoreKeyImpl.java
│ │ │ │ ├── FileBaseBinaryFileStoreValueImpl.java
│ │ │ │ ├── FileBaseContentStoreBlockImpl.java
│ │ │ │ ├── FileBaseContentStoreMaster.java
│ │ │ │ ├── FileBaseContentStoreSlave.java
│ │ │ │ ├── IndexBucket.java
│ │ │ │ ├── IndexGrid.java
│ │ │ │ ├── LongStoreKey.java
│ │ │ │ ├── MallocContentStoreSpaceException.java
│ │ │ │ ├── ManagedStoreFileMetaData.java
│ │ │ │ ├── SearchReachedMaxBucketsNumberException.java
│ │ │ │ ├── StoreKey.java
│ │ │ │ ├── StoreValue.java
│ │ │ │ └── StringStoreKey.java
│ │ │ └── util
│ │ │ ├── Asserts.java
│ │ │ ├── ByteArrayObjectInput.java
│ │ │ ├── ByteArrayObjectOutput.java
│ │ │ ├── DeleteDirectoryContentsFailedException.java
│ │ │ ├── HexDumper.java
│ │ │ ├── IOHelper.java
│ │ │ ├── ObjectCache.java
│ │ │ ├── ObjectCacheFactory.java
│ │ │ ├── SerializationUtils.java
│ │ │ ├── SimpleObjectCacheFactoryImpl.java
│ │ │ ├── SimpleObjectCacheImpl.java
│ │ │ └── Utils.java
│ └── resources
│ │ └── for-location.txt
│ └── test
│ ├── java
│ └── com
│ │ └── github
│ │ └── garychenc
│ │ └── filemap
│ │ └── impl
│ │ └── test
│ │ ├── RepeatableKeyFileMapTest.java
│ │ └── UniqueKeyFileMapTest.java
│ └── resources
│ └── for-location.txt
└── doc
└── img
├── Overview-1.png
├── Overview-2.png
└── Sys-Arch.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 简介
2 |
3 | ## FileMap 是一个用 Java 编写的,基于文件的高性能本地 Key - Value 存储库,可以理解为一个将数据存储在文件上的 Map,因此,其可存储巨大的数据量,而且具有持久化的效果。
4 |
5 | FileMap 使用非常简单,创建一个 com.github.garychenc.filemap.RepeatableKeyFileMap 对象或 com.github.garychenc.filemap.UniqueKeyFileMap 对象即可开始使用。创建对象的时候指定数据存储的本地目录即可。
6 |
7 | UniqueKeyFileMap 类确保添加新 Key - Value 的时候,新的 Key 与目前 Map 中所有的 Key 都不重复才能添加成功。
8 |
9 | RepeatableKeyFileMap 类允许添加新 Key - Value 的时候,新的 Key 可与原来 Map 中已经存在的 Key 重复。假如需要 Key 的唯一性,由客户端自己保证。
10 |
11 | UniqueKeyFileMap 类由于每次 add 操作都需要搜索 FileMap,确保即将添加的 key 不存在,所以性能会比 RepeatableKeyFileMap 差一些。而 RepeatableKeyFileMap则每次直接将记录添加到 FileMap 中,不进行判断,性能比 UniqueKeyFileMap 好一些,假如应用能够确保产生的 key 的唯一性,并且即使 key 重复也不造成大的影响,则使用 RepeatableKeyFileMap 性能好一些。
12 |
13 | UniqueKeyFileMap 和 RepeatableKeyFileMap 类都是线程安全的。
14 |
15 | FileMap 采用乐观离线锁对记录进行并发更新管理,所以,每次更新或者移除记录的时候需要提供预期的版本号,假如版本号不正确,说明在此之前记录已经被修改了,更新或移除此记录会抛出 VersionConflictedException,需要重新读出记录,拿到最新的版本号之后再进行更新或移除操作。一般操作模式为 :
16 |
17 | ```
18 |
19 | do {
20 | try {
21 | StoreEntry testValue = fileMap.read("TEST-KEY-1");
22 | fileMap.update((String) testValue.getKey(), "TEST-VALUE-111100-1", testValue.getVersionNumber());
23 | break;
24 | } catch (VersionConflictedException e) {
25 | continue;
26 | } catch (StoreReaderException | StoreWriterException e) {
27 | e.printStackTrace();
28 | break;
29 | }
30 | } while (true);
31 |
32 | ```
33 |
34 | FileMap 使用完毕之后,必须调用其 close() 方法关闭 FileMap,否则可能造成资源泄露。
35 |
36 | FileMap 基本使用方法示例 :
37 |
38 | ```
39 |
40 | try (FileMap fileMap = new UniqueKeyFileMap(storeDir.getAbsolutePath(), "Test-1")) {
41 |
42 | fileMap.add("TEST-KEY-1", "TEST-VALUE-1");
43 | fileMap.add("TEST-KEY-2", "TEST-VALUE-2");
44 |
45 | System.out.println(fileMap.size()); // Size = 2
46 |
47 | StoreEntry testValue1 = fileMap.read("TEST-KEY-1");
48 | StoreEntry testValue2 = fileMap.read("TEST-KEY-2");
49 |
50 | System.out.println(testValue1.getValue()); // Value = "TEST-VALUE-1"
51 | System.out.println(testValue1.getVersionNumber()); // Version = 0
52 |
53 | System.out.println(testValue2.getValue()); // Value = "TEST-VALUE-2"
54 | System.out.println(testValue2.getVersionNumber()); // Version = 0
55 |
56 | fileMap.update("TEST-KEY-2", "TEST-VALUE-2-001", testValue2.getVersionNumber());
57 |
58 | testValue2 = fileMap.read("TEST-KEY-2");
59 | System.out.println(testValue2.getValue()); // Value = "TEST-VALUE-2-001"
60 | System.out.println(testValue2.getVersionNumber()); // Version = 1
61 |
62 | fileMap.remove("TEST-KEY-1", testValue1.getVersionNumber());
63 | fileMap.remove("TEST-KEY-2", testValue2.getVersionNumber());
64 | }
65 |
66 | ```
67 |
68 | # 快速入门
69 |
70 | 接下来将会介绍如何将 FileMap 快速使用起来。首先,读者需要先安装 JDK 和 Maven,并且具有一定的 Java 开发知识,具有一个可用的 Java 开发 IDE。
71 |
72 | + 用 GIT clone 该项目的源代码,代码路径:https://github.com/garychenc/file-map.git 。
73 |
74 | + 使用 eclipse 或 idea 等 Java 开发 IDE 将代码以 Maven 项目的形式导入到 IDE 中。代码在 clone 路径的 code 目录中。
75 |
76 | + 在 IDE 中直接运行 test 源码目录的 com.github.garychenc.filemap.impl.test 包中的测试案例,无须做任何配置。
77 |
78 | + RepeatableKeyFileMapTest 测试案例对 RepeatableKeyFileMap 类进行测试。UniqueKeyFileMapTest 测试案例对 UniqueKeyFileMap 类进行测试。
79 |
80 | + testNormalUseCase 测试基本使用 case,testMultiThreadNormalUseCase1,testMultiThreadNormalUseCase2 进行并发使用测试,并且也可作为性能测试案例使用。
81 |
82 | + 通过对 com.github.garychenc.filemap.impl.test 包中的测试案例进行学习,即可掌握 FileMap 的使用方法。由于是作为类库使用,无须任何配置。
83 |
84 | + 使用 IDE 中 Maven 的 install 功能即可将 FileMap 打包为一个 jar 包,在其它项目中使用。
85 |
86 | # 联系方式
87 |
88 | Gary CHEN : email : gary.chen.c@qq.com
89 |
90 | # 系统架构简介
91 |
92 | **系统整体设计思想 :**
93 |
94 | 
95 |
96 | **系统设计思想详细描述 :**
97 |
98 | 
99 |
100 | **系统详细架构设计描述 :**
101 |
102 | 
103 |
104 | + FileMap 接口是系统的入口,其实现类有 RepeatableKeyFileMap 和 UniqueKeyFileMap,两个类大同小异,FileMap 实现包含一个 BinaryFileStore 列表,每个 BinaryFileStore 对象代表一个文件存储集合。
105 |
106 | + BinaryFileStore 实现了上述描述的基于内存的 Map 类型索引,索引的每个 IndexBucket 指向一个 FileBaseContentStoreSlave 对象,该对象管理该 IndexBucket 指向的文件存储位置和该位置存储的数据。 FileBaseContentStoreSlave 对象管理着在哪个 Slave Data Store File 的哪个位置存储着真实的数据,并且提供数据的读取、写入方法。一个 Slave Data Store File 可对应多个 FileBaseContentStoreSlave 对象,整个 FileMap 包含多个 Slave Data Store File,数据分布在这些 Slave Data Store File 上,每个文件最大存储 64M 的数据。
107 |
108 | + FileBaseContentStoreMaster 对所有 FileBaseContentStoreSlave 和 Slave Data Store File 进行管理,每次 BinaryFileStore 需要存储一个新数据的时候,首先需要向 FileBaseContentStoreMaster 申请一个 FileBaseContentStoreSlave,申请的时候 FileBaseContentStoreMaster 就会在一个空闲的 Slave Data Store File 中为新申请的 FileBaseContentStoreSlave 分配存储空间,并且返回文件存储位置给 Slave,接着将 Slave 纳入 FileBaseContentStoreMaster 进行管理。然后,BinaryFileStore 通过新申请的 FileBaseContentStoreSlave 将数据存储到刚刚分配的文件存储空间中。假如,没有文件可以分配需要的空间,则新建一个文件,在该文件上分配所需空间,并且将该文件纳入管理列表,对文件进行管理。由于 BinaryFileStore 的 IndexBucket 索引只存储 FileBaseContentStoreSlave 的编号,所以每次读取数据的时候,首先需要通过 FileBaseContentStoreMaster 根据 Slave 编号获取 FileBaseContentStoreSlave 对象,然后通过 FileBaseContentStoreSlave 读取其管理的文件位置的数据。
109 |
110 | + FileBaseContentStoreMaster 具有无用文件存储块和无用文件垃圾回收功能,当某个 FileBaseContentStoreSlave 被标记为删除之后,该 Slave 和其管理的文件存储块将加入已删除 Slave 列表,该列表按照可存储空间从大到小排序,每次申请新的 Slave 的时候会优先从该列表中拿出存储空间刚好合适的 Slave 重新使用。当某个文件包含的所有 FileBaseContentStoreSlave 都被删除之后,该文件和其包含的 FileBaseContentStoreSlave 都会被从系统中删除,以节省内存和磁盘存储空间。但是文件编号保留,下次需要创建新文件的时候,优先使用该文件编号生产新文件的文件名。
111 |
112 | + 对数据进行更新的时候,首先按照数据读取方法的步骤搜索到需要的 FileBaseContentStoreSlave ,看看该 FileBaseContentStoreSlave 的存储空间是否能够容纳下更新后的数据,假如可以,则直接将新的数据写入到该 FileBaseContentStoreSlave 所指向的文件存储块中,假如不能容纳,则向 FileBaseContentStoreMaster 申请新的 FileBaseContentStoreSlave ,然后将数据写入到该新申请的 Slave 中,并且更新内存索引和索引文件中对应的数据。
113 |
114 | + 在数据插入到 FileMap 中的时候,从 FileBaseContentStoreMaster 中申请 FileBaseContentStoreSlave 时就会按照需存储数据实际大小的 2 倍申请存储空间,以使后续更新数据的时候可以在原空间上写入新的数据,除非新数据大小超过了原来数据大小的两倍才需要申请新的 FileBaseContentStoreSlave ,这样就避免了更新数据时,需频繁申请新的 FileBaseContentStoreSlave 。
115 |
116 | + BinaryFileStore 中的内存索引会按照一定的数据结构存储在索引存储文件中,索引存储文件的文件名后缀为 : meta.db.map,FileBaseContentStoreMaster 管理的 Slave 和 Slave Data Store File 也会按照一定的数据结构存储在 Slave 管理文件和 Slave Data Store File 管理文件中,管理文件的后缀名分别为 : slaves.management 和 store-files.management。 FileMap 第一次创建的时候会根据可存储数据量参数的大小生成索引存储文件、Slave 管理文件和 Slave Data Store File 管理文件,所以,第一次创建的时候速度会有点慢,可存储数据量参数设置越大,创建越慢,默认可存储数据量参数的大小为 50 万,创建时间为几秒。从第二次开始,创建 FileMap 只是加载索引存储文件、Slave 管理文件和 Slave Data Store File 管理文件,速度会快很多。可存储数据量为 50 万的这些文件总的加载时间为 200 毫秒左右。 FileMap 加载索引存储文件、Slave 管理文件和 Slave Data Store File 管理文件之后,将创建文件中存储的内存索引和 Slave、Slave Data Store File等数据结构。
117 |
118 | + Slave Data Store File 文件名的后缀为 slave.data,文件名最后的号码为文件编号,每个文件最大存储 64M 的数据。当文件大于等于 64M,新申请 FileBaseContentStoreSlave 时,将会新创建 Slave Data Store File, 用于存储新 Slave 的数据,新创建的文件编号将在原来最后一个文件编号的基础上加一。
119 |
--------------------------------------------------------------------------------
/code/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.github.garychenc.filemap
7 | file-map
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | file-map
12 | http://maven.apache.org
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 | 1.6.1
19 | 1.1.7
20 | 4.10
21 |
22 |
23 |
24 |
25 | org.slf4j
26 | slf4j-api
27 | ${version.slf4j}
28 | jar
29 |
30 |
31 |
32 | ch.qos.logback
33 | logback-core
34 | ${version.logback}
35 |
36 |
37 |
38 | ch.qos.logback
39 | logback-classic
40 | ${version.logback}
41 |
42 |
43 |
44 | junit
45 | junit
46 | ${version.junit}
47 | test
48 |
49 |
50 |
51 |
52 |
53 |
54 | org.apache.maven.plugins
55 | maven-compiler-plugin
56 | 3.5.1
57 |
58 | 1.8
59 | 1.8
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/RepeatableKeyFileMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap;
18 |
19 | import com.github.garychenc.filemap.store.StoreIsFullException;
20 | import com.github.garychenc.filemap.store.StoreReaderException;
21 | import com.github.garychenc.filemap.store.StoreWriterException;
22 | import com.github.garychenc.filemap.store.filestore.BinaryFileStore;
23 |
24 | import java.io.Externalizable;
25 | import java.io.Serializable;
26 |
27 | /**
28 | * RepeatableKeyFileMap 类为 FileMap 的一个实现,该类的 add 方法允许添加新 Key - Value 的时候,新的 Key 可与原来 Map 中已经存在的 Key 重复。假如需要 Key 的唯一性,由客户端自己保证。
29 | *
30 | * @author Gary CHEN
31 | *
32 | */
33 | public class RepeatableKeyFileMap extends AbstractFileMap {
34 |
35 | /**
36 | * 创建一个 RepeatableKeyFileMap 对象。创建 RepeatableKeyFileMap 对象失败时抛出运行时异常。
37 | *
38 | * @param storeDirPath FileMap 数据存储在文件上时的存储目录。
39 | * @param storeName FileMap 的存储名,存储名用于在同个存储目录中有多个 FileMap 存储时,区分不同的 FileMap 。
40 | * 假如存储目录相同,则每个 FileMap 实例的存储名都必须不一样。两个不同的 FileMap 实例绝对不能使用相同的存储目录和存储名。
41 | * 否则存储的数据可能会互相干扰,出现不可预知的错误。
42 | */
43 | public RepeatableKeyFileMap(String storeDirPath, String storeName) {
44 | super(storeDirPath, storeName);
45 | }
46 |
47 | /**
48 | * 创建一个 RepeatableKeyFileMap 对象。创建 RepeatableKeyFileMap 对象失败时抛出运行时异常。
49 | *
50 | * @param storeDirPath FileMap 数据存储在文件上时的存储目录。
51 | * @param storeName FileMap 的存储名,存储名用于在同个存储目录中有多个 FileMap 存储时,区分不同的 FileMap 。
52 | * 假如存储目录相同,则每个 FileMap 实例的存储名都必须不一样。两个不同的 FileMap 实例绝对不能使用相同的存储目录和存储名。
53 | * 否则存储的数据可能会互相干扰,出现不可预知的错误。
54 | * @param isFlushFileCacheEveryOperation FileMap 写数据的时候默认先写在操作系统的文件缓存中,然后再刷新文件缓存的数据到磁盘上,该参数
55 | * 控制是否每次对 FileMap 进行 add,update,remove 操作之后都刷新文件缓存的数据到磁盘上。
56 | * true 为每次都刷新,false 则等待 FileMap close 的时候再刷新。
57 | */
58 | public RepeatableKeyFileMap(String storeDirPath, String storeName, boolean isFlushFileCacheEveryOperation) {
59 | super(storeDirPath, storeName, isFlushFileCacheEveryOperation);
60 | }
61 |
62 | /**
63 | * 创建一个 RepeatableKeyFileMap 对象。创建 RepeatableKeyFileMap 对象失败时抛出运行时异常。
64 | *
65 | * @param storeDirPath FileMap 数据存储在文件上时的存储目录。
66 | * @param storeName FileMap 的存储名,存储名用于在同个存储目录中有多个 FileMap 存储时,区分不同的 FileMap 。
67 | * 假如存储目录相同,则每个 FileMap 实例的存储名都必须不一样。两个不同的 FileMap 实例绝对不能使用相同的存储目录和存储名。
68 | * 否则存储的数据可能会互相干扰,出现不可预知的错误。
69 | * @param isFlushFileCacheEveryOperation FileMap 写数据的时候默认先写在操作系统的文件缓存中,然后再刷新文件缓存的数据到磁盘上,该参数
70 | * 控制是否每次对 FileMap 进行 add,update,remove 操作之后都刷新文件缓存的数据到磁盘上。
71 | * true 为每次都刷新,false 则等待 FileMap close 的时候再刷新。
72 | * @param isStrictStorage 由于上述写数据的特性,所以,当 FileMap 被不正常关闭的时候,有可能出现某些数据丢失、损坏,而出现无法再次读取的情况。
73 | * 该参数控制当出现数据无法读取的时候,是抛出异常,还是忽略该数据,返回 null,并且将该数据从 FileMap 中移除。
74 | * ture 抛出异常,false 忽略该数据。
75 | */
76 | public RepeatableKeyFileMap(String storeDirPath, String storeName, boolean isFlushFileCacheEveryOperation, boolean isStrictStorage) {
77 | super(storeDirPath, storeName, isFlushFileCacheEveryOperation, isStrictStorage);
78 | }
79 |
80 | /**
81 | * 创建一个 RepeatableKeyFileMap 对象。创建 RepeatableKeyFileMap 对象失败时抛出运行时异常。
82 | *
83 | * @param storeDirPath FileMap 数据存储在文件上时的存储目录。
84 | * @param storeName FileMap 的存储名,存储名用于在同个存储目录中有多个 FileMap 存储时,区分不同的 FileMap 。
85 | * 假如存储目录相同,则每个 FileMap 实例的存储名都必须不一样。两个不同的 FileMap 实例绝对不能使用相同的存储目录和存储名。
86 | * 否则存储的数据可能会互相干扰,出现不可预知的错误。
87 | * @param isFlushFileCacheEveryOperation FileMap 写数据的时候默认先写在操作系统的文件缓存中,然后再刷新文件缓存的数据到磁盘上,该参数
88 | * 控制是否每次对 FileMap 进行 add,update,remove 操作之后都刷新文件缓存的数据到磁盘上。
89 | * true 为每次都刷新,false 则等待 FileMap close 的时候再刷新。
90 | * @param isStrictStorage 由于上述写数据的特性,所以,当 FileMap 被不正常关闭的时候,有可能出现某些数据丢失、损坏,而出现无法再次读取的情况。
91 | * 该参数控制当出现数据无法读取的时候,是抛出异常,还是忽略该数据,返回 null,并且将该数据从 FileMap 中移除。
92 | * ture 抛出异常,false 忽略该数据。
93 | * @param aFileMapStoreMaxSize FileMap 内部采用多个文件存储数据,该参数控制当一个文件存储的记录条数到达多少时创建新的文件存储新的数据。
94 | */
95 | public RepeatableKeyFileMap(String storeDirPath, String storeName, boolean isFlushFileCacheEveryOperation, boolean isStrictStorage, int aFileMapStoreMaxSize) {
96 | super(storeDirPath, storeName, isFlushFileCacheEveryOperation, isStrictStorage, aFileMapStoreMaxSize);
97 | }
98 |
99 | @Override
100 | public boolean add(String key, byte[] value) throws StoreWriterException {
101 | while (true) {
102 | BinaryFileStore spaceAvailableMapStore = null;
103 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
104 | try {
105 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
106 | spaceAvailableMapStore = fileMapStore;
107 | break;
108 | }
109 | } catch (StoreReaderException ex) {
110 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
111 | }
112 | }
113 |
114 | if (spaceAvailableMapStore != null) {
115 | try {
116 | spaceAvailableMapStore.add(key, value);
117 | return true;
118 | } catch (StoreIsFullException e) {
119 | // continue;
120 | }
121 | } else {
122 | spaceAvailableMapStore = extendNewFileMapStore();
123 |
124 | try {
125 | spaceAvailableMapStore.add(key, value);
126 | return true;
127 | } catch (StoreIsFullException e) {
128 | // continue;
129 | }
130 | }
131 | }
132 | }
133 |
134 | @Override
135 | public boolean add(long key, byte[] value) throws StoreWriterException {
136 | while (true) {
137 | BinaryFileStore spaceAvailableMapStore = null;
138 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
139 | try {
140 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
141 | spaceAvailableMapStore = fileMapStore;
142 | break;
143 | }
144 | } catch (StoreReaderException ex) {
145 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
146 | }
147 | }
148 |
149 | if (spaceAvailableMapStore != null) {
150 | try {
151 | spaceAvailableMapStore.add(key, value);
152 | return true;
153 | } catch (StoreIsFullException e) {
154 | // continue;
155 | }
156 | } else {
157 | spaceAvailableMapStore = extendNewFileMapStore();
158 |
159 | try {
160 | spaceAvailableMapStore.add(key, value);
161 | return true;
162 | } catch (StoreIsFullException e) {
163 | // continue;
164 | }
165 | }
166 | }
167 | }
168 |
169 | @Override
170 | public boolean add(String key, String value) throws StoreWriterException {
171 | while (true) {
172 | BinaryFileStore spaceAvailableMapStore = null;
173 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
174 | try {
175 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
176 | spaceAvailableMapStore = fileMapStore;
177 | break;
178 | }
179 | } catch (StoreReaderException ex) {
180 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
181 | }
182 | }
183 |
184 | if (spaceAvailableMapStore != null) {
185 | try {
186 | spaceAvailableMapStore.add(key, value);
187 | return true;
188 | } catch (StoreIsFullException e) {
189 | // continue;
190 | }
191 | } else {
192 | spaceAvailableMapStore = extendNewFileMapStore();
193 |
194 | try {
195 | spaceAvailableMapStore.add(key, value);
196 | return true;
197 | } catch (StoreIsFullException e) {
198 | // continue;
199 | }
200 | }
201 | }
202 | }
203 |
204 | @Override
205 | public boolean add(long key, String value) throws StoreWriterException {
206 | while (true) {
207 | BinaryFileStore spaceAvailableMapStore = null;
208 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
209 | try {
210 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
211 | spaceAvailableMapStore = fileMapStore;
212 | break;
213 | }
214 | } catch (StoreReaderException ex) {
215 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
216 | }
217 | }
218 |
219 | if (spaceAvailableMapStore != null) {
220 | try {
221 | spaceAvailableMapStore.add(key, value);
222 | return true;
223 | } catch (StoreIsFullException e) {
224 | // continue;
225 | }
226 | } else {
227 | spaceAvailableMapStore = extendNewFileMapStore();
228 |
229 | try {
230 | spaceAvailableMapStore.add(key, value);
231 | return true;
232 | } catch (StoreIsFullException e) {
233 | // continue;
234 | }
235 | }
236 | }
237 | }
238 |
239 | @Override
240 | public boolean add(String key, Externalizable value) throws StoreWriterException {
241 | while (true) {
242 | BinaryFileStore spaceAvailableMapStore = null;
243 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
244 | try {
245 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
246 | spaceAvailableMapStore = fileMapStore;
247 | break;
248 | }
249 | } catch (StoreReaderException ex) {
250 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
251 | }
252 | }
253 |
254 | if (spaceAvailableMapStore != null) {
255 | try {
256 | spaceAvailableMapStore.add(key, value);
257 | return true;
258 | } catch (StoreIsFullException e) {
259 | // continue;
260 | }
261 | } else {
262 | spaceAvailableMapStore = extendNewFileMapStore();
263 |
264 | try {
265 | spaceAvailableMapStore.add(key, value);
266 | return true;
267 | } catch (StoreIsFullException e) {
268 | // continue;
269 | }
270 | }
271 | }
272 | }
273 |
274 | @Override
275 | public boolean add(long key, Externalizable value) throws StoreWriterException {
276 | while (true) {
277 | BinaryFileStore spaceAvailableMapStore = null;
278 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
279 | try {
280 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
281 | spaceAvailableMapStore = fileMapStore;
282 | break;
283 | }
284 | } catch (StoreReaderException ex) {
285 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
286 | }
287 | }
288 |
289 | if (spaceAvailableMapStore != null) {
290 | try {
291 | spaceAvailableMapStore.add(key, value);
292 | return true;
293 | } catch (StoreIsFullException e) {
294 | // continue;
295 | }
296 | } else {
297 | spaceAvailableMapStore = extendNewFileMapStore();
298 |
299 | try {
300 | spaceAvailableMapStore.add(key, value);
301 | return true;
302 | } catch (StoreIsFullException e) {
303 | // continue;
304 | }
305 | }
306 | }
307 | }
308 |
309 | @Override
310 | public boolean add(String key, Serializable value) throws StoreWriterException {
311 | while (true) {
312 | BinaryFileStore spaceAvailableMapStore = null;
313 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
314 | try {
315 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
316 | spaceAvailableMapStore = fileMapStore;
317 | break;
318 | }
319 | } catch (StoreReaderException ex) {
320 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
321 | }
322 | }
323 |
324 | if (spaceAvailableMapStore != null) {
325 | try {
326 | spaceAvailableMapStore.add(key, value);
327 | return true;
328 | } catch (StoreIsFullException e) {
329 | // continue;
330 | }
331 | } else {
332 | spaceAvailableMapStore = extendNewFileMapStore();
333 |
334 | try {
335 | spaceAvailableMapStore.add(key, value);
336 | return true;
337 | } catch (StoreIsFullException e) {
338 | // continue;
339 | }
340 | }
341 | }
342 | }
343 |
344 | @Override
345 | public boolean add(long key, Serializable value) throws StoreWriterException {
346 | while (true) {
347 | BinaryFileStore spaceAvailableMapStore = null;
348 | for (BinaryFileStore fileMapStore : this.fileMapStores) {
349 | try {
350 | if (spaceAvailableMapStore == null && fileMapStore.size() < aFileMapStoreMaxSize) {
351 | spaceAvailableMapStore = fileMapStore;
352 | break;
353 | }
354 | } catch (StoreReaderException ex) {
355 | throw new StoreWriterException("Check is key exist failed. Key : " + key, ex);
356 | }
357 | }
358 |
359 | if (spaceAvailableMapStore != null) {
360 | try {
361 | spaceAvailableMapStore.add(key, value);
362 | return true;
363 | } catch (StoreIsFullException e) {
364 | // continue;
365 | }
366 | } else {
367 | spaceAvailableMapStore = extendNewFileMapStore();
368 |
369 | try {
370 | spaceAvailableMapStore.add(key, value);
371 | return true;
372 | } catch (StoreIsFullException e) {
373 | // continue;
374 | }
375 | }
376 | }
377 | }
378 | }
379 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/store/Store.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap.store;
18 |
19 | /**
20 | *
21 | * @author Gary CHEN
22 | *
23 | */
24 | public interface Store {
25 |
26 | public void close() throws StoreException;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/store/StoreEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap.store;
18 |
19 | /**
20 | * 封装了值、版本号和 key 的搜索结果对象,versionNumber 版本号,value 存储的值,key 用于读取值的关键字。
21 | *
22 | * @author Gary CHEN
23 | *
24 | */
25 | public class StoreEntry {
26 |
27 | private final long versionNumber;
28 | private final Object value;
29 | private final Object key;
30 |
31 | public StoreEntry(long versionNumber, Object value, Object key) {
32 | this.versionNumber = versionNumber;
33 | this.value = value;
34 | this.key = key;
35 | }
36 |
37 | public long getVersionNumber() {
38 | return versionNumber;
39 | }
40 |
41 | public Object getValue() {
42 | return value;
43 | }
44 |
45 | public Object getKey() {
46 | return key;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "StoreEntry [versionNumber=" + versionNumber + ", value=" + value + ", key=" + key + "]";
52 | }
53 |
54 | @Override
55 | public int hashCode() {
56 | final int prime = 31;
57 | int result = 1;
58 | result = prime * result + ((value == null) ? 0 : value.hashCode());
59 | result = prime * result + (int) (versionNumber ^ (versionNumber >>> 32));
60 | return result;
61 | }
62 |
63 | @Override
64 | public boolean equals(Object obj) {
65 | if (this == obj) {
66 | return true;
67 | }
68 | if (obj == null) {
69 | return false;
70 | }
71 | if (!(obj instanceof StoreEntry)) {
72 | return false;
73 | }
74 | StoreEntry other = (StoreEntry) obj;
75 | if (value == null) {
76 | if (other.value != null) {
77 | return false;
78 | }
79 | } else if (!value.equals(other.value)) {
80 | return false;
81 | }
82 | if (versionNumber != other.versionNumber) {
83 | return false;
84 | }
85 | return true;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/store/StoreException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap.store;
18 |
19 | /**
20 | *
21 | * @author Gary CHEN
22 | *
23 | */
24 | public class StoreException extends Exception {
25 |
26 | /**
27 | *
28 | */
29 | private static final long serialVersionUID = -4324407847255959555L;
30 |
31 | /**
32 | *
33 | */
34 | public StoreException() {
35 | }
36 |
37 | /**
38 | * @param message
39 | */
40 | public StoreException(String message) {
41 | super(message);
42 | }
43 |
44 | /**
45 | * @param cause
46 | */
47 | public StoreException(Throwable cause) {
48 | super(cause);
49 | }
50 |
51 | /**
52 | * @param message
53 | * @param cause
54 | */
55 | public StoreException(String message, Throwable cause) {
56 | super(message, cause);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/store/StoreIsFullException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap.store;
18 |
19 | /**
20 | *
21 | * @author Gary CHEN
22 | *
23 | */
24 | public class StoreIsFullException extends Exception {
25 |
26 | public StoreIsFullException() {
27 | }
28 |
29 | public StoreIsFullException(String message) {
30 | super(message);
31 | }
32 |
33 | public StoreIsFullException(String message, Throwable cause) {
34 | super(message, cause);
35 | }
36 |
37 | public StoreIsFullException(Throwable cause) {
38 | super(cause);
39 | }
40 |
41 | public StoreIsFullException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
42 | super(message, cause, enableSuppression, writableStackTrace);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/code/src/main/java/com/github/garychenc/filemap/store/StoreReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package com.github.garychenc.filemap.store;
18 |
19 | import java.util.List;
20 | import java.util.Set;
21 |
22 | /**
23 | *
24 | * @author Gary CHEN
25 | *
26 | */
27 | public interface StoreReader extends Store {
28 |
29 | public StoreEntry read(String key) throws StoreReaderException;
30 | public StoreEntry read(long key) throws StoreReaderException;
31 |
32 | public StoreEntry read(String key, boolean removeWhenEntryCorrupt) throws StoreReaderException;
33 | public StoreEntry read(long key, boolean removeWhenEntryCorrupt) throws StoreReaderException;
34 |
35 | public Set