From f14d4e06b864bce223490b7df739bed1d1f87d30 Mon Sep 17 00:00:00 2001 From: Knut Forkalsrud Date: Mon, 2 Jan 2012 19:28:27 -0800 Subject: [PATCH] Make sure we flush the cached video if the source file has changed. --- .../java/org/forkalsrud/album/db/Chunk.java | 4 +++- .../org/forkalsrud/album/db/MovieDatabase.java | 12 +++++++----- .../org/forkalsrud/album/video/MovieCoder.java | 18 ++++++++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/forkalsrud/album/db/Chunk.java b/src/main/java/org/forkalsrud/album/db/Chunk.java index e256ad5..3591160 100644 --- a/src/main/java/org/forkalsrud/album/db/Chunk.java +++ b/src/main/java/org/forkalsrud/album/db/Chunk.java @@ -5,10 +5,12 @@ package org.forkalsrud.album.db; public class Chunk { + public long timestamp; public byte[] bits; public byte[] meta; - public Chunk(int capacity, int metaCapacity) { + public Chunk(long timestamp, int capacity, int metaCapacity) { + this.timestamp = timestamp; this.bits = new byte[capacity]; this.meta = new byte[0]; } diff --git a/src/main/java/org/forkalsrud/album/db/MovieDatabase.java b/src/main/java/org/forkalsrud/album/db/MovieDatabase.java index e376bd6..c77120e 100644 --- a/src/main/java/org/forkalsrud/album/db/MovieDatabase.java +++ b/src/main/java/org/forkalsrud/album/db/MovieDatabase.java @@ -78,7 +78,7 @@ public class MovieDatabase extends TupleBinding { OperationStatus status = OperationStatus.SUCCESS; Transaction txn = environment.beginTransaction(null, null); while (OperationStatus.SUCCESS.equals(status)) { - DatabaseEntry binKey = key(key, seq); + DatabaseEntry binKey = key(key, seq++); status = db.delete(txn, binKey); } txn.commitSync(); @@ -96,12 +96,13 @@ public class MovieDatabase extends TupleBinding { public Chunk entryToObject(TupleInput in) { int version = in.readInt(); - if (version != 1 && version != 2) { - throw new RuntimeException("I only understand versions 1 and 2"); + if (version != 1 && version != 2 && version != 3) { + throw new RuntimeException("I only understand versions 1, 2 and 3"); } + long ts = version >= 3 ? in.readLong() : 0; int lobLen = in.readInt(); int metaLen = version >= 2 ? in.readInt() : 0; - Chunk chunk = new Chunk(lobLen, metaLen); + Chunk chunk = new Chunk(ts, lobLen, metaLen); in.read(chunk.bits, 0, lobLen); if (version >= 2) { in.read(chunk.meta, 0, metaLen); @@ -113,7 +114,8 @@ public class MovieDatabase extends TupleBinding { @Override public void objectToEntry(Chunk chunk, TupleOutput out) { - out.writeInt(2); // version 1 + out.writeInt(3); // version 3 + out.writeLong(chunk.timestamp); out.writeInt(chunk.bits.length); out.writeInt(chunk.meta.length); out.write(chunk.bits); diff --git a/src/main/java/org/forkalsrud/album/video/MovieCoder.java b/src/main/java/org/forkalsrud/album/video/MovieCoder.java index eafe0f5..938f5d9 100644 --- a/src/main/java/org/forkalsrud/album/video/MovieCoder.java +++ b/src/main/java/org/forkalsrud/album/video/MovieCoder.java @@ -159,9 +159,11 @@ public class MovieCoder { private int chunkNo = 0; private FlvFilter filter; private String dbKey; + private long fileTimestamp; public EncodingProcess(File file, Thumbnail thumbnail, Dimension size) { this.file = file; + this.fileTimestamp = file.lastModified(); this.targetSize = size; if (targetSize.getWidth() % 2 > 0) targetSize = new Dimension(targetSize.getWidth() + 1, targetSize.getHeight()); if (targetSize.getHeight() % 2 > 0) targetSize = new Dimension(targetSize.getWidth(), targetSize.getHeight() + 1); @@ -246,7 +248,7 @@ public class MovieCoder { @Override public void writeHeader(byte[] data) { int len = data.length; - Chunk chunk0 = new Chunk(len, 0); + Chunk chunk0 = new Chunk(fileTimestamp, len, 0); chunk0.bits = data; movieDb.store(dbKey, 0, chunk0); notifyListeners(0, false); @@ -290,7 +292,7 @@ public class MovieCoder { private void startNewChunk() { this.chunkNo++; - this.currentChunk = new Chunk(chunkSize, 0); + this.currentChunk = new Chunk(fileTimestamp, chunkSize, 0); this.chunkPos = 0; this.remainingCapacity = chunkSize; } @@ -309,7 +311,7 @@ public class MovieCoder { return; } // reallocate - Chunk last = new Chunk(chunkPos, 0); + Chunk last = new Chunk(fileTimestamp, chunkPos, 0); System.arraycopy(currentChunk.bits, 0, last.bits, 0, chunkPos); movieDb.store(key(file, targetSize), chunkNo, last); currentChunk = null; @@ -353,7 +355,7 @@ public class MovieCoder { // TODO (knut 05 JUL 2011) Come up with a better interface for supporting // range requests etcetera - public void stream(File file, Thumbnail thumbnail, String size, OutputStream out) throws IOException, InterruptedException { + public void stream(File file, Thumbnail thumbnail, String size, OutputStream out) { try { grabStream(file, thumbnail, size).stream(out); @@ -379,6 +381,14 @@ public class MovieCoder { EncodingProcess ep = currentEncodings.get(key); Chunk chunk = movieDb.load(key, 0); + // If the file has been modified since our last encoding job finished + if (chunk != null && ep == null) { + if (chunk.timestamp != file.lastModified()) { + log.info(" " + key + " has changed so cache entry wil be refreshed"); + movieDb.delete(key); + chunk = null; + } + } // If neither we need to start the encoding process if (chunk == null && ep == null) { ep = submitEncodingJob(file, thumbnail, targetSize, key);