■_
Programming Erlang
『Programming Erlang』届いたよ - val it : α → α = fun
先日ここにも書いたように発送されたという連絡は来ましたが
ブツはまだわたしの手元には着いていません。
まあ航空便じゃない(多分)しな。
さてそんな『Programming Erlang』ですが、邦訳が出るという話があるようです。
わたしも詳しい状況はよく知りませんし、すくなくともわたしが訳しているのとは関係ありません。
というか誰が訳しているのかも知らない。
なのでいつ出るかもわかりませんし詳しい話はできませんが、まあ、
そう遠くないうちに翻訳は出るんじゃないでしょーか、とだけ言っておきます。
あはははは(乾いて引きつった笑い)
いつものパターンくさい喃
さて、わたしのこの本に対する評価というのを書いていなかったように思いますが、
これはかなり良い本だと思いました。
(略)
そんなわけで Erlang に興味がなくても読んでみると得るものがあるのではと
思いたくなるくらい。
それは楽しみな。
■_
Dive into python sourcecode
つーことで file オブジェクトに寄り道してみる
PyObject *
PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
{
PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
NULL, NULL);
if (f != NULL) {
PyObject *o_name = PyString_FromString(name);
if (o_name == NULL)
return NULL;
if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
Py_DECREF(f);
f = NULL;
}
Py_DECREF(o_name);
}
return (PyObject *) f;
}
PyObject *
PyFile_FromString(char *name, char *mode)
{
extern int fclose(FILE *);
PyFileObject *f;
f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
if (f != NULL) {
if (open_the_file(f, name, mode) == NULL) {
Py_DECREF(f);
f = NULL;
}
}
return (PyObject *)f;
}
static PyObject *
file_read(PyFileObject *f, PyObject *args)
{
long bytesrequested = -1;
size_t bytesread, buffersize, chunksize;
PyObject *v;
if (f->f_fp == NULL)
return err_closed();
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
f->f_buf[0] != '\0')
return err_iterbuffered();
if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
return NULL;
if (bytesrequested < 0)
buffersize = new_buffersize(f, (size_t)0);
else
buffersize = bytesrequested;
if (buffersize > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"requested number of bytes is more than a Python string can hold");
return NULL;
}
v = PyString_FromStringAndSize((char *)NULL, buffersize);
if (v == NULL)
return NULL;
bytesread = 0;
for (;;) {
Py_BEGIN_ALLOW_THREADS
errno = 0;
chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread,
buffersize - bytesread, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS
if (chunksize == 0) {
if (!ferror(f->f_fp))
break;
clearerr(f->f_fp);
/* When in non-blocking mode, data shouldn't
* be discarded if a blocking signal was
* received. That will also happen if
* chunksize != 0, but bytesread < buffersize. */
if (bytesread > 0 && BLOCKED_ERRNO(errno))
break;
PyErr_SetFromErrno(PyExc_IOError);
Py_DECREF(v);
return NULL;
}
bytesread += chunksize;
if (bytesread < buffersize) {
clearerr(f->f_fp);
break;
}
if (bytesrequested < 0) {
buffersize = new_buffersize(f, buffersize);
if (_PyString_Resize(&v, buffersize) < 0)
return NULL;
} else {
/* Got what was requested. */
break;
}
}
if (bytesread != buffersize)
_PyString_Resize(&v, bytesread);
return v;
}
PyTypeObject PyFile_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"file",
sizeof(PyFileObject),
0,
(destructor)file_dealloc, /* tp_dealloc */
(ry
(getiterfunc)file_self, /* tp_iter */
(iternextfunc)file_iternext, /* tp_iternext */
file_methods, /* tp_methods */
file_memberlist, /* tp_members */
file_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
file_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
file_new, /* tp_new */
PyObject_Del, /* tp_free */
};
/* A larger buffer size may actually decrease performance. */
#define READAHEAD_BUFSIZE 8192
static PyObject *
file_iternext(PyFileObject *f)
{
PyStringObject* l;
if (f->f_fp == NULL)
return err_closed();
l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
if (l == NULL || PyString_GET_SIZE(l) == 0) {
Py_XDECREF(l);
return NULL;
}
return (PyObject *)l;
}
/* Used by file_iternext. The returned string will start with 'skip'
uninitialized bytes followed by the remainder of the line. Don't be
horrified by the recursive call: maximum recursion depth is limited by
logarithmic buffer growth to about 50 even when reading a 1gb line. */
static PyStringObject *
readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
{
PyStringObject* s;
char *bufptr;
char *buf;
Py_ssize_t len;
if (f->f_buf == NULL)
if (readahead(f, bufsize) < 0)
return NULL;
len = f->f_bufend - f->f_bufptr;
if (len == 0)
return (PyStringObject *)
PyString_FromStringAndSize(NULL, skip);
bufptr = (char *)memchr(f->f_bufptr, '\n', len);
if (bufptr != NULL) {
bufptr++; /* Count the '\n' */
len = bufptr - f->f_bufptr;
s = (PyStringObject *)
PyString_FromStringAndSize(NULL, skip+len);
if (s == NULL)
return NULL;
memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
f->f_bufptr = bufptr;
if (bufptr == f->f_bufend)
drop_readahead(f);
} else {
bufptr = f->f_bufptr;
buf = f->f_buf;
f->f_buf = NULL; /* Force new readahead buffer */
assert(skip+len < INT_MAX);
s = readahead_get_line_skip(
f, (int)(skip+len), bufsize + (bufsize>>2) );
if (s == NULL) {
PyMem_Free(buf);
return NULL;
}
memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
PyMem_Free(buf);
}
return s;
}
static PyObject *
file_self(PyFileObject *f)
{
if (f->f_fp == NULL)
return err_closed();
Py_INCREF(f);
return (PyObject *)f;
}
static PyObject *
file_readlines(PyFileObject *f, PyObject *args)
{
long sizehint = 0;
PyObject *list;
PyObject *line;
char small_buffer[SMALLCHUNK];
char *buffer = small_buffer;
size_t buffersize = SMALLCHUNK;
PyObject *big_buffer = NULL;
size_t nfilled = 0;
size_t nread;
size_t totalread = 0;
char *p, *q, *end;
int err;
int shortread = 0;
if (f->f_fp == NULL)
return err_closed();
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
f->f_buf[0] != '\0')
return err_iterbuffered();
if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
return NULL;
if ((list = PyList_New(0)) == NULL)
return NULL;
for (;;) {
if (shortread)
nread = 0;
else {
Py_BEGIN_ALLOW_THREADS
errno = 0;
nread = Py_UniversalNewlineFread(buffer+nfilled,
buffersize-nfilled, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS
shortread = (nread < buffersize-nfilled);
}
if (nread == 0) {
sizehint = 0;
if (!ferror(f->f_fp))
break;
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
error:
Py_DECREF(list);
list = NULL;
goto cleanup;
}
totalread += nread;
p = (char *)memchr(buffer+nfilled, '\n', nread);
if (p == NULL) {
/* Need a larger buffer to fit this line */
nfilled += nread;
buffersize *= 2;
if (buffersize > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"line is longer than a Python string can hold");
goto error;
}
if (big_buffer == NULL) {
/* Create the big buffer */
big_buffer = PyString_FromStringAndSize(
NULL, buffersize);
if (big_buffer == NULL)
goto error;
buffer = PyString_AS_STRING(big_buffer);
memcpy(buffer, small_buffer, nfilled);
}
else {
/* Grow the big buffer */
if ( _PyString_Resize(&big_buffer, buffersize) < 0 )
goto error;
buffer = PyString_AS_STRING(big_buffer);
}
continue;
}
end = buffer+nfilled+nread;
q = buffer;
do {
/* Process complete lines */
p++;
line = PyString_FromStringAndSize(q, p-q);
if (line == NULL)
goto error;
err = PyList_Append(list, line);
Py_DECREF(line);
if (err != 0)
goto error;
q = p;
p = (char *)memchr(q, '\n', end-q);
} while (p != NULL);
/* Move the remaining incomplete line to the start */
nfilled = end-q;
memmove(buffer, q, nfilled);
if (sizehint > 0)
if (totalread >= (size_t)sizehint)
break;
}
if (nfilled != 0) {
/* Partial last line */
line = PyString_FromStringAndSize(buffer, nfilled);
if (line == NULL)
goto error;
if (sizehint > 0) {
/* Need to complete the last line */
PyObject *rest = get_line(f, 0);
if (rest == NULL) {
Py_DECREF(line);
goto error;
}
PyString_Concat(&line, rest);
Py_DECREF(rest);
if (line == NULL)
goto error;
}
err = PyList_Append(list, line);
Py_DECREF(line);
if (err != 0)
goto error;
}
cleanup:
Py_XDECREF(big_buffer);
return list;
}
んーここまでみてもなぜLightCSVより高速なのかわからない…
■_
今日のUSBデバイス
バッファロー、TurboUSB搭載のポータブルハードディスクに300GBモデル登場 | パソコン | マイコミジャーナル
300GBで4万弱ですか。
ふと、初めて買ったMOドライブ(128MBメディアのみ。SCSI接続)が
10万円くらいしたのを思い出したり。
東芝、32Gバイトの大容量モデルを含むUSBフラッシュメモリ「TransMemory」シリーズ:ニュース - CNET Japan
多分MLCだよねえ。スピードはどうなんだろう?
ReadyBoost対応ということならそこそこアクセス速度は出るのか?
価格についてはオープン価格となっている。
まるっきり見当もつかないというのはなあ。
バッファローのアレから考えるとその倍くらい?
impressで紹介記事があった→
東芝、容量32GBのReadyBoost対応USBメモリ
実売価格は、U2J-001GTが4,000円前後、U2Kシリーズの1GBモデル
「U2K-001GT」が3,000円前後、2GBの「U2K- 002GT」が6,000円前後、
4GBの「U2K-004GT」が12,000円前後、8GBの「U2K-008GT」が24,000円前後、
32GB のU2G-032GTが80,000円前後の見込み。
■
今日もまたAmazonからの手紙
ご予約いただいてお ります下記の商品に関し、
予定しておりました当サイト配送センターへの入荷が未だされていないため、
発送が遅れております。お待たせしており、誠に申し訳ございま せん。
継続して商品の手配を進めておりますが、現時点において想定される予定日を目処に
発送予定日を変更させていただいております。
(ry
Kent Beck (著) "Implementation Patterns"
むーん。
まあ読む時間ないからいいか(^^;