Re: Is this the proper way to do it?

2021-02-12 Thread mw via Digitalmars-d-learn

On Saturday, 13 February 2021 at 05:52:34 UTC, Jack wrote:
I have a base class A, where I make specific operator depending 
on the derived class type. Currently I'm using something like 
this:


c is a class derived from A
bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || 
(cast(K)c) !is null ... ;


as the number of cast(C) !is null is growing, I'm afraid of 
this being a inelegant or even poor performance approach. How 
would you do that?


Isn't that what virtual function is designed for?

```
class Base {
  bool shouldDoX() {return false;}
}

class Derived: Base {
  bool shouldDoX() {return true;}
}

class Derived2: Derived {
  bool shouldDoX() {return false;}
}

...

```


Is this the proper way to do it?

2021-02-12 Thread Jack via Digitalmars-d-learn
I have a base class A, where I make specific operator depending 
on the derived class type. Currently I'm using something like 
this:


c is a class derived from A
bool shouldDoX = (cast(X)c) !is null || (cast(Y)c) !is null || 
(cast(K)c) !is null ... ;


as the number of cast(C) !is null is growing, I'm afraid of this 
being a inelegant or even poor performance approach. How would 
you do that?


Re: how to properly compare this type?

2021-02-12 Thread Jack via Digitalmars-d-learn

helpful always,thank you guys


Re: Trying to reduce memory usage

2021-02-12 Thread Ali Çehreli via Digitalmars-d-learn

On 2/11/21 6:22 PM, H. S. Teoh wrote:

>bool[size_t] hashes;

I would start with an even simpler solution until it's proven that there 
still is a memory issue:


import std.stdio;

void main() {
bool[string] lines;
foreach (line; stdin.byLine) {
if (line !in lines) {
stdout.writeln(line);
lines[line.idup] = true;
}
// else this line already seen before; just skip it
}
}

(Grr... Thanks for the tab characters! :p)

Ali



Re: vibe.d json deserializeJson!Foo and ddbc.update!Foo

2021-02-12 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/12/21 6:22 PM, Chris Bare wrote:

I'm working on a project with vibe.d and ddbc to access my database.
Both have powerful functions that operate on Struct types to avoid a lot 
of boilerplate code.

I have a web site that sends a json message to update a record.
deserializeJson creates a new Foo record containing the json data.
However, there are some fields in the record which are not in the json, 
and these get default values.

I have another Foo that has the original values.

What would be the best way to merge the updated values into the original?
Obviously I can copy from one Foo to the other, but that's pretty 
inelegant.
If I could pass an existing Foo to deserializeJson and have only some 
fields filled in, that would be perfect.

I tried this:

deserializeJson!Foo(foo, req.json);

but it completely overwrites all the fields in foo.

Any suggestions? Is there a trick I'm just not seeing?


Does @ignore work? That's a UDA that tells vibe to ignore the field. 
Though I don't know if it means it leaves it alone completely.


https://vibed.org/api/vibe.data.serialization/ignore

-Steve


Re: GC.addRange in pure function

2021-02-12 Thread Petar via Digitalmars-d-learn

On Friday, 12 February 2021 at 12:17:13 UTC, Per Nordlöw wrote:

On Tuesday, 9 February 2021 at 03:05:10 UTC, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling 
GC.addRange or GC.removeRange isn't allowed?


Would making

