I'm playing with map and filter and stuff, trying to do a functional way of removing an index from a map, like this:
({
([ "name": "user1",
"val": "test",
"random": "other"
)],
([ "name": "user2",
"val": "another test",
"random": "something else"
]),
})
The array and mapping will be in that kind of format. …
[View More]name is unique among all the map entries, and all the keys exist with all the maps. I want to change it to something like this:
([ "user1": ([ "val": test", "random": "other" ]),
"user2": ([ "val": "another test", "random": "something else" ])
])
I can get the keys for the new map with array[*]["name"].
But removing that key from the maps and leaving the others is giving me a problem. Filter doesn't quite work because it only gives the value, and I'm not testing on the value, but the key.
A foreach would work, but I'm wondering if I can do something like:
mkmapping(a[*]["name"],map(a,lambda(mapping m) { filter(......something here
If anybody has any ideas that would be great...
thanks
[View Less]
I've been working through the check-in comments and have about 3/4 of them
distilled into meaningful release notes, however I'm getting to the point
where I need a little assistance weeding out noise and making sense of
what's left.
I put together a list of the entries that I haven't added to the release
notes yet, and I'd like to give everyone an opportunity to weigh in. The
list is at the following url:
http://wiki.gotpike.org/ReleaseToDo7-8-664
If you've got something to say about …
[View More]anything left, feel free to put
together a sentence or two describing the change. You can either
send them to me, or just add them to the bottom of the wiki
page. Also, if you know the entry isn't worth writing about,
feel free to remove it from the list. Otherwise, I won't put too much more
effort into adding the rest of these.
Best,
Bill
[View Less]
I've prepared a new 7.8 test release for consideration. Please feel free to download and test.
http://pike.ida.liu.se/download/pub/pike/alpha/7.8.664/
The following known problems exist:
- Change log is not complete (feel free to contribute)
- A compilation problem exists under OSX 10.6/7: pike_threadlib includes mach*.h, which causes an error.
Please feel free to get in touch with any comments or concerns.
Bill
bill(a)welliver.org
Does anyone know how often in the code we actually depend on the
fact that the same string will be at the same address in memory?
Because I'm contemplating an optimisation which would involve making
the string duplication avoidance opportunistic instead of mandatory.
I.e. something along the lines of all strings shorter than stringmin will
always be optimised to a single reference, and all strings above that *might*
have more than one reference, but not necessarily do (i.e. they're not
fully …
[View More]hashed all the time, to avoid the overhead of rehashing large strings
repeatedly when juggling around lots of strings).
All the places that depend on same string = same address would need to be
patched. Also, to determine stringmin, some profiling of existing apps
would be interesting. Is that statistic available for say Roxen, to know
the distribution of string length and reference count in a running
application?
--
Stephen.
Sex is like air. It's only a big deal if you can't get any.
[View Less]
I just pulled the latest pike version from git.
It clearly has been a while, since I've actively participated.
I apologise for my extended leave, it was due to some real-life issues
that got in the way of things. That is not to say that I didn't stop using
Pike or Roxen; quite the opposite, I just didn't have time to keep up on
the mailinglists. I got snippets of updates through Marc though, so I wasn't
completely ignorant.
Anyway, the good news is: I'm back.
I just glanced through the …
[View More]mailinglist archives (in my mailbox) and it is
quite a bundle to skip through (not started on that yet).
I first checked the state of the pgsql module. I see some minor updates/fixes.
I have one small and one very important fix waiting here which should get in
ASAP (which I have been hunting down for the past three years, but did not,
until about 2 weeks ago, result in a SEGV; which finally made it possible
to zoom in on it; which, in effect, was the final nudge that I needed to get
back on track with the mailinglist here).
Hmmm, I just glanced through http://pike.ida.liu.se/development/git/rw-git.xml
Is it supposed to be automatic that when you "git commit" it will push it
into the main repo?
Do I still have access?
If not, can I be reinstated?
--
Stephen.
Being able to try has no purpose if failing is not an option.
[View Less]
We pushed an experimental branch which uses a new block allocator we
have been developing. This one uses a different algorithm than the one
we briefly mentioned on the conference. The new one uses a hashtable for
page lookup instead of radix trees.
The branch can be found under arne/block_alloc, a GJAlloc-bundle is
available at http://fortranland.com/GJAlloc-0.08.tar.gz or from
https://github.com/arneg/GJAlloc via git. The branch currently contains
alot of obsolete history, which we …
[View More]would squash into one commit in case
of inclusion.
Standalone performance comparisons are available at
https://github.com/arneg/GJAlloc/wiki/Performance-comparison. The
speedup is quite noticeable when compiling with --cleanup-on-exit,
otherwise for most use cases the differences should be unnoticable.
However, when having many things around that do not get freed linearly,
the speedup can be dramatic. A rather extreme example is
time pike -e 'array a = map(allocate(1000000, 5), random_string); for (int i = 0; i < 10000000; i++) { int k = random(sizeof(a)); a[k] = random_string(5);}'
It would be interesting to see real world benchmarks, in case anyone
feels like it ,)
We would naturally like to incorporate this into Pike (7.9) and hope for
a discussion about the allocator itself and how to best include it.
Currently, GJAlloc is requested as a bundle by the CritBit module, which
uses its API directly. All other modules use macro definitions which are
compatible with the ones from block_allocator.h.
best
arne & tobi
[View Less]
Hi all,
A few months ago, started a conversation about what I'll call multi-tenant
applications: that is, a single pike process running multiple applications
(perhaps including copies of a given application) with isolated program
and module spaces. The idea is to provide a similar capability to that
provided by Java's ClassLoader API.
That is, I'd like to be able to do the following:
pike
+-----------------|-----------------+
…
[View More] | |
thread a1...an thread b1 ... bn
compilation handler a compilation handler b
loads classes for app1 instance 1 loads classes for app1 instance
from location a,b from location a,c (perhaps)
uses module foo.bar uses module foo.bar
foo.bar != foo.bar
though it would perhaps be acceptable if
object_program(foo.bar) == object_program(foo.bar)
applications would not be aware of each other (a condition
of the multi-tenant contract) and thus object identity
would not need to be maintained.
I've been dabbling with the approach suggested at the Pike conference,
which was to use a compilation handler to provide this functionality. I've
come tantalizingly close, being able to use an overriden master to provide
versions of compile_string() and friends that automatically select the
desired compilation handler based on various criteria (such as threads in
an application). While a bit clunky, it seems to allow me to control
visibility of identifiers in a given application or thread, but there does
seem to be a limitation that for me is fatal: the programs and module
objects are cached by the master, and therefore any two applications are
not truely isolated: they share a common set of modules (and
join/dirnodes) and (though less problematic) precompiled programs.Because
programs and modules seem to be indexed by filename, I've played around
with adding a unique identifier in order to split the cache on a
per-handler basis, but this hasn't worked either (programs seem to be
loaded as desired, but modules are still problematic.)
I've attempted to add storage of these caches in the compilation handler,
but it results in extremely odd failures (for example, a given class will
be cached as a zero value in the programs mapping, which means the program
won't be found, even if it's on disk.
As a brute force attempt to prove that the idea can work, I'm thinking
about short circuiting the auto-reload functionality so that it always
reloads a given class from disk. I'm not sure that this will actually
prove beneficial, as modules would still be persistent.
As always, any thoughts or suggestions would be welcome.
Bill
[View Less]
I'd like to solicit some design feedback for a new feature that I'd like
to contribute. I apologize for the length of this message, but hopefully
it contains all of the details needed to get the conversation started.
First, some quick background:
Over the past few years I've written a few modules[1] that provide access
to a number of technologies that are either part of Darwin or one of
Apple's Darwin-based OSes (OSX, iOS, etc). A common feature that keeps
occurring is their reliance on …
[View More]an active run loop. Normally, this is
either NSRunloop or CFRunLoop (they are distinct APIs, but they share
a common set of event sources.) In the past, I've resorted to adding a
persistent call-out to the default back end, which is similar to the
approach taken by the GTK2 module. This is normally good enough for
sitatuions where events are relatively infrequent, such as GUI-input work.
However, it's not always suitable for higher interrupt volumes and it also
has the side effect of presenting a continual, though low, load on the
CPU. This isn't a huge problem, but it's unclean and if one were to
increase the frequency of the poll-out to the CF/NS run loop, the load
becomes higher, and thus harder to ignore.
A Solution:
After doing some research on better ways to approach the problem, I
discovered that CF/NS run loops use kqueue at their core. As a result, a
kqueue can be added to the run loop and polled for events. That's
convenient, because pike uses kqueue on Darwin in its default backend,
Pike.PollDeviceBackend. Swapping out the direct call to kevent() with one
that calls the run loop results in "native" Pike I/O working the way it
should, plus Darwin layered functionality working properly as well (and
low CPU utilization, too).
I think that this is a useful new feature to add to Pike, but I've got
some concerns about how best to include it. Right now, I've created a
branch called hww3/cfrunloop_backend[2] that includes the functionality
and swaps out the existing implementation under Darwin. That is, of
course, the simplest approach, but I think is probably not the best idea:
Pros:
- Uses kqueue() at its core, so the existing backend will fire events in
the same way.
- Allows a number of technologies to function normally when used from with
Pike processes, without the use of hacks.
Cons:
- There is exactly one Run Loop per thread, which, if used universally,
could present issues because this means behavior would differ from other
Backends.
- There is slightly more overhead per trip through the backend due to
events being single-shot. This means that the kqueue has to be re-added to
the runloop each loop. I don't think it's a major overhead, it still
exists.
Alternate Implementations:
A second approach would be to provide an additional backend
implementation, say Pike.CFBackend, that's available on Darwin based
systems. I see one or two problems with this, though:
- There would need to be a way to activiate this selectively at runtime,
something like set_default_backend(Pike.CFBackend()), which probably
doesn't exist right now, right?
- Because 90% of the implementation would be shared with
PollDeviceBackend, I think it would involve a fair amount of code
duplication inside of backend.cmod, which I think would make maintenance
more difficult.
A third (and right now, I believe the best) approach would be to add one
or two methods to Pike.Backend that could be implemented by
PollDeviceBackend on Darwin and be used to activate this alternate mode.
For example:
int(0..1) has_client_mode()
which would return true if there were a client optimization (I suggest
client because CFRunLoop would be more useful for client apps than
traditional server based apps, though that's certainly not an either/or
situaiton) and:
void enable_client_mode(int(0..1))
that would trigger calls to CFRunLoopRunInMode() instead of kevent()
directly.
Input Sought:
I think either of the two alternative approaches would be just fine,
assuming that the concerns could be addressed. I'm just not sure which
would be best from a design and implementation standpoint (I sort of
think the last option would be simplest for _me_ to get working, but if
someone has desire to help tackle it, I'd be game to play along).
The upshot of allowing the proposed backend changes for other folks using
Pike are that:
a) SDL and GL becomes usable out of the box on OSX
b) I am prepared to contribute a few pieces of code, namely:
- FSEvents module
- Updated Filesystem.Monitor that uses FSEvents on Darwin and inotify on
Linux to eliminate polling
- DNS_SD querying support on OSX
- ObjectiveC bridge (possibly)
Hopefully we can have a bit of discussion about the options and approaches
and come up with a solution that works without being terribly
inconvenient. Please do drop me a note if anything about this proposal is
unclear.
Best,
Bill
[1] Public.ObjectiveC, Public.System.FSEvents, Public.IO.IOWarror,
additions to DNS-SD; SDL and GL on OSX also share this requirement.
[2] http://hg.welliver.org/pike/changesets, not yet pushed to the pike
master repo.
[View Less]
5
6
gobject-introspection
by Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum
01 Apr '12
01 Apr '12
Hi guys.
I was feeling bored so I started work on a Pike binding for GLib:s
object introspection repository (aka "gir").
It's still horribly incomplete, but it can already handle simple stuff
like this:
---8<---
import GI.repository;
void main()
{
Notify.init("notifytest");
Notify.Notification.new("Hello world", "This is an example",
"dialog-information")->show();
}
---8<---
The branch is available as "marcus/gobject-introspection" on the git
server if you want to check …
[View More]it out or (*gasp*) contribute. :-)
[View Less]