Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[c++11/14/17] Biblioteka do przechowywania danych więcej niż może ram

Ostatnio zmodyfikowano 2018-01-16 21:51
Autor Wiadomość
crash
Temat założony przez niniejszego użytkownika
[c++11/14/17] Biblioteka do przechowywania danych więcej niż może ram
» 2018-01-07 01:46:20
Cześć. Znacie jakieś gotowe biblioteki do przechowywania i iterowania po zbiorze danych, którego ilość przekracza ram? Najlepiej wraz z kodem źródłowym.
Co prawda piszę strukturę-nakładkę na wektor z cachingiem na dysk, ale to będzie kod na kolanie. Nie wchodzi w grę baza danych ze względu na czas dostępu. Nie wymagam usuwania, bardzo zależy mi na początkowym wstawieniu i iteracji za pomocą indeksu liczbowego... Typ przechowywanych elementów: bool. Z góry dzięki za pomoc
P-168451
DejaVu
» 2018-01-07 14:21:33
Nie sądzę, aby taki kontener miał sens, skoro przechowujesz tylko 0 i 1. W każdym razie nie spotkałem się z biblioteką, która umożliwiałaby przechowywanie ogromnego zbioru danych, która nie wykorzystuje bazy danych. Spotkałem się jedynie z sytuacją, gdy firma posiadała własną bibliotekę do magazynowania dużych zbiorów danych.
P-168455
pekfos
» 2018-01-07 14:22:45
Nie wymagam usuwania, bardzo zależy mi na początkowym wstawieniu i iteracji za pomocą indeksu liczbowego... Typ przechowywanych elementów: bool.
W takim wypadku własna implementacja to chwila kodzenia.
P-168456
DejaVu
» 2018-01-07 14:34:15
wystarczy zaimplementować zapisywanie jednego bloku np. 1MB booli do pliku
size_t, n-bajtów
i potem to zrobić razy K-bloków
segment na którym pracuje trzyma w pamięci i po sprawie
opcjonalnie: trzyma x-ostatnio używanych bloków w pamięci, aby nie przekroczyć Z-ramu
P-168457
crash
Temat założony przez niniejszego użytkownika
ChunkedArray, BoolArray
» 2018-01-16 21:51:39
Dzięki za sugestie. Trochę pozmienialiśmy kilka koncepcji i część obliczeń robimy jednak w Javie. Jako że wiele razy otrzymałem tutaj pomoc czy to pytając na forum czy znajdując odpowiedzi przez Google'a, postanowiłem podzielić się swoją pracą - być może komuś się przyda, mimo że kod jest w Javie:

ChunkedArray.java

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;

public class ChunkedArray<Type> {


    public static class CacheError extends Exception {

        private String msg;

        public CacheError(String msg) {
            this.msg = msg;
        }

        public String toString() {
            return this.msg;
        }
    }

    //-----------------------------------------------------------



    public  Object[]  currentCache;
    private Type      defaultValue;
    private String    cacheDir;
    private long      maxSize;
    private int       chunkSize;
    private int       chunkPosition;
    private long      chunkCount;
    private long      currentIndex;
    private long      cacheFile;


    //-----------------------------------------------------------



    private ChunkedArray(String cacheDir)
            throws ChunkedArray.CacheError
    {
        //throw new ChunkedArray.CacheError("Functionality never coded before");

        try {
            FileInputStream fstream = new FileInputStream(cacheDir + "/cache_info.txt");
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String strLine = "";
            ArrayList<String> cacheInfo = new ArrayList<>();

            while ((strLine = br.readLine()) != null)
                cacheInfo.add(strLine);

            fstream.close();
            br.close();


            this.maxSize = Long.valueOf( cacheInfo.get(0).split(":")[1] );
            this.chunkSize = Integer.valueOf( cacheInfo.get(1).split(":")[1] );
            String fileDefaultValue = cacheInfo.get(2).split(":")[1];


            System.out.println(">>fis="+cacheDir + "/" + fileDefaultValue.replaceAll("\n",""));
            fstream = new FileInputStream(cacheDir + "/" + fileDefaultValue.replaceAll("\n",""));
            ObjectInputStream ois = new ObjectInputStream(fstream);
            this.defaultValue = (Type) ois.readObject(); //type unsafe but works

            System.out.println("this.defV: " + this.defaultValue);

            this.currentCache = new Object[this.chunkSize];


            this.loadFromDisk(0);
            this.currentIndex = -1;
            this.chunkPosition = -1;
            this.cacheDir = cacheDir;

            System.out.println("zaladowano!");

        } catch (Exception e) {
            throw new ChunkedArray.CacheError("ChunkedArray ctor CacheError: "+e.getClass().getName());
        }

    }


