There have been many excellent index structures developed for byte-addressable RAM or block-based storage [2]. However, they are not directly applicable to flash memory. Prior work on indexing over flash memory are mainly based on the use of logical addresses. Wu et al. [6] and Xiang et al. [7] propose to implement B-tree over flash memory, and a node translation table is used to map B-tree nodes to flash-memory pages. Lin et al. [5] propose a new design of hash tables for flash memory, for which a bucket is mapped to a collection of related flash-memory pages. Actually, maintaining the mapping of logical addresses to physical addresses is not an issue specific to index structures. For
flash-based disk emulation [1, 11, 16], the mapping is from disk-sector numbers to flash-memory locations. A native flash file system [17, 18] should map an i-node number with a byte offset to flash-memory addresses.
The use of logical addresses introduces two technical issues. The first prob-lem is that a RAM-resident translation table is required. The translation table costs precious RAM space and energy. For reducing the RAM-space require-ments, Chang et al. [11] developed a variable-granularity scheme for address translation. Kim et al. [15] and Lee et al. [16] propose to reduce the table size by adopting block-level translation instead of page-level translation. As to energy consumption, although it is not formally addressed in past work, its significance can be verified by the following observations: A typical SDRAM [4] needs 70 mA in operating mode, 20 mA in standby mode, and 160 mA for refresh every other 64 milli-seconds. A typical NOR flash [3] needs 30 mA in operating mode, 30 mA for read/write/erase, and 10 µA in standby mode.
Besides the costs of space and energy, the other problem of using logical ad-dresses is that the mapping is unknown until the entire flash memory is scanned.
Wu et al. [8] propose to incrementally commit summary information onto flash memory to help to speed up the scanning procedure. Yim et al. [9] propose to compress the entire mapping information and put it in some handy locations.
Regardless which techniques are taken for reducing RAM footprint and for shortening scanning time, these overheads are inevitable. Different from prior work, this work considers organizing data in terms of physical addresses. We aim at completely removing the needs for address translation and initialization scan.
3 Design and Implementation of Soft Lists
This section proposes soft lists. We shall first present simple soft lists, which emulate linearly ordered lists. Simple soft lists are then extended to multilevel soft lists for better scalability.
3.1 Simple Soft Lists
3.1.1 Index Objects and Soft Pointers
An index object is the smallest unit for indexing with soft lists. It is of a key, a value, and a soft pointer referring to another index object. Basically the length of the keys can be arbitrary, so there can be infinitely many other keys between any two keys. For simplicity, we use fixed-length slots for storing keys. A value is as large as a key in size. We assume that each update to the value rewrites the entire index object. Note that the value can also be a soft pointer referring to a data page. For the ease of presentation, index objects, objects, and keys are interchangeably used to refer to the same thing in the rest of this paper.
A B C
A spare block for GC Copy valid data
(a) (b)
?
?
?
?
Figure 2: A problem caused by garbage collection. (a) A block has valid data A, B, C, and D. (b) Before the block can be erased, all valid data are copied to a spare block. Four data objects are forcibly moved, and all the physical pointers referring to them become invalid.
As mentioned in Section 2.2, the physical residence of index objects may involuntarily be changed because of the needs for garbage collection. Figure 2(a) shows an scenario, in which a block has valid objects A, B, C, and D. To erase the block for garbage collection, beforehand all the valid objects must be moved to a spare block. However it invalidates all the physical pointers previously referring to the objects, as shown in Figure 2(b). To revise the physical pointers, objects a, b, c, and d can be rewritten out of place. However, recursively another batch of object rewrites could be triggered. Because free space is consumed before free space can be reclaimed, the system might be deadlocked.
Soft pointers are proposed to approach the problem. The basic idea is to allow a number of “probes” when referring to an index object. In other words, if an index object is involuntarily moved, it is moved to some pre-determined locations. On access, a soft pointer may not immediately refer to the desired index object, but the correct one can always be found after some probes. The
A A
Figure 3: Index object “p” refers to index object “A” by means of a soft pointer.
A turnstile is of four blocks including a spare block. (a) Object A is shifted to the spare block and then block 1 can be erased for garbage collection. (b) The soft pointer does not lose object A after erasing block 1, because it refers to all the index objects having the same block offset in a turnstile.
use of soft pointers removes pointer updates from garbage-collection activities, and therefore deadlocks are avoided.
Soft pointers are realized by means of turnstiles. A turnstile is a group of NOR-flash blocks, and the entire NOR flash is partitioned into turnstiles. Every turnstile is allocated to some spare block for garbage collection, and garbage collection is confined to each individual turnstile. Figure 3(a) shows a turnstile, in which there are four blocks and block 2 is a spare block. Consider that object
“p” outside the turnstile refers to object “A” inside the turnstile by means of a soft pointer. It is called an inter-turnstile reference. Now suppose that block 1 is chosen for erasure. Object A is “shifted” to block 2, and block 1 is then erased into a new spare block, as shown in Figure 3(b). Logically the turnstile is “rotated” counterclockwise for garbage collection. A valid object is always shifted to a spare block with the same block offset, and a soft pointer refers to all the index objects having the same block offset. As turnstile rotates, the soft pointer never loses object A, if up to four probes are allowed. Other than object A, the referred objects in blocks 3 and 4 are random objects.
If an object refers to another object in the same turnstile, then it is called an intra-turnstile reference. For intra-turnstile reference, a soft pointer is the relative distance between an object to the referred object. In this case, the maximum number of probes needed is the number of spare blocks in a turnstile.
Because the worst case is that all the spare blocks are in-between the two objects.
For example, in Figure 3, up to 1 extra probe is needed. Besides that fewer probes are needed by intra-turnstile references, the rationale to rotate a turnstile on garbage collection is to consider wear leveling. As a turnstile rotates, every block is in turn erased so wear leveling is perfect. However, readers may notice that if the block to erase is far from the spare block(s), then the overheads of object copy and block erasure is high. We shall again address this issue in Section 3.3.
For the ease of presentation, some terms are defined here: Let the degree of soft pointers be how many blocks a turnstile has. Including the intended object, a soft pointer refers to many objects. Let the intended object be the target object (e.g., object A in Figure 3), and all the others be the buddy objects of the soft pointers.
10 15 40 55 70 200
(a)
(b) 41
10 15 40 41 55 70 200
Figure 4: (a) A linearly ordered list. (b) A soft list with soft pointers. The degree of the soft pointers is two.
3.1.2 Search with Simple Soft Lists
This section introduces simple soft lists, which organize index objects with soft pointers. We are particularly interested in how search is carried out with soft lists and how soft pointers benefit search.
Let us first be focused on search with a linearly ordered list. A linearly ordered list is based on physical pointers. With the example shown in Figure 4(a), to locate a key, starting from the first index object, iteratively we move forward until the current key is no smaller than the key to find. The desired key is found if the current key equals to it, otherwise it does not exists. So to locate key 200, we need to visit 7 objects.
A soft list, which emulates a linearly ordered list, organizes index objects with soft pointers. Figure 4(b) shows an example on soft lists, in which the degree of soft pointers is two. Different from search with a linearly ordered list, we move forward until the keys of all the probed objects are no smaller than the key to find. Note that, on de-referencing a soft pointer for search, it is not required to distinguish its target object from the buddy objects.
For example, in Figure 4(b), suppose that we are to find key 200. In the beginning we start from key 10, and the next keys may be 70 and then 200.
Surprisingly, it takes only three steps. On search, it is possible that we skip too far and must fall back to try again. For example, to search key 55, starting from 10, for the first trial we go to 70, which is larger than 55, so we fall back to 10 and try again. For the second trial we get 15, which is smaller than 55, and the search continues. From key 15, we go straight to 55 and report the key is found.
The search takes three steps only. Another case on search is that the desired key does not exist. If we are to search 16 for example, from key 10, key 15 is visited. From key 15, for the first trial we have key 40, which is larger than 16.
For the second trial, we have key 55, which is also larger than 16. After trying all the possibilities, it is reported that key 16 can not be found.
Because buddy objects are random objects, on search with soft lists it is possible to skip over a large amount of index objects. However, by this way backward moves are also possible. For example, suppose that we are to search key 41 and currently we are at key 40. From key 40 it is possible to move backward to key 10. In this case, we shall fall back to key 40 and try again, and this time we shall find key 41. Backward moves are of course overheads of using soft lists, and we shall address this issue again in Section 3.2.2. Algorithm 1
Algorithm 1 Search with a simple soft list Require: curr: the first (leftmost) index object,
key: the key to locate
Define: curr→next: a soft pointer,
curr→next[i]: the i-th probe of the soft pointer.
1: while curr→key != key do
2: for each curr→next[i] do
3: if curr→next[i]→key ¡ curr→key then
4: continue; {avoid backward moves}
5: end if
6: if curr→next[i]→key ≤ key then
7: curr = curr→next[i];
8: break;
9: end if
10: end for
11: if curr→next[i]→key ¿ key then
12: return NOT FOUND; {all probes have been tried}
13: end if
14: end while
15: return FOUND;
shows the procedure of searching with a simple soft list.
3.1.3 Insertion/Deletion and Spare Pointers
Different from search, insertion/deletion involve modifications to soft lists. Let us first be focused on insertion. Because soft lists emulate linearly ordered lists, a new object is always inserted right after the object which’s key is immediately smaller than the new key. Let the object be the immediate predecessor of the new object. If the new object is always written as a buddy object of the immediate predecessor, then the predecessor’s soft pointer needs not change. However, it is infeasible because the total number of buddy objects a soft pointer can have is limited. Instead, any free space is eligible for storing the new object. To refer to the newly inserted object, the predecessor’s soft pointer must be revised.
As mentioned previously in Section 2.2, updates to pointers inevitably pose the propagation problem. To address this, for each index object, we propose to reserve some empty slots as spare pointers. In the rest of this paper, the terms spare pointer and spare slots are interchangeably used. Initially a soft pointer occupies the first spare slot. As the soft pointer is revised, updates are in turn logged in empty spare slots. Figure 5 shows that an index object has four spare pointers, and initially the first is a soft pointer referring to object A. Suppose that the soft pointer is to be revised to refer to a newly inserted object B. A new soft pointer is written to the second slot, and then that in the first slot becomes invalid. The third spare pointer is in turn used for referring to another object C. By this way, until all the spare pointers are used up, an index object may revise its soft pointer for many times. The idea of spare pointers is feasible thanks to that NOR flash is byte-addressable.
When an index object runs out all its spare pointers, to refresh its spare slots, we may choose to rotate the turnstile it belongs to until the object is shifted
key
Figure 5: An index object, in which there are four spare slots. The object’s soft pointer is in turn revised to refer to objects A, B, and C. The fourth slot is not yet used.
to a spare block. However, it might be too costly, if garbage collection is not necessary at that time. Instead, we propose to rewrite the index object out of place. As readers may notice, to rewrite an object may in turn triggers pointer updates. But the use of spare pointer can largely slow down the propagation of pointer updates. For example, if one object has eight spare pointers, then pointer updates won’t be propagated to three other objects until an object is updated out of place for 83 = 512 times. Whenever necessary, turnstiles can be rotated to completely stop any propagation. The use of spare pointers of course has its drawbacks. Specifically, the spare pointers must be scanned to identify which one is the valid pointer. However, in contrast to rewriting index objects, the cost of pointer scan is acceptable, because NOR flash reads much faster than writes, as shown in Table 1. We shall provide evaluation on this in our experiments.
With spare pointers, before a new object is inserted, its immediate prede-cessor must be located. To locate the location for insertion and the immediate predecessor, starting from the first object in a soft list, repeatedly we move forward to the next object via soft pointers until all the referred objects’ key are larger than the key to be inserted. At this point, the current object is the immediate predecessor.
For example, to insert key 16 to the soft list in Figure 4(b), starting from key 10, the next key can be 200. Because 200 is larger than 16, we fall back to 10, and for the second probe we have 15, which is smaller than 16. So we move forward to 15, and then get the next key 40. Key 40 is larger than key 16, so we fall back and try again to de-reference the soft pointer of key 15, and this time we have 55. Because both 40 and 55 are larger than 16, we stop here and report that the immediate predecessor of 16 is 15. The procedure to find immediate predecessors is very similar to that in Algorithm 1, except that, when the algorithm reports “NOT FOUND” (i.e., Step 12), “curr” is the immediate predecessor. A new object is then inserted right after the immediate predecessor, and then the inserted object refers to the predecessor’s prior target object.
Deletion is carried out with a similar procedure. The immediate predecessor of the deleted object is first located, and then the predecessor’s soft pointer is revised to refer to the target object of the deleted object.
10
Figure 6: A multilevel soft list, which is of four simple soft list. Index objects hook on soft lists by means of soft pointers with degree=2. References for random forward skips are not drawn.