@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="00-full-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="00-full-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>00-full-overview</title>
|
||||
<rect fill="white" x="-5" y="170" width="704" height="599"/>
|
||||
<g id="00-full-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -18,7 +18,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="00-lsm-read-flow" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="00-lsm-read-flow" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>00-lsm-read-flow</title>
|
||||
<rect fill="white" x="6" y="194" width="693" height="361"/>
|
||||
<g id="00-lsm-read-flow_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -13,7 +13,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="00-lsm-write-flow" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="00-lsm-write-flow" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>00-lsm-write-flow</title>
|
||||
<rect fill="white" x="6" y="245" width="693" height="273"/>
|
||||
<g id="00-lsm-write-flow_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -13,7 +13,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-01-frozen" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-01-frozen" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-01-frozen</title>
|
||||
<rect fill="white" x="6" y="214" width="693" height="135"/>
|
||||
<g id="week1-01-frozen_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-01-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-01-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-01-overview</title>
|
||||
<rect fill="white" x="6" y="213" width="693" height="136"/>
|
||||
<g id="week1-01-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-01-single" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-01-single" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-01-single</title>
|
||||
<rect fill="white" x="6" y="245" width="693" height="104"/>
|
||||
<g id="week1-01-single_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-02-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-02-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-02-overview</title>
|
||||
<rect fill="white" x="6" y="213" width="693" height="136"/>
|
||||
<g id="week1-02-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-03-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-03-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-03-overview</title>
|
||||
<rect fill="white" x="-5" y="245" width="704" height="524"/>
|
||||
<g id="week1-03-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-04-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-04-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-04-overview</title>
|
||||
<rect fill="white" x="6" y="245" width="693" height="480"/>
|
||||
<g id="week1-04-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-05-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-05-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-05-overview</title>
|
||||
<rect fill="white" x="6" y="170" width="693" height="236"/>
|
||||
<g id="week1-05-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-07-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-07-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-07-overview</title>
|
||||
<rect fill="white" x="-5" y="461" width="784" height="308"/>
|
||||
<g id="week1-07-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -13,7 +13,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week1-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week1-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week1-overview</title>
|
||||
<rect fill="white" x="-5" y="170" width="784" height="599"/>
|
||||
<g id="week1-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-00-leveled" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-00-leveled" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-00-leveled</title>
|
||||
<rect fill="white" x="85" y="204" width="473" height="245"/>
|
||||
<g id="week2-00-leveled_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-00-tiered" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-00-tiered" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-00-tiered</title>
|
||||
<rect fill="white" x="62" y="198" width="453" height="306"/>
|
||||
<g id="week2-00-tiered_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-00-two-extremes-1" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-00-two-extremes-1" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-00-two-extremes-1</title>
|
||||
<rect fill="white" x="85" y="277" width="517" height="177"/>
|
||||
<g id="week2-00-two-extremes-1_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-00-two-extremes-2" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-00-two-extremes-2" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-00-two-extremes-2</title>
|
||||
<rect fill="white" x="85" y="277" width="527" height="328"/>
|
||||
<g id="week2-00-two-extremes-2_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
94
mini-lsm-book/src/lsm-tutorial/week2-01-full.svg
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="85 204 473 198" width="473" height="198">
|
||||
<defs>
|
||||
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
|
||||
<g>
|
||||
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-01-full" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-01-full</title>
|
||||
<rect fill="white" x="85" y="204" width="473" height="198"/>
|
||||
<g id="week2-01-full_Layer_1">
|
||||
<title>Layer 1</title>
|
||||
<g id="Graphic_67">
|
||||
<rect x="119" y="288" width="150.5" height="112.974" fill="white"/>
|
||||
<path d="M 119 288 L 269.5 288 L 269.5 400.974 L 119 400.974 Z" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_47">
|
||||
<rect x="128.292" y="301.974" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="128.292" y="301.974" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(133.292 313.5)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_46">
|
||||
<text transform="translate(90 313.5)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L0</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_45">
|
||||
<rect x="128.5" y="353.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="128.5" y="353.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(133.5 365.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_43">
|
||||
<text transform="translate(90.208 365.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_69">
|
||||
<line x1="159.69716" y1="204.974" x2="159.69716" y2="292.074" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_77">
|
||||
<rect x="200.88684" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="200.88684" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(205.88684 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_78">
|
||||
<rect x="340" y="348.5" width="217.5" height="52.474" fill="white"/>
|
||||
<path d="M 340 348.5 L 557.5 348.5 L 557.5 400.974 L 340 400.974 Z" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_79">
|
||||
<rect x="346.208" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="346.208" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(351.208 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_80">
|
||||
<rect x="416.5765" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="416.5765" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(421.5765 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_81">
|
||||
<rect x="486.5765" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="486.5765" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(491.5765 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_83">
|
||||
<line x1="269.5" y1="353.43125" x2="330.1692" y2="360.64243" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_84">
|
||||
<text transform="translate(286.65832 320.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="29132252e-20" y="15">Full Compaction</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_85">
|
||||
<text transform="translate(309 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-01-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-01-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-01-overview</title>
|
||||
<rect fill="white" x="6" y="245" width="693" height="269"/>
|
||||
<g id="week2-01-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
141
mini-lsm-book/src/lsm-tutorial/week2-02-simple.svg
Normal file
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="85 204 473 245" width="473" height="245">
|
||||
<defs>
|
||||
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
|
||||
<g>
|
||||
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-02-simple" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-02-simple</title>
|
||||
<rect fill="white" x="85" y="204" width="473" height="245"/>
|
||||
<g id="week2-02-simple_Layer_1">
|
||||
<title>Layer 1</title>
|
||||
<g id="Graphic_67">
|
||||
<rect x="119" y="288" width="150.5" height="112.974" fill="white"/>
|
||||
<path d="M 119 288 L 269.5 288 L 269.5 400.974 L 119 400.974 Z" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_47">
|
||||
<rect x="128.292" y="301.974" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="128.292" y="301.974" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(133.292 313.5)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_46">
|
||||
<text transform="translate(90 313.5)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L0</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_45">
|
||||
<rect x="128.5" y="353.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="128.5" y="353.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(133.5 365.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_43">
|
||||
<text transform="translate(90.208 365.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_42">
|
||||
<rect x="200.88684" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="200.88684" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(205.88684 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_41">
|
||||
<rect x="273.48168" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="273.48168" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(278.48168 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_40">
|
||||
<text transform="translate(90 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L2</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_39">
|
||||
<rect x="128.292" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="128.292" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(133.292 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_38">
|
||||
<rect x="346.07652" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="346.07652" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(351.07652 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_69">
|
||||
<line x1="159.69716" y1="204.974" x2="159.69716" y2="292.074" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_77">
|
||||
<rect x="200.88684" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="200.88684" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(205.88684 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_78">
|
||||
<rect x="340" y="348.5" width="217.5" height="52.474" fill="white"/>
|
||||
<path d="M 340 348.5 L 557.5 348.5 L 557.5 400.974 L 340 400.974 Z" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_79">
|
||||
<rect x="346.208" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="346.208" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(351.208 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_80">
|
||||
<rect x="416.5765" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="416.5765" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(421.5765 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_81">
|
||||
<rect x="486.5765" y="354.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="486.5765" y="354.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(491.5765 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Line_83">
|
||||
<line x1="269.5" y1="353.43125" x2="330.1692" y2="360.64243" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
</g>
|
||||
<g id="Graphic_84">
|
||||
<text transform="translate(345 313.5)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="2842171e-20" y="15">Simple Leveled Compaction</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_85">
|
||||
<text transform="translate(309 366.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="1278977e-18" y="15">L1</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_86">
|
||||
<rect x="418.67136" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="418.67136" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(423.67136 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Graphic_87">
|
||||
<rect x="490.67136" y="406.5" width="62.81032" height="41.5" fill="white"/>
|
||||
<rect x="490.67136" y="406.5" width="62.81032" height="41.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
|
||||
<text transform="translate(495.67136 418.026)" fill="black">
|
||||
<tspan font-family="Helvetica Neue" font-size="16" fill="black" x="11.445159" y="15">SST</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-04-leveled" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-04-leveled" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-04-leveled</title>
|
||||
<rect fill="white" x="85" y="204" width="542" height="405"/>
|
||||
<g id="week2-04-leveled_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -13,7 +13,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-05-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-05-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-05-overview</title>
|
||||
<rect fill="white" x="6" y="245" width="765" height="268"/>
|
||||
<g id="week2-05-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
@@ -8,7 +8,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-06-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-06-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-06-overview</title>
|
||||
<rect fill="white" x="6" y="213" width="693" height="291"/>
|
||||
<g id="week2-06-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -13,7 +13,7 @@
|
||||
</g>
|
||||
</marker>
|
||||
</defs>
|
||||
<g id="week2-overview" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none" stroke="none" fill="none">
|
||||
<g id="week2-overview" fill="none" stroke="none" fill-opacity="1" stroke-dasharray="none" stroke-opacity="1">
|
||||
<title>week2-overview</title>
|
||||
<rect fill="white" x="6" y="156" width="788" height="358"/>
|
||||
<g id="week2-overview_Layer_1">
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,6 +1,6 @@
|
||||
# Compaction Implementation
|
||||
|
||||

|
||||

|
||||
|
||||
In this chapter, you will:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Simple Compaction Strategy
|
||||
|
||||

|
||||

|
||||
|
||||
In this chapter, you will:
|
||||
|
||||
|
||||
@@ -9,10 +9,70 @@ In this chapter, you will:
|
||||
|
||||
## Task 1: Manifest Encoding
|
||||
|
||||
The system uses a manifest file to record all operations happened in the engine. Currently, there are only two types of them: compaction and SST flush. When the engine restarts, it will read the manifest file, reconstruct the state, and load the SST files on the disk.
|
||||
|
||||
There are many approaches to storing the LSM state. One of the easiest way is to simply store the full state into a JSON file. Every time we do a compaction or flush a new SST, we can serialize the entire LSM state into a file. The problem with this approach is that when the database gets super large (i.e., 10k SSTs), writing the manifest to the disk would be super slow. Therefore, we designed the manifest to be a append-only file.
|
||||
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/manifest.rs
|
||||
```
|
||||
|
||||
We encode the manifest records using JSON. You may use `serde_json::to_vec` to encode a manifest record to a json, write it to the manifest file, and do a fsync. When you read from the manifest file, you may use `serde_json::Deserializer::from_slice` and it will return a stream of records. You do not need to store the record length or so, as `serde_json` can automatically find the split of the records.
|
||||
|
||||
After the engine runs for several hours, the manifest file might get very large. At that time, you may periodically compact the manifest file to store the current snapshot and truncate the logs. This is an optimization you may implement as part of bonus tasks.
|
||||
|
||||
## Task 2: Write Manifests
|
||||
|
||||
You can now go ahead and modify your LSM engine to write manifests when necessary. In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/lsm_storage.rs
|
||||
src/compact.rs
|
||||
```
|
||||
|
||||
For now, we only use two types of the manifest records: SST flush and compaction. SST flush record stores the SST id that gets flushed to the disk. Compaction record stores the compaction task and the produced SST ids. Every time you write some new files the the disk, first sync the files and the storage directory, and then write to the manifest and sync the manifest.
|
||||
|
||||
To sync the directory, you may implement the `sync_dir` function, where you can use `File::open(dir).sync_all()?` to sync it. On Linux, directory is a file that contains the list of files in the directory. By doing fsync on the directory, you will ensure that the newly-written (or removed) files can be visible to the user if the power goes off.
|
||||
|
||||
## Task 3: Flush on Close
|
||||
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/lsm_storage.rs
|
||||
```
|
||||
|
||||
You will need to implement the `close` function. If `self.options.enable_wal = false` (we will cover WAL in the next chapter), you should flush all memtables to the disk before stopping the storage engine, so that all user changes will be persisted.
|
||||
|
||||
## Task 4: Recover from the State
|
||||
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/lsm_storage.rs
|
||||
```
|
||||
|
||||
Now, you may modify the `open` function to recover the engine state from the manifest file. To recover it, you will need to first generate the list of SSTs you will need to load. You can do this by calling `apply_compaction_result` and recover SST ids in the LSM state. After that, you may iterate the state and load all SSTs (update the sstables hash map). During the process, you will need to compute the maximum SST id and update the `next_sst_id` field. After that, you may create a new memtable using that id and increment the id by one.
|
||||
|
||||
You may use the mini-lsm-cli to test your implementation.
|
||||
|
||||
```
|
||||
cargo run --bin mini-lsm-cli
|
||||
fill 1000 2000
|
||||
close
|
||||
cargo run --bin mini-lsm-cli
|
||||
get 1500
|
||||
```
|
||||
|
||||
## Test Your Understanding
|
||||
|
||||
* When do you need to call `fsync`? Why do you need to fsync the directory?
|
||||
* What are the places you will need to write to the manifest?
|
||||
|
||||
## Bonus Tasks
|
||||
|
||||
* **Manifest Compaction.** When the number of logs in the manifest file gets too large, you can rewrite the manifest file to only store the current snapshot and append new logs to that file.
|
||||
|
||||
{{#include copyright.md}}
|
||||
|
||||
@@ -9,13 +9,52 @@ In this chapter, you will:
|
||||
|
||||
## Task 1: WAL Encoding
|
||||
|
||||
## Task 2: Write WALs
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/wal.rs
|
||||
```
|
||||
|
||||
In the previous chapter, we have implemented the manifest file, so that the LSM state can be persisted. And we implemented the `close` function to flush all memtables to SSTs before stopping the engine. Now, what if the system crashes (i.e., powered off)? We can log memtable modifications to WAL (write-ahead log), and recover WALs when restarting the database. WAL is only enabled when `self.options.enable_wal = true`.
|
||||
|
||||
The WAL encoding is simply a list of key-value pairs.
|
||||
|
||||
```
|
||||
| key_len | key | value_len | value |
|
||||
```
|
||||
|
||||
You will also need to implement the `recover` function to read the WAL and recover the state of a memtable.
|
||||
|
||||
## Task 2: Integrate WALs
|
||||
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/mem_table.rs
|
||||
src/wal.rs
|
||||
src/lsm_storage.rs
|
||||
```
|
||||
|
||||
`MemTable` has a WAL field. If the `wal` field is set to `Some(wal)`, you will need to append to the WAL when updating the memtable. In your LSM engine, you will need to create WALs if `enable_wal = true`. You will also need update the manifest using the `ManifestRecord::NewMemtable` record when new memtable is created.
|
||||
|
||||
## Task 3: Recover from the WALs
|
||||
|
||||
In this task, you will need to modify:
|
||||
|
||||
```
|
||||
src/lsm_storage.rs
|
||||
```
|
||||
|
||||
If WAL is enabled, you will need to recover the memtables based on WALs when loading the database. You will also need to implement the `sync` function of the database. The basic guarantee of `sync` is that the engine is sure that the data is persisted to the disk (and will be recovered when it restarts). To achieve this, you can simply sync the WAL corresponding to the current memtable.
|
||||
|
||||
```
|
||||
cargo run --bin mini-lsm-cli -- --enable-wal
|
||||
```
|
||||
|
||||
## Test Your Understanding
|
||||
|
||||
* When can you tell the user that their modifications (put/delete) have been persisted?
|
||||
* How can you handle corrupted data in WAL?
|
||||
|
||||
We do not provide reference answers to the questions, and feel free to discuss about them in the Discord community.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ struct Args {
|
||||
path: PathBuf,
|
||||
#[arg(long, default_value = "leveled")]
|
||||
compaction: CompactionStrategy,
|
||||
#[arg(long, default_value = "true")]
|
||||
#[arg(long)]
|
||||
enable_wal: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
use std::ops::Bound;
|
||||
|
||||
use bytes::Bytes;
|
||||
use tempfile::tempdir;
|
||||
|
||||
use crate::iterators::StorageIterator;
|
||||
use crate::lsm_storage::{LsmStorageInner, LsmStorageOptions};
|
||||
|
||||
fn as_bytes(x: &[u8]) -> Bytes {
|
||||
Bytes::copy_from_slice(x)
|
||||
}
|
||||
|
||||
fn check_iter_result(iter: impl StorageIterator, expected: Vec<(Bytes, Bytes)>) {
|
||||
let mut iter = iter;
|
||||
for (k, v) in expected {
|
||||
assert!(iter.is_valid());
|
||||
assert_eq!(
|
||||
k,
|
||||
iter.key(),
|
||||
"expected key: {:?}, actual key: {:?}",
|
||||
k,
|
||||
as_bytes(iter.key()),
|
||||
);
|
||||
assert_eq!(
|
||||
v,
|
||||
iter.value(),
|
||||
"expected value: {:?}, actual value: {:?}",
|
||||
v,
|
||||
as_bytes(iter.value()),
|
||||
);
|
||||
iter.next().unwrap();
|
||||
}
|
||||
assert!(!iter.is_valid());
|
||||
}
|
||||
|
||||
fn sync(storage: &LsmStorageInner) {
|
||||
storage.force_freeze_memtable().unwrap();
|
||||
storage.force_flush_next_imm_memtable().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_get() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
assert_eq!(&storage.get(b"1").unwrap().unwrap()[..], b"233");
|
||||
assert_eq!(&storage.get(b"2").unwrap().unwrap()[..], b"2333");
|
||||
assert_eq!(&storage.get(b"3").unwrap().unwrap()[..], b"23333");
|
||||
storage.delete(b"2").unwrap();
|
||||
assert!(storage.get(b"2").unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_scan_memtable_1() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
storage.delete(b"2").unwrap();
|
||||
check_iter_result(
|
||||
storage.scan(Bound::Unbounded, Bound::Unbounded).unwrap(),
|
||||
vec![
|
||||
(Bytes::from("1"), Bytes::from("233")),
|
||||
(Bytes::from("3"), Bytes::from("23333")),
|
||||
],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Included(b"1"), Bound::Included(b"2"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("1"), Bytes::from("233"))],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Excluded(b"1"), Bound::Excluded(b"3"))
|
||||
.unwrap(),
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_scan_memtable_2() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
storage.delete(b"1").unwrap();
|
||||
check_iter_result(
|
||||
storage.scan(Bound::Unbounded, Bound::Unbounded).unwrap(),
|
||||
vec![
|
||||
(Bytes::from("2"), Bytes::from("2333")),
|
||||
(Bytes::from("3"), Bytes::from("23333")),
|
||||
],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Included(b"1"), Bound::Included(b"2"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("2"), Bytes::from("2333"))],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Excluded(b"1"), Bound::Excluded(b"3"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("2"), Bytes::from("2333"))],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_get_after_sync() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
sync(&storage);
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
assert_eq!(&storage.get(b"1").unwrap().unwrap()[..], b"233");
|
||||
assert_eq!(&storage.get(b"2").unwrap().unwrap()[..], b"2333");
|
||||
assert_eq!(&storage.get(b"3").unwrap().unwrap()[..], b"23333");
|
||||
storage.delete(b"2").unwrap();
|
||||
assert!(storage.get(b"2").unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_scan_memtable_1_after_sync() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
sync(&storage);
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
storage.delete(b"2").unwrap();
|
||||
check_iter_result(
|
||||
storage.scan(Bound::Unbounded, Bound::Unbounded).unwrap(),
|
||||
vec![
|
||||
(Bytes::from("1"), Bytes::from("233")),
|
||||
(Bytes::from("3"), Bytes::from("23333")),
|
||||
],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Included(b"1"), Bound::Included(b"2"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("1"), Bytes::from("233"))],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Excluded(b"1"), Bound::Excluded(b"3"))
|
||||
.unwrap(),
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_scan_memtable_2_after_sync() {
|
||||
use crate::lsm_storage::LsmStorageInner;
|
||||
let dir = tempdir().unwrap();
|
||||
let storage = LsmStorageInner::open(&dir, LsmStorageOptions::default_for_week1_test()).unwrap();
|
||||
storage.put(b"1", b"233").unwrap();
|
||||
storage.put(b"2", b"2333").unwrap();
|
||||
sync(&storage);
|
||||
storage.put(b"3", b"23333").unwrap();
|
||||
sync(&storage);
|
||||
storage.delete(b"1").unwrap();
|
||||
check_iter_result(
|
||||
storage.scan(Bound::Unbounded, Bound::Unbounded).unwrap(),
|
||||
vec![
|
||||
(Bytes::from("2"), Bytes::from("2333")),
|
||||
(Bytes::from("3"), Bytes::from("23333")),
|
||||
],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Included(b"1"), Bound::Included(b"2"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("2"), Bytes::from("2333"))],
|
||||
);
|
||||
check_iter_result(
|
||||
storage
|
||||
.scan(Bound::Excluded(b"1"), Bound::Excluded(b"3"))
|
||||
.unwrap(),
|
||||
vec![(Bytes::from("2"), Bytes::from("2333"))],
|
||||
);
|
||||
}
|
||||