`new T[]` inject a call to `GC.addRange` based on `T` (and 
maybe also T's attributes)


be a step forward?


`GC.addRange` is only used for memory allocated outside of the GC 
that can hold references to GC allocated objects. Since `new T[]` 
uses the GC, all the information is typeinfo is already there 
(*), so `GC.addRange` is unnecessary and even wrong, because when 
the GC collects the memory it won't call `GC.removeRange` on it


Implementation-wise, metadata about GC-allocated memory is held 
in the GC internal data structures, whereas the GC roots and 
ranges are stored in separate malloc/free-managed containers.


(*) Currently `new T[]` is lowered to an `extern (C)` runtime 
hook and the compiler passes to it typeid(T). After this the call 
chain is: _d_newarray_d_newarray{T,iT,mTX,miTX} -> _d_newarrayU 
-> __arrayAlloc -> GC.qalloc -> ConservativeGC.mallocNoSync -> 
Gcx.alloc -> {small,big}Alloc -> setBits


vibe.d json deserializeJson!Foo and ddbc.update!Foo

2021-02-12 Thread Chris Bare via Digitalmars-d-learn
I'm working on a project with vibe.d and ddbc to access my 
database.
Both have powerful functions that operate on Struct types to 
avoid a lot of boilerplate code.

I have a web site that sends a json message to update a record.
deserializeJson creates a new Foo record containing the json data.
However, there are some fields in the record which are not in the 
json, and these get default values.

I have another Foo that has the original values.

What would be the best way to merge the updated values into the 
original?
Obviously I can copy from one Foo to the other, but that's pretty 
inelegant.
If I could pass an existing Foo to deserializeJson and have only 
some fields filled in, that would be perfect.

I tried this:

deserializeJson!Foo(foo, req.json);

but it completely overwrites all the fields in foo.

Any suggestions? Is there a trick I'm just not seeing?

--
Chris


Re: GC.addRange in pure function

2021-02-12 Thread Petar via Digitalmars-d-learn

On Friday, 12 February 2021 at 19:48:01 UTC, vitamin wrote:
On Wednesday, 10 February 2021 at 16:25:44 UTC, Petar Kirov 
[ZombineDev] wrote:

On Wednesday, 10 February 2021 at 13:44:53 UTC, vit wrote:

[...]


TL;DR Yes, you can, but it depends on what "without problem" 
means for you :P


[...]


Thanks,

Yes, I am implementing container (ref counted pointer). When 
allcoator is Mallcoator (pure allocate and deallocate) and 
constructor of Type inside rc pointer has pure constructor and 
destructor, then only impure calls was GC.addRange and 
GC.removeRange.

Now there are marked as pure.


Great, that's the exact idea!


Re: GC.addRange in pure function

2021-02-12 Thread vitamin via Digitalmars-d-learn
On Wednesday, 10 February 2021 at 16:25:44 UTC, Petar Kirov 
[ZombineDev] wrote:

On Wednesday, 10 February 2021 at 13:44:53 UTC, vit wrote:

[...]


TL;DR Yes, you can, but it depends on what "without problem" 
means for you :P


[...]


Thanks,

Yes, I am implementing container (ref counted pointer). When 
allcoator is Mallcoator (pure allocate and deallocate) and 
constructor of Type inside rc pointer has pure constructor and 
destructor, then only impure calls was GC.addRange and 
GC.removeRange.

Now there are marked as pure.


Re: Trying to reduce memory usage

2021-02-12 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 12, 2021 at 07:23:12AM +, frame via Digitalmars-d-learn wrote:
> On Friday, 12 February 2021 at 02:22:35 UTC, H. S. Teoh wrote:
> 
> > This turns the OP's O(n log n) algorithm into an O(n) algorithm,
> > doesn't need to copy the entire content of the file into memory, and
> > also uses much less memory by storing only hashes.
> 
> But this kind of hash is maybe insufficient to avoid hash collisions.
> For such big data slower but stronger algorithms like SHA are
> advisable.

I used toHash merely as an example. Obviously, you should use a hash
that works well with the input data you're trying to process (i.e.,
minimal chances of collision, not too slow to compute, etc.). SHA hashes
are probably a safe bet, as chances of collision are negligible.


> Also associative arrays uses the same weak algorithm where you can run
> into collision issues. Thus using the hash from string data as key can
> be a problem. I always use a quick hash as key but hold actually a
> collection of hashes in them and do a lookup to be on the safe side.
[...]

You can use a struct wrapper that implements its own toHash method.


T

-- 
Mediocrity has been pushed to extremes.


Re: Profiling

2021-02-12 Thread James Blachly via Digitalmars-d-learn

On 2/9/21 12:45 AM, JG wrote:
I was trying to profile a d program. So I ran: dub build 
--build=profile. I then ran the program and it produced trace.log and 
trace.def. I then ran d-profile-viewer and got the following error:


std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382): 
Unexpected '-' when converting from type char[] to type ulong


??:? [0x564a8630fda5]
??:? [0x564a86333286]
??:? [0x564a863199fd]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:2382 [0x564a862c89a1]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:1941 [0x564a862c86cc]
/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d:223 [0x564a862c869c]
app.d:1095 [0x564a862cdd71]
app.d:1138 [0x564a862ce7ba]
??:? [0x564a863196cb]
??:? [0x564a863195c7]
??:? [0x564a8631941d]
/home/jg/dlang/ldc-1.24.0/bin/../import/core/internal/entrypoint.d:42 
[0x564a862ce7e4]

??:? __libc_start_main [0x7fd482807cb1]

Is d-profile-viewer no longer working? Or did I do something wrong?


Speaking of D profile viewer [1] we had good luck with it after fixing 
the missing timestamps in the profile (I think on Linux platforms it 
cannot actually measure times and so we had to rewrite the profile file 
to generate some fake timestamp(s) or timings -- hazy on details).


Anyway, if you can get it working it was a nice callgraph tool


[1] https://bitbucket.org/andrewtrotman/d-profile-viewer/src/master/


Re: GC.addRange in pure function

2021-02-12 Thread Per Nordlöw via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 03:05:10 UTC, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling 
GC.addRange or GC.removeRange isn't allowed?


Would making

`new T[]` inject a call to `GC.addRange` based on `T` (and maybe 
also T's attributes)


be a step forward?


Re: Trying to reduce memory usage

2021-02-12 Thread frame via Digitalmars-d-learn

On Friday, 12 February 2021 at 07:23:12 UTC, frame wrote:

On Friday, 12 February 2021 at 02:22:35 UTC, H. S. Teoh wrote:

This turns the OP's O(n log n) algorithm into an O(n) 
algorithm, doesn't
need to copy the entire content of the file into memory, and 
also uses

much less memory by storing only hashes.


But this kind of hash is maybe insufficient to avoid hash 
collisions. For such big data slower but stronger algorithms 
like SHA are advisable.


Also associative arrays uses the same weak algorithm where you 
can run into collision issues. Thus using the hash from string 
data as key can be a problem. I always use a quick hash as key 
but hold actually a collection of hashes in them and do a 
lookup to be on the safe side.


Forgot to mention that this kind of solution needs a better 
approach if you don't want to miss a potential different line:


You can use a weak hash but track the line position and count how 
often the same hash occurs as a pre-process. In the post-process 
you look for this lines again and compare if they are really 
identical or hash collisions to correct.