]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.filesystem.services/src/org/simantics/filesystem/services/internal/sizetracker/SizeTrackerImpl.java
Added org.simantics.filesystem.services
[simantics/platform.git] / bundles / org.simantics.filesystem.services / src / org / simantics / filesystem / services / internal / sizetracker / SizeTrackerImpl.java
diff --git a/bundles/org.simantics.filesystem.services/src/org/simantics/filesystem/services/internal/sizetracker/SizeTrackerImpl.java b/bundles/org.simantics.filesystem.services/src/org/simantics/filesystem/services/internal/sizetracker/SizeTrackerImpl.java
new file mode 100644 (file)
index 0000000..b1ca0aa
--- /dev/null
@@ -0,0 +1,92 @@
+package org.simantics.filesystem.services.internal.sizetracker;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+import java.util.function.LongConsumer;
+
+import org.simantics.filesystem.services.sizetracker.SizeChangeEvent;
+import org.simantics.filesystem.services.sizetracker.SizeTracker;
+import org.simantics.utils.datastructures.file.DirectorySizeTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ * 
+ * TODO: change to use quiet time and "post notification" to throttle updates
+ */
+public class SizeTrackerImpl implements SizeTracker {
+
+       private Logger logger = LoggerFactory.getLogger(SizeTrackerImpl.class);
+
+       private Path path;
+       private DirectorySizeServiceImpl service;
+       private DirectorySizeTracker tracker;
+       private CopyOnWriteArrayList<Consumer<SizeChangeEvent>> listeners = new CopyOnWriteArrayList<>();
+       private volatile long oldSize = 0L;
+
+       private LongConsumer theListener = newSize -> {
+               long os = oldSize;
+               oldSize = newSize;
+               //logger.info(path + ": size changed: " + ((double) os / (1024.0*1024.0)) + " MB -> " + ((double) newSize / (1024.0*1024.0)) + " MB");
+               fireSizeChange(os, newSize);
+       };
+
+       public SizeTrackerImpl(DirectorySizeServiceImpl service, Path path) throws IOException {
+               this.service = service;
+               this.path = path;
+               this.tracker = DirectorySizeTracker.startTracker(theListener);
+       }
+
+       public SizeTrackerImpl start() throws IOException {
+               new Thread(() -> {
+                       try {
+                               synchronized (SizeTrackerImpl.this) {
+                                       if (tracker != null)
+                                               tracker.track(path);
+                               }
+                       } catch (IOException e) {
+                               logger.error("Failed to start tracking size of directory " + path, e);
+                       }
+               }, "SizeTrackerStarter").start();
+               return this;
+       }
+
+       @Override
+       public synchronized void close() throws IOException {
+               if (tracker == null)
+                       return;
+               tracker.close();
+               tracker = null;
+               service.removeTracker(path);
+       }
+
+       @Override
+       public Path path() {
+               return path;
+       }
+
+       @Override
+       public long size() {
+               return oldSize;
+       }
+
+       @Override
+       public void addListener(Consumer<SizeChangeEvent> listener) {
+               listeners.add(listener);
+       }
+
+       @Override
+       public void removeListener(Consumer<SizeChangeEvent> listener) {
+               listeners.remove(listener);
+       }
+
+       private void fireSizeChange(long oldSize, long newSize) {
+               SizeChangeEvent e = new SizeChangeEventImpl(path, oldSize, newSize);
+               listeners.forEach(c -> c.accept(e));
+       }
+
+}