SORU
2 EKİM 2013, ÇARŞAMBA


Scalaz 7 zipWithİndex ile kaçınarak bellek sızıntısı/grup enumeratees

Arka plan

Olarak Scalaz 7 iteratees sürekli yığın alanı verileri (yani sınırsız) geniş bir akışı işlemek için kullanıyorum this question, kaydetti.

Benim kod bu gibi görünüyor:

type ErrorOrT[M[ _], A] = EitherT[M, Throwable, A]
type ErrorOr[A] = ErrorOrT[IO, A]

def processChunk(c: Chunk, idx: Long): Result

def process(data: EnumeratorT[Chunk, ErrorOr]): IterateeT[Vector[(Chunk, Long)], ErrorOr, Vector[Result]] =
  Iteratee.fold[Vector[(Chunk, Long)], ErrorOr, Vector[Result]](Nil) { (rs, vs) =>
    rs    vs map { 
      case (c, i) => processChunk(c, i) 
    }
  } &= (data.zipWithIndex mapE Iteratee.group(P))

Sorun

Bir bellek sızıntısı içine çalıştırmak gibi görünüyor, ama hata benim kod Scalaz ya da olup olmadığını bilmek Scalaz/FP yeterince aşina değilim. Sezgisel olarak, bu kod sadece (sipariş üzerine) gerektirir bekliyorumPkat Chunkboyutlu uzay.

Not: OutOfMemoryError Bir karşılaşıldı, ama benim kod consume kullanarak a similar question buldum.

Test

Bazı testler deneyin ve sorunu izole etmek için koştum. Özetlemek gerekirse, sızıntı sadece zipWithIndex group ikisi de kullanıldığında ortaya çıkacak gibi görünüyor.

// no zipping/grouping
scala> (i1 &= enumArrs(1 << 25, 128)).run.unsafePerformIO
res47: Long = 4294967296

// grouping only
scala> (i2 &= (enumArrs(1 << 25, 128) mapE Iteratee.group(4))).run.unsafePerformIO
res49: Long = 4294967296

// zipping and grouping
scala> (i3 &= (enumArrs(1 << 25, 128).zipWithIndex mapE Iteratee.group(4))).run.unsafePerformIO
java.lang.OutOfMemoryError: Java heap space

// zipping only
scala> (i4 &= (enumArrs(1 << 25, 128).zipWithIndex)).run.unsafePerformIO
res51: Long = 4294967296

// no zipping/grouping, larger arrays
scala> (i1 &= enumArrs(1 << 27, 128)).run.unsafePerformIO
res53: Long = 17179869184

// zipping only, larger arrays
scala> (i4 &= (enumArrs(1 << 27, 128).zipWithIndex)).run.unsafePerformIO
res54: Long = 17179869184

Testler için kod:

import scalaz.iteratee._, scalaz.effect.IO, scalaz.std.vector._

// define an enumerator that produces a stream of new, zero-filled arrays
def enumArrs(sz: Int, n: Int) = 
  Iteratee.enumIterator[Array[Int], IO](
    Iterator.continually(Array.fill(sz)(0)).take(n))

// define an iteratee that consumes a stream of arrays 
// and computes its length
val i1 = Iteratee.fold[Array[Int], IO, Long](0) { 
  (c, a) => c   a.length 
}

// define an iteratee that consumes a grouped stream of arrays 
// and computes its length
val i2 = Iteratee.fold[Vector[Array[Int]], IO, Long](0) { 
  (c, as) => c   as.map(_.length).sum 
}

// define an iteratee that consumes a grouped/zipped stream of arrays
// and computes its length
val i3 = Iteratee.fold[Vector[(Array[Int], Long)], IO, Long](0) {
  (c, vs) => c   vs.map(_._1.length).sum
}

// define an iteratee that consumes a zipped stream of arrays
// and computes its length
val i4 = Iteratee.fold[(Array[Int], Long), IO, Long](0) {
  (c, v) => c   v._1.length
}

Soru

  • Hata kodum mu?
  • Nasıl sabit yığın alanı içinde bu işi yapabilir miyim?

CEVAP
24 Mart 2013, Pazar


Aynı sorun bende de vardı ve html2canvas kullanarak çözüldü.

1) sayfanıza html2canvas İndir vardır.

2) resmi olarak, DİV, oluşturmak istediğiniz bölüm için bir KİMLİK olduğundan emin Olun(Burada kullanacağım ‘cardview’ örnek olarak).

3) süreci başlatmak için aşağıdaki işlevi Arayın

function printDiv(div)
{
    html2canvas([document.getElementById('cardview')], {   
        onrendered: function(canvas)  
        {
            var img = canvas.toDataURL()
            $.post("save.php", {data: img}, function (file) {
            window.location.href =  "download.php?path="  file});   
        }
    });         
}

4) Bir metin dosyası Oluşturun, kök dizininde aşağıdaki içeriğe sahip save.php gibi adı

<?php
$data = $_POST['data'];
$file = md5(uniqid()) . '.png';

// remove "data:image/png;base64,"
$uri =  substr($data,strpos($data,",") 1);

// save to file
file_put_contents('./'.$file, base64_decode($uri));

// return the filename
echo $file; exit;

5) Bir metin dosyası Oluşturun, adını root olarak aşağıdaki içerik olarak download.php dizin

<?php
$file = trim($_GET['path']);

// force user to download the image
if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: image/png');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    unlink($file);
    exit;
}
else {
    echo "$file not found";
}

Şimdi, HTML resim bir biçim alacak! içerik indirilen ve aynı biçimde resmi ve sayfanızda vardı stilleri yazdırabilirsiniz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Murray Winiata

    Murray Winia

    2 ŞUBAT 2009
  • sk8ingis4me

    sk8ingis4me

    16 Mart 2006
  • Virtual Riot

    Virtual Riot

    19 Mayıs 2011