@@ -48,10 +48,11 @@ public CacheManager(@NotNull Configuration conf) throws IOException {
4848 throw new IOException ("Couldn't create cache directory!" );
4949
5050 try {
51- File tableFile = new File (parent , "table.sqlite " );
52- this .table = DriverManager .getConnection ("jdbc:sqlite :" + tableFile .getAbsolutePath ());
51+ File tableFile = new File (parent , "table" );
52+ this .table = DriverManager .getConnection ("jdbc:h2 :" + tableFile .getAbsolutePath ());
5353 createTablesIfNeeded ();
5454
55+ deleteCorruptedEntries ();
5556 if (conf .doCleanUp ()) doCleanUp ();
5657 } catch (SQLException ex ) {
5758 throw new IOException (ex );
@@ -75,6 +76,31 @@ private static File getCacheFile(@NotNull File parent, @NotNull String hex) thro
7576 return new File (parent , hex );
7677 }
7778
79+ private static boolean exists (@ NotNull File parent , @ NotNull String hex ) {
80+ String firstLevel = hex .substring (0 , 2 );
81+ String secondLevel = hex .substring (2 , 4 );
82+
83+ parent = new File (parent , "/" + firstLevel + "/" + secondLevel + "/" );
84+ return new File (parent , hex ).exists ();
85+ }
86+
87+ private void deleteCorruptedEntries () throws SQLException , IOException {
88+ if (!enabled ) return ;
89+
90+ List <String > toRemove = new ArrayList <>();
91+ try (PreparedStatement statement = table .prepareStatement ("SELECT DISTINCT fileId FROM Headers" )) {
92+ ResultSet set = statement .executeQuery ();
93+ while (set .next ()) {
94+ String fileId = set .getString ("fileId" );
95+ if (!exists (parent , fileId ))
96+ toRemove .add (fileId );
97+ }
98+ }
99+
100+ for (String fileId : toRemove )
101+ remove (fileId );
102+ }
103+
78104 private void doCleanUp () throws SQLException , IOException {
79105 if (!enabled ) return ;
80106
@@ -104,7 +130,7 @@ private void remove(@NotNull String fileIdHex) throws SQLException, IOException
104130 }
105131
106132 File file = getCacheFile (parent , fileIdHex );
107- if (!file .delete ())
133+ if (file . exists () && !file .delete ())
108134 LOGGER .warn ("Couldn't delete cache file: " + file .getAbsolutePath ());
109135
110136 LOGGER .trace (String .format ("Removed %s from cache." , fileIdHex ));
@@ -114,11 +140,11 @@ private void createTablesIfNeeded() throws SQLException {
114140 if (!enabled ) return ;
115141
116142 try (Statement statement = table .createStatement ()) {
117- statement .execute ("CREATE TABLE IF NOT EXISTS Chunks ( `fileId` TEXT NOT NULL, `chunkIndex` INTEGER NOT NULL, `available` INTEGER NOT NULL, PRIMARY KEY(`fileId`,`chunkIndex`) )" );
143+ statement .execute ("CREATE TABLE IF NOT EXISTS Chunks ( `fileId` VARCHAR NOT NULL, `chunkIndex` INTEGER NOT NULL, `available` INTEGER NOT NULL, PRIMARY KEY(`fileId`,`chunkIndex`) )" );
118144 }
119145
120146 try (Statement statement = table .createStatement ()) {
121- statement .execute ("CREATE TABLE IF NOT EXISTS Headers ( `fileId` TEXT NOT NULL, `id` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`fileId`,`id`) )" );
147+ statement .execute ("CREATE TABLE IF NOT EXISTS Headers ( `fileId` VARCHAR NOT NULL, `id` VARCHAR NOT NULL, `value` VARCHAR NOT NULL, PRIMARY KEY(`fileId`,`id`) )" );
122148 }
123149 }
124150
@@ -134,16 +160,7 @@ public CacheManager.Handler forFileId(@NotNull ByteString fileId) throws IOExcep
134160
135161 Handler handler = handlers .get (fileId );
136162 if (handler == null ) {
137- File file = getCacheFile (parent , fileId );
138- if (!file .exists ()) {
139- try {
140- remove (Utils .bytesToHex (fileId ));
141- } catch (SQLException ex ) {
142- throw new IOException (ex );
143- }
144- }
145-
146- handler = new Handler (fileId , file );
163+ handler = new Handler (fileId , getCacheFile (parent , fileId ));
147164 handlers .put (fileId , handler );
148165 }
149166
@@ -199,7 +216,7 @@ private Handler(@NotNull ByteString fileId, @NotNull File file) throws IOExcepti
199216 private void updateTimestamp () {
200217 if (updatedTimestamp ) return ;
201218
202- try (PreparedStatement statement = table .prepareStatement ("INSERT OR REPLACE INTO Headers (fileId, id, value) VALUES (?, ?, ?)" )) {
219+ try (PreparedStatement statement = table .prepareStatement ("MERGE INTO Headers (fileId, id, value) VALUES (?, ?, ?)" )) {
203220 statement .setString (1 , Utils .bytesToHex (fileId ));
204221 statement .setString (2 , Utils .byteToHex (HEADER_TIMESTAMP ));
205222 statement .setString (3 , Utils .bytesToHex (BigInteger .valueOf (System .currentTimeMillis () / 1000 ).toByteArray ()));
@@ -212,7 +229,7 @@ private void updateTimestamp() {
212229 }
213230
214231 public void setHeader (byte id , byte [] value ) throws SQLException {
215- try (PreparedStatement statement = table .prepareStatement ("INSERT OR REPLACE INTO Headers (fileId, id, value) VALUES (?, ?, ?)" )) {
232+ try (PreparedStatement statement = table .prepareStatement ("MERGE INTO Headers (fileId, id, value) VALUES (?, ?, ?)" )) {
216233 statement .setString (1 , Utils .bytesToHex (fileId ));
217234 statement .setString (2 , Utils .byteToHex (id ));
218235 statement .setString (3 , Utils .bytesToHex (value ));
@@ -293,7 +310,7 @@ public void writeChunk(byte[] buffer, int index) throws IOException, SQLExceptio
293310 io .write (buffer );
294311 }
295312
296- try (PreparedStatement statement = table .prepareStatement ("INSERT OR REPLACE INTO Chunks (fileId, chunkIndex, available) VALUES (?, ?, ?)" )) {
313+ try (PreparedStatement statement = table .prepareStatement ("MERGE INTO Chunks (fileId, chunkIndex, available) VALUES (?, ?, ?)" )) {
297314 statement .setString (1 , Utils .bytesToHex (fileId ));
298315 statement .setInt (2 , index );
299316 statement .setInt (3 , 1 );
0 commit comments