    public ChunkedArray(Type defaulValue, String cacheDir, long maxSize, int chunkSize)
        throws ChunkedArray.CacheError
    {
        this.defaultValue = defaulValue;
        this.cacheDir = cacheDir;
        this.maxSize = maxSize;
        this.chunkSize = chunkSize;

        this.chunkPosition = 0;
        this.chunkCount = (int)( maxSize / chunkSize) + 1;

        this.currentIndex = 0;

        this.resetCache();
        this.fillCacheDefaultValues();

        this.createDiskStructure();
        this.saveCacheInfo();
        this.setCacheFile(this.currentIndex);
        this.saveCacheInfo();
    }



    private void createDiskStructure() {
        long chunkCount = (long) this.maxSize / this.chunkSize;
        (new File("./" + this.cacheDir)).mkdir();
        for (int i = 0; i < this.chunkCount; i++) {
            try {
                //(new File("./" + this.cacheDir + "/" + i + ".txt")).createNewFile();
                FileOutputStream fos = new FileOutputStream("./" + this.cacheDir + "/" + i + ".txt");
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeObject(this.currentCache);
                oos.close();
                fos.close();

            } catch (Exception e) {
                System.out.println("Create disk structure info");
            }
        }
    }


    public void fillCacheDefaultValues() {
        for (int i=0;  i<this.chunkSize;  i++)
            this.currentCache[i] = this.defaultValue;
    }


    public void resetCache() {
        this.currentCache = new Object[this.chunkSize];

        for (int i=0;  i<this.chunkSize;  i++)
            this.currentCache[i] = this.defaultValue;
    }


    public void saveCacheInfo() throws ChunkedArray.CacheError {
        try {
            PrintWriter pw = new PrintWriter("./" + this.cacheDir + "/cache_info.txt");
            pw.write("maxSize:" + this.maxSize + "\n");
            pw.write("chunkSize:" + this.chunkSize + "\n");
            pw.write("defaultValueFile:defaultValue.txt\n");
            pw.close();

            FileOutputStream fos = new FileOutputStream("./" + this.cacheDir + "/defaultValue.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(this.defaultValue);
            oos.close();
            fos.close();

        } catch (Exception e) {
            throw new ChunkedArray.CacheError("ChunkedArray.CacheError: saveCacheInfo Error");
        }
    }


    public void setCacheFile(long cacheFile) {
        this.cacheFile = cacheFile;
    }


    public ChunkedArray<Type> set(long index, Type value) throws ChunkedArray.CacheError
    {
        if (index > this.maxSize)
            throw new ChunkedArray.CacheError("Index out of bounds exception (index > maxSize");
        if (index < 0)
            throw new ChunkedArray.CacheError("Index out of bounds exception (index < 0");

        this.selectCacheFile(index);
        this.currentCache[ (int) (index % this.chunkSize) ] = value;
        return this;
    }


    public Type get(long index) throws ChunkedArray.CacheError {

        if (index > this.maxSize)
            throw new ChunkedArray.CacheError("Index out of bounds exception (index > maxSize");
        if (index < 0)
            throw new ChunkedArray.CacheError("Index out of bounds exception (index < 0");

        this.selectCacheFile(index);
        return (Type) this.currentCache[ (int) (index % this.chunkSize) ];
    }


    public void saveCache() {
        this.saveToDisk(this.currentIndex);
    }


    public void saveToDisk(long fileIndex) {
        try {
            FileOutputStream fos = new FileOutputStream("./" + this.cacheDir + "/" + fileIndex + ".txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(this.currentCache);
        } catch (Exception e) {
            System.out.println("ChunkedArray.saveToDisk() error: " + e);
            e.printStackTrace();
        }
    }


    public void loadFromDisk(long fileIndex) {
        if (fileIndex == this.currentIndex) return;

        try {
            //System.out.println("Loading cache...");
            FileInputStream fis = new FileInputStream("./" + this.cacheDir + "/" + fileIndex + ".txt"); //new FileInputStream("student.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            this.currentCache = (Type[]) ois.readObject();

            this.currentIndex = fileIndex;
        } catch (Exception e) {
            System.out.println("ChunkedArray.loadFromDisk() error at index: " + fileIndex + ", with error:"+ e);
            e.printStackTrace();
        }
    }


    public void selectCacheFile(long index) throws ChunkedArray.CacheError
    {
        long newIndex = 0;

        if (index != 0)
            newIndex = index / this.chunkSize;

        if (newIndex != this.currentIndex) {
            System.out.println("selectCacheFile: swap cache needed");
            this.saveToDisk(this.currentIndex);
            this.loadFromDisk(newIndex);
            this.currentIndex = newIndex;
        }
    }



    public long getMaxSize() {
        return this.maxSize;
    }


    //@Override
    public String toStringXY() {
        return "ChunkedArray{" +
                "currentCache=" + /*Arrays.toString(currentCache)*/  currentCache.length +
                ", defaultValue=" + defaultValue +
                ", cacheDir='" + cacheDir + '\n' +
                ", maxSize=" + maxSize + '\n' +
                ", chunkSize=" + chunkSize + '\n' +
                ", chunkPosition=" + chunkPosition + '\n' +
                ", chunkCount=" + chunkCount + '\n' +
                ", currentIndex=" + currentIndex + '\n' +
                ", cacheFile=" + cacheFile + '\n' +
                '}';
    }

    @Override
    public String toString() {

        /*

    public  Object[]  currentCache;
    private Type      defaultValue;
    private String    cacheDir;
    private long      maxSize;
    private int       chunkSize;
    private int       chunkPosition;
    private long      chunkCount;
    private long      currentIndex;
    private long      cacheFile;

         */

        StringBuilder sb = new StringBuilder();
        sb.append("currentCache.length: " + currentCache.length+"\n");
        sb.append("defaultType: " + defaultValue+"\n");
        sb.append("cacheDir: " + cacheDir+"\n");
        sb.append("maxSize:" + maxSize+"\n");
        sb.append("chunkSize: " + chunkSize+"\n");
        sb.append("chunkPosition: + " + chunkPosition+"\n");
        sb.append("chunkCount: " + chunkCount+"\n");
        sb.append("currentIndex: " + currentIndex+"\n");
        sb.append("cacheFile: " + cacheFile+"\n");

        return sb.toString();
    }

    public static <X> ChunkedArray<X>  loadFromCache(String cacheDir) throws ChunkedArray.CacheError
    {
        return new ChunkedArray<X>(cacheDir);
    }
}

BoolArray.java

import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;

//https://stackoverflow.com/questions/5849154/can-we-write-our-own-iterator-in-java
//https://www.youtube.com/watch?v=tIOBLlehkpA




public class BoolArray /*implements Iterable<boolean>*/ {


    public class CacheError extends Exception {

        private String msg;

        public CacheError(String msg) {
            this.msg = msg;
        }

        public String toString() {
            return this.msg;
        }
    }


    private int chunkSize;
    //private BigInteger maxSize;
    private BigInteger maxSize;
    private boolean defaultValue;
    private BigInteger currentIndex;
    private String cacheDir;

    private BigInteger chunkSize_;
    private BigInteger position;
    private int chunkPosition, currentChunk, chunkCount;

    private boolean []currentCache;


    private BoolArray(String cacheDir) throws CacheError {
        try {
            FileInputStream fstream = new FileInputStream(cacheDir + "/cache_info.txt");
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String strLine;
            ArrayList<String> cacheInfo = new ArrayList<>();

            while ((strLine = br.readLine()) != null)
                cacheInfo.add(strLine);

            br.close();

            this.maxSize = new BigInteger( cacheInfo.get(0).split(":")[1] );
            //this.chunkSize = new BigInteger( cacheInfo.get(1).split(":")[1] );
            this.chunkSize = Long.valueOf( cacheInfo.get(1).split(":")[1] ).intValue();
            this.defaultValue = Boolean.valueOf( cacheInfo.get(2).split(":")[1] );
            this.currentIndex = BigInteger.ZERO;
            this.cacheDir = cacheDir;

            this.loadFromDisk(this.currentIndex);

            this.chunkSize_ = new BigInteger(this.chunkSize+"");
            this.chunkPosition = 0;
            this.chunkCount = maxSize.divide(this.chunkSize_).intValue();

            System.out.println("BoolArray ctor ends");

        }catch (Exception e) {
            throw new CacheError("Something went wrong qrde");
        }

    }



    public BoolArray(BigInteger maxSize, int chunkSize, String cacheDir, boolean defaultValue)
            throws BoolArray.CacheError
    {
        this.maxSize = maxSize;
        this.chunkSize = chunkSize;
        this.cacheDir = cacheDir;
        this.defaultValue = defaultValue;

        this.resetCache();
        this.fillCacheDefaultVaues();

        this.createDiskStructure();
        this.saveCacheInfo();

        this.currentIndex = BigInteger.ZERO;
        this.selectCacheFile(this.currentIndex);

        this.chunkSize_ = new BigInteger(this.chunkSize+"");
        this.chunkPosition = 0;
        this.chunkCount = maxSize.divide(this.chunkSize_).intValue();

        System.out.println("BoolArray ctor ends");
    }


    private void fillCacheDefaultVaues() {
        for (int i=0;  i<chunkSize;  i++)
            this.currentCache[i] = defaultValue;

        System.out.println("fillCacheDefaultValus ends");
    }


    private void resetCache() {
        this.currentCache = new boolean[chunkSize/*.intValue()*/];
    }


    public void saveCacheInfo() throws BoolArray.CacheError {
        try {
            PrintWriter pw = new PrintWriter("./" + this.cacheDir + "/cache_info.txt");
            pw.write("maxSize:" + this.maxSize + "\n");
            pw.write("chunkSize:" + this.chunkSize + "\n");
            pw.write("defaultValue:" + this.defaultValue + "\n");
            pw.close();
        } catch (Exception e) {
            throw new CacheError("BoolArray.saveCacheInfo exception with cache: " + this.cacheDir);
        }
    }


    public void createDiskStructure() throws CacheError {
        BigInteger chunk_count = this.maxSize.divide(new BigInteger(this.chunkSize+"")).add(BigInteger.ONE);

        (new File("./" + this.cacheDir)).mkdir();

        for (BigInteger i = BigInteger.ZERO; i.compareTo(chunk_count) < 0; i = i.add(BigInteger.ONE)) {
            try {

                //(new File("./" + this.cacheDir + "/" + i + ".txt")).createNewFile();

                this.saveToDisk(i);

            } catch (Exception e) {
                throw new CacheError("BoolArray.createDiscStructure exception in for-loop with i="+i);
            }
        }
        System.out.println("createDiskStructure ends");
    }


    public void selectCacheFile(BigInteger index) throws CacheError {

        BigInteger newIndex = BigInteger.ZERO;

        if (index.compareTo(BigInteger.ZERO) != 0)
            //newIndex = (int) (this.chunkSize / index);
            newIndex = index.divide(this.chunkSize_);

        if (newIndex.compareTo(this.currentIndex)!=0) {
            //System.out.println("cache file index change! new="+newIndex+", prev="+this.currentIndex);
            System.out.println("selectCacheFile: swap cache");
            this.saveToDisk(this.currentIndex);
            this.loadFromDisk(newIndex);
            this.currentIndex = newIndex;
        }
        //System.out.println("selectCacheFile ends");
    }


    public void set(BigInteger index, boolean value) throws CacheError {
        //System.out.println("set index:"+index);

        this.selectCacheFile(index);

        BigInteger mod = index.mod(this.chunkSize_);

        this.currentCache[ mod.intValue() ] = value;
    }



    public boolean get(BigInteger index) throws CacheError {
        selectCacheFile(index);

        return this.currentCache[ index.mod(this.chunkSize_).intValue() ] ;
    }


    public boolean[]  getCurrentCache() {
        return currentCache;
    }


    public boolean[]  loadCacheFromFile(String path)
        throws BoolArray.CacheError
    {
        try {
            //System.out.println("Loading cache...");
            FileInputStream fis = new FileInputStream(path); //new FileInputStream("student.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            return (boolean[]) ois.readObject();
        } catch (Exception e) {
            throw new CacheError("BoolArray.loadCacheFromFile"+path);
        }
    }


    public boolean setCurrentCache(boolean []newCache) throws BoolArray.CacheError {
        if (newCache.length != this.currentCache.length)
            throw new BoolArray.CacheError("Cannot setCurrentCache");

        this.currentCache = newCache;
        return true;
    }



    public void saveToDisk(BigInteger fileIndex) throws CacheError {

        try {
            FileOutputStream fos = new FileOutputStream("./" + this.cacheDir + "/" + fileIndex + ".txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(this.currentCache);
        } catch (Exception e) {
            throw new CacheError("BoolArray.saveToDisk error");
        }
        /*try {
            PrintWriter out = new PrintWriter(this.cacheDir + "/" + fileIndex +".txt");
            for (int i=0;  i<this.currentCache.length;  i++)
                out.write(this.currentCache[i]+"");
        } catch (Exception e) {
            throw new CacheError("BoolArray.saveToDisk exception");
        }*/
        System.out.println("saveToDisk ends");
    }


    public void saveCache() throws CacheError {
        this.saveToDisk(this.currentIndex);
        System.out.println("saveCache");
    }


    public void loadFromDisk(BigInteger fileIndex) throws BoolArray.CacheError {

        /*this.currentCache = FilesUtils.loadFromFile(this.cacheDir + "/" + fileIndex + ".txt");
        this.currentIndex = fileIndex;*/


        if (fileIndex.compareTo(this.currentIndex) ==0 ) return;

        String path = "./" + this.cacheDir + "/" + fileIndex + ".txt";

        new File(path).exists();


        //size inefficient
        try {
            //System.out.println("Loading cache...");

            FileInputStream fis = new FileInputStream(path); //new FileInputStream("student.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            this.currentCache = (boolean[]) ois.readObject();

            this.currentIndex = fileIndex;
            System.out.println("loadFromDisk ends");
        } catch (Exception e) {
            throw new CacheError("BoolArray.loadFromDisk exception with fileindex="+fileIndex+", and path="+path);
        }

        //time inefficient?
        /*
        try {
            FileReader fr = null;
            BufferedReader r = new BufferedReader(new FileReader(this.cacheDir+"/"+fileIndex+".txt"));
            int ch;

            this.resetCache();
            int pos = -1;
            while ((ch = r.read()) != -1) {
                pos++;
                if (ch=='1')
                    this.currentCache[pos] = true;
                else
                    this.currentCache[pos] = false;
            }
        } catch (Exception e) {
            throw new CacheError("BoolArray.loadFromDisk");
        }*/
    }


    public BigInteger getMaxSize() {
        return this.maxSize;
    }


    public static BoolArray  loadFromCache(String cacheDir) throws CacheError {
        return new BoolArray(cacheDir);
    }


    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append("BoolArray info:\n\n");
        sb.append("chunkSize:    " + chunkSize + "\n");
        sb.append("maxSize:      " + maxSize + "\n");
        sb.append("defaultValue: " + defaultValue + "\n");
        sb.append("currentIndex  " + currentIndex + "\n");
        sb.append("cacheDir:     " + cacheDir+"\n\n");

        return sb.toString();
    }


    //----------


    public boolean getFirst() throws BoolArray.CacheError {
        this.chunkPosition = 0;
        this.currentChunk = 0;
        return this.get(BigInteger.ZERO);
    }


    public boolean getNext() throws BoolArray.CacheError {
        this.chunkPosition++;
        if (this.chunkPosition > this.chunkSize) {
            this.chunkPosition = 0;
            this.currentChunk++;

            if (this.currentChunk > this.chunkCount)
                throw new CacheError("BoolArray.getNext has reached end of collction");

            this.loadFromDisk(BigInteger.valueOf(this.currentChunk));
            return this.currentCache[0];
        }
        return this.currentCache[this.chunkPosition];
    }

    public boolean getLast() throws BoolArray.CacheError {
        this.chunkPosition = this.chunkSize;
        this.currentChunk  = this.chunkCount;
        this.position = this.maxSize;
        return this.get(this.maxSize);
    }

    public boolean setPosition(BigInteger position) throws BoolArray.CacheError {
        this.get(position);

        this.position = position;
        return false;
    }

    public boolean hasNext() throws BoolArray.CacheError {
        return this.position.add(BigInteger.ONE).compareTo(this.maxSize) < 0;

    }
}

ChunkedArray można parametryzować typem, BoolArray dziala tylko na typie prostym boolean.
Konstruktory o kilku argumentach tworzą podstawy cache, strukturę na dysku, zapisują do pliku informacyjnego status cache,
metody statyczne loadcośtam służą do wczytania danego chunka do pamięci. Kod jest jeszcze w wersji rozobczej, ale działa.
Przy pewnych modyfikacjach można kod przepisać na C++. Pozdrawiam
P-168788
« 1 »
  Strona 1 z 1