changeset 168:04baa690f90d

* Start adding StorageAdviser class to determine whether caches should be on disc or in memory
author Chris Cannam
date Mon, 25 Sep 2006 13:44:05 +0000
parents 665342c6ec57
children 603991c63ff6
files base/StorageAdviser.cpp base/StorageAdviser.h base/base.pro data/fft/FFTDataServer.cpp system/System.cpp system/System.h
diffstat 6 files changed, 174 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base/StorageAdviser.cpp	Mon Sep 25 13:44:05 2006 +0000
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "StorageAdviser.h"
+
+#include "Exceptions.h"
+#include "TempDirectory.h"
+
+#include "system/System.h"
+
+#include <iostream>
+
+StorageAdviser::Recommendation
+StorageAdviser::recommend(Criteria criteria,
+			  int minimumSize,
+			  int maximumSize)
+{
+    QString path = TempDirectory::getInstance()->getPath();
+
+    int discSpace = GetDiscSpaceMBAvailable(path.toLocal8Bit());
+    int memory = GetRealMemoryMBAvailable();
+
+    std::cerr << "Disc space: " << discSpace << ", memory: " << memory << std::endl;
+
+    return Recommendation(0);
+}
+
+
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base/StorageAdviser.h	Mon Sep 25 13:44:05 2006 +0000
@@ -0,0 +1,51 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef _STORAGE_ADVISER_H_
+#define _STORAGE_ADVISER_H_
+
+/**
+ * A utility class designed to help decide whether to store cache data
+ * (for example FFT outputs) in memory or on disk in the TempDirectory.
+ */
+
+class StorageAdviser
+{
+public:
+    // pass to recommend() zero or more of these OR'd together
+    enum Criteria {
+        SpeedCritical       = 1,
+        PrecisionCritical   = 2,
+        RepeatabilityUseful = 4
+    };
+
+    // recommend() returns one or two of these OR'd together
+    enum Recommendation {
+        UseMemory          = 1,
+        UseDisc            = 2,
+        ConserveSpace      = 4,
+        UseAsMuchAsYouLike = 8
+    };
+
+    // may throw InsufficientDiscSpace exception if it looks like
+    // minimumSize won't fit on the disc
+
+    static Recommendation recommend(Criteria criteria,
+                                    int minimumSize,
+                                    int maximumSize);
+};
+
+#endif
+
--- a/base/base.pro	Fri Sep 22 16:46:10 2006 +0000
+++ b/base/base.pro	Mon Sep 25 13:44:05 2006 +0000
@@ -31,6 +31,7 @@
            RingBuffer.h \
            Scavenger.h \
            Selection.h \
+           StorageAdviser.h \
            TempDirectory.h \
            Thread.h \
            UnitDatabase.h \
@@ -51,6 +52,7 @@
            RealTime.cpp \
            RecentFiles.cpp \
            Selection.cpp \
+           StorageAdviser.cpp \
            TempDirectory.cpp \
            Thread.cpp \
            UnitDatabase.cpp \
--- a/data/fft/FFTDataServer.cpp	Fri Sep 22 16:46:10 2006 +0000
+++ b/data/fft/FFTDataServer.cpp	Mon Sep 25 13:44:05 2006 +0000
@@ -22,6 +22,9 @@
 
 #include "system/System.h"
 
+#include "base/StorageAdviser.h"
+
+
 #define DEBUG_FFT_SERVER 1
 //#define DEBUG_FFT_SERVER_FILL 1
 
@@ -72,6 +75,13 @@
         return server;
     }
 
+
+    //!!!
+
+    StorageAdviser::Recommendation recommendation =
+        StorageAdviser::recommend(StorageAdviser::Criteria(0), 0, 0);
+
+
     m_servers[n] = ServerCountPair
         (new FFTDataServer(n,
                            model,
--- a/system/System.cpp	Fri Sep 22 16:46:10 2006 +0000
+++ b/system/System.cpp	Mon Sep 25 13:44:05 2006 +0000
@@ -15,8 +15,14 @@
 
 #include "System.h"
 
+#include <QFile>
+#include <QTextStream>
+#include <QStringList>
+#include <QString>
+
 #ifndef _WIN32
 #include <signal.h>
+#include <sys/statvfs.h>
 #endif
 
 #include <iostream>
@@ -70,6 +76,62 @@
 #endif
 }
 
+int
+GetRealMemoryMBAvailable()
+{
+    // ugh
+    QFile meminfo("/proc/meminfo");
+    if (meminfo.open(QFile::ReadOnly)) {
+        std::cerr << "opened meminfo" << std::endl;
+        QTextStream in(&meminfo);
+        while (!in.atEnd()) {
+            QString line = in.readLine(256);
+            std::cerr << "read: \"" << line.toStdString() << "\"" << std::endl;
+            if (line.startsWith("MemFree:")) {
+                QStringList elements = line.split(' ', QString::SkipEmptyParts);
+                QString unit = "kB";
+                if (elements.size() > 2) unit = elements[2];
+                int size = elements[1].toInt();
+                std::cerr << "have size \"" << size << "\", unit \""
+                          << unit.toStdString() << "\"" << std::endl;
+                if (unit.toLower() == "gb") return size * 1024;
+                if (unit.toLower() == "mb") return size;
+                if (unit.toLower() == "kb") return size / 1024;
+                return size / 1048576;
+            }
+        }
+    }
+    return -1;
+}
+
+int
+GetDiscSpaceMBAvailable(const char *path)
+{
+#ifdef _WIN32
+    __int64 available, total, totalFree;
+    if (GetDiskFreeSpaceEx(path, &available, &total, &totalFree)) {
+        available /= 1048576;
+        return int(available);
+    } else {
+        std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code "
+                  << GetLastError() << std::endl;
+        return -1;
+    }
+#else
+    struct statvfs buf;
+    if (!statvfs(path, &buf)) {
+        // do the multiplies and divides in this order to reduce the
+        // likelihood of arithmetic overflow
+        std::cerr << "statvfs(" << path << ") says available: " << buf.f_bavail << ", block size: " << buf.f_bsize << std::endl;
+        return ((buf.f_bavail / 1024) * buf.f_bsize) / 1024;
+    } else {
+        perror("statvfs failed");
+        return -1;
+    }
+#endif
+}
+    
+
 double mod(double x, double y) { return x - (y * floor(x / y)); }
 float modf(float x, float y) { return x - (y * floorf(x / y)); }
 
--- a/system/System.h	Fri Sep 22 16:46:10 2006 +0000
+++ b/system/System.h	Mon Sep 25 13:44:05 2006 +0000
@@ -75,6 +75,14 @@
 enum ProcessStatus { ProcessRunning, ProcessNotRunning, UnknownProcessStatus };
 extern ProcessStatus GetProcessStatus(int pid);
 
+// Return a vague approximation to the number of free megabytes of real memory.
+// Return -1 if unknown.
+extern int GetRealMemoryMBAvailable();
+
+// Return a vague approximation to the number of free megabytes of disc space
+// on the partition containing the given path.  Return -1 if unknown.
+extern int GetDiscSpaceMBAvailable(const char *path);
+
 #include <cmath>
 
 extern double mod(double x, double y);