|
Thanks for reply, but my files are in tif format.
Mazy
"One who dives deep gets the pearls,the burning desire for realization brings the goal nearer." - Babuji
|
|
|
|
|
Unless the TIFF file uses JPEG compression (which is possible, but kind of pointless), the compression is lossless. That means that you can not change the quality of the compression as the compression does not make any quality compromises.
Unless you specifically need the TIFF format, you could try the PNG format instead. It is also lossless, but compresses a lot better. If you want lossy compression, use the JPEG format.
---
Year happy = new Year(2007);
|
|
|
|
|
I would like for the page to load and then for a process to kick off. The results of the process would then be updated on the page (via AJAX if I can ever get it to work). How do I do this?
|
|
|
|
|
It doesn't work that way. Well, it's possible using server push, but that requires that you start a component in the browser that establishes a permanent connection between the browser and the server, and even then you would have to re-attach it to the running process on the server.
Normally everything that you send between the server and the browser is initiated by the browser. The server can not send anything to the browser unless the browser is first sending a request to the server.
You can use AJAX to poll the server at a specific interval, so that the server could respond with the result. The running threads would have to store the results in a static list, so that the AJAX request could pick up the lastest result from a specific thread. You would also have to give each thread a unique identifier to identify the results, and keep the identifier in the page, so that it could be sent in the AJAX call in order to pick up the result from the correct thread.
---
Year happy = new Year(2007);
|
|
|
|
|
Wow, so is there an easy way to have an update page could be easily updated with information regarding the process that was kicked off on the page load event?
|
|
|
|
|
That depends on what you mean by easy... There is nothing in it that is very complicated, but it's certainly not something you just drag and drop on your page.
---
Year happy = new Year(2007);
|
|
|
|
|
Hi All,
how many types of authentication modes available in .Net?
how can we Implement forms-based cookie-less authentication in our application? i mean where & how can we set this Property?
thanks in advance,
Rahi
If you look at what you do not have in life, you don't have anything,
If you look at what you have in life, you have everything... "
|
|
|
|
|
Cookies are not used for authentication, they are used to maintain settings between sessions. That's not really the same thing. You can make a cookie keep authentication settings, but at the point of login, your authentication system will verify those details, all the cookie provides is persistence.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Hey all,
I'm working on a small program that manipulates an XML file, like the one below:
<code><?xml version="1.0" encoding="UTF-8"?>
<Root>
<patient>
<name>Jack Sparrow</name>
<gender>female</gender>
<dob>1/1/1940</dob>
<age>67</age>
<parentsnames>n/a</parentsnames>
<maritialstatus>divorced</maritialstatus>
<streetaddress>123 Anywhere Dr</streetaddress>
<homephone>111-111-1111</homephone>
<workphone>222-222-2222</workphone>
<cellphone>333-333-3333</cellphone>
<citystatezip>Somewhere/ST/12345</citystatezip>
<iseval>1</iseval>
<dateinitialeval>1/1/2006</dateinitialeval>
<lengthinitialeval>1.4</lengthinitialeval>
<isinter>0</isinter>
<dateinitialinter>
</dateinitialinter>
<lengthinitialinter>0</lengthinitialinter>
<notes>Dr. Don</notes>
<supervisor>1</supervisor>
<attributes>
<speech>0</speech>
<language>1</language>
<articulation>0</articulation>
<hearing>1</hearing>
<tbi>0</tbi>
<cva>1</cva>
<voice>0</voice>
<fluency>0</fluency>
</attributes>
</patient>
</Root></code>
I am trying to make the script remove an old entry, then add a new entry at the end of the XML file (as you can see, this file only has one entry). I am trying to do the removing using the following code snipped:
<code> string filename = "data.xml";
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filename);
}
catch (System.IO.FileNotFoundException)
{
//Do nothing
}
string expr = "/Root/patient[name='" + this.clientName.Text + "']";
XmlNode node;
node = xmlDoc.SelectSingleNode(expr);
node.ParentNode.RemoveChild(node);</code>
(this.clientName.Text contains the name of the client). The expression is matching just fine, if I add a MessageBox() to output node.OuterXml, everything displays fine. However, the RemoveChild() does nothing (it doesn't remove the field that was matched). The script goes on to write the edited entry, so I end up with two entries that are almost the same instead of a new one in place of an old one. What's wrong?
Let me know if you need any more information.
|
|
|
|
|
You really want to look for the patient using a better unique Id than name, and then you want to keep a reference to the existing patient node. This code will remove the name node only, which is obviously not what you want. It's probably easier to delete the existing record than to write code that either updates or edits, but either way, name is not a good unique Id, and you want to delete the patient record, not the name node.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
I am rather new to XML, so I tried your code as an exercise.
I added some logging to see intermediate states.
It did remove the entire patient record from xmlDoc, as you would have hoped.
To change the file, I guess you would need to terminate with xmlDoc.Save
Luc Pattyn
|
|
|
|
|
I have a function that will divide a loop iteration among threads. Each thread will be given its portion of work to do by giving it the array to iterate through and the start and end index that will be the range of indexes it will work on. I'm also assuming that I will not need to synchronize the access to the array since it works on each variable independently but I may be wrong. Here is what I have.
public Range[] ReturnIndexRanges(long[] indexes)
{
Range[] ranges = null;
Thread[] threads = new Thread[Environment.ProcessorCount];
long length = ((end - start) + 1) / Environment.ProcessorCount;
_start = start;
foreach (Thread t in threads)
{
t = new Thread(new ParameterizedThreadStart(ReturnRangesOfIndexes));
t.Start(new ThreadedReturnRangesOfIndexData(ranges, indexes, _start, length - 1));
_start += length;
length = end - length + 1;
}
return JoinDividedRanges(ranges);
}
private class ThreadedReturnRangesOfIndexData
{
public ThreadedReturnRangesOfIndexData(Range[] ranges, long[] indexes, long start, long end)
{
ranges_out = ranges;
indexes_in = indexes;
this.start = start;
this.end = end;
}
public long start, end;
public long[] indexes_in;
public Range[] ranges_out;
}
The ThreadedReturnRangesOfIndexData class is just a small class that hold some information such as the array of the indexes being passed into the method and the array of Ranges that will be returned. It will be like ref but since it is an array I do not need to add ref or out to it because an array is a reference type.
What I need is to figure out how to divide the indexes up evenly in the ReturnIndexRanges method at the top. This is my first attempt at creating a multi-threaded program so I would appreciate some tips if you have any. Should I just forget about threading?
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
Hello again,
I have some thoughts about this:
1) I hope you dont go through all this if ProcessorCount==1
or maybe you should, just to make sure it is also correct in that case ?
2) in my experience it works a lot easier when you never use end, but instead
use end+1 (saves a lot of mistakes, and it fits the for-loop paradigma).
3) I would not try to divide the job in exactly even parts, when you split
100 in 48+52 it won't matter that much.
4) I would be very careful not to have data that resides in the same cache line
(more precisely in addresses that differ by less than the cache line size)
be written by different processors. It would cause a lot of invalidate,
flush and reload operations, and would be devastating for performance.
And yes this is hard to achieve in a high-level language.
I hope but am not absolutely sure, arrays are always allocated at
an address that is a multiple of a sufficiently high power of 2
(say a multiple of 256 B). You can check this somewhat by experimenting,
better is to have it specd somewhere, but I dont recall having seen that.
5) 3+4 together means: I would, still thinking of arrays, split on
boundaries that correspond to 256 B or more, hence round up to 64
when dealing with 4B ints, etc.
6) I do recall some Intel articles that suggested making structs artificially
larger when you can afford it, just to achieve my point 4 (e.g. for control
data, such as task control blocks).
One of them showed how you can really kill a multi-processor system: have
two threads do spin locks on 2 data items that belong to the same cache line !
7) on the other hand, if you over-align your data, you increase the possibility
of cache trashing; example: if you need repetitive access to only 1000 bytes,
but all these bytes are at a stride of 1KB, they would constantly miss in
a cache even as big as 2MB, since cache associativity nowadays is something
like 8-way, so there would only be 8 cache line candidates to cache the
requested data (the cache line candidate in each way being determined by
the lowest address bits (but excluding those that correspond to the
cache line width).
8) in conclusion, I suggest you use variables for your basic parameters
(such as number of processors, estimated safe allignment (my 256 B above), etc.
And once you have it running, just do some more experiments with slightly
different values for those variables, just to see what really helps.
Good luck, and please keep posting your progress.
Luc Pattyn
|
|
|
|
|
Well thanks for the information. I think I will stick to the single threaded version of my method until I do more research. I didn't even think about the cache and aligning the data. I wanted to get the absolute max performance I could but it seems that will be much more complex than I thought it would. Here is the single threaded version. Its much simpler.
/// <summary>
/// Finds the ranges that may be in a sorted array of indexes. A range is one or more indexes that increment
/// by one, an array containing 6,7,8,10,400,401,402 contains three ranges 6-8, 10, and 400-402.
/// </summary>
/// <param name="indexes">A sorted array of indexes to search.</param>
/// <returns>An array of Ranges.</returns>
public Range[] FindIndexRanges(long[] indexes)
{
if (indexes.LongLength == 0)
return new Range[0];
if (indexes.LongLength == 1)
return new Range[] { new Range(indexes[0], indexes[0]) };
Range[] ranges = new Range[1];
bool resize = false; //this should be true after 1 range has been found
long firstIndex = indexes[0];
long lastIndex = indexes[0];
for (long i = 1; i < indexes.LongLength; i++)
{
if (indexes[i] == indexes[i - 1] + 1)
{
lastIndex++;
if (i != indexes.LongLength - 1)
continue;
}
if (resize)
Array.Resize<Range>(ref ranges, ranges.Length + 1);
ranges[ranges.Length - 1] = new Range(firstIndex, lastIndex);
firstIndex = lastIndex = indexes[i];
resize = true;
}
return ranges;
}
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
My first impression is the optimization requires 3 steps:
1. algorithm optimization, if any
(fits another message board!)
2. regular coding optimization
3. advanced optimization (such as multi-threading)
1. some questions:
- what can you tell about expected average range length ?
- is er an absolute max range length (or an extremely unlikely range length) ?
- do you need ranges in sequential order ?
- how harmful would it be to have a result array with a known length
(=useful data) but an exagerated "capacity" ?
2. I am not familiar with Array.Resize() but am very suspicious about it.
Please run similar code with an ArrayList or so, something that can
grow in chunks much larger than 1. I am afraid right now your CPU spends
a lot of time in growing an array !
3. keep this for later, indeed.
Luc Pattyn
|
|
|
|
|
Luc Pattyn wrote: - what can you tell about expected average range length ?
The average range length will be the length of the text you select in Word or notepad, this is going into a hex editor.
Luc Pattyn wrote: - is er an absolute max range length (or an extremely unlikely range length) ?
If you mean the length between the range's minvalue and maxvalue then it would be long.MaxValue + 1.
Luc Pattyn wrote: - do you need ranges in sequential order ?
Yes, if they are not in order then a copy and paste operation would be a impossible with multiple selections.
Luc Pattyn wrote: - how harmful would it be to have a result array with a known length
(=useful data) but an exagerated "capacity" ?
I would have to set the unused ranges values to -1 to signify that it is not needed. Why would I need to set it to a known length?
Luc Pattyn wrote: I am not familiar with Array.Resize() but am very suspicious about it.
Please run similar code with an ArrayList or so, something that can
grow in chunks much larger than 1. I am afraid right now your CPU spends
a lot of time in growing an array !
Well unless the user selects many items and that are separated(which would cause more than one range to be created) then it could become a performance killer. This is unlikely since FindIndexRanges is not used in the main algorithms, it is a programmer's convenience than can become very useful when using the public API around my hex editor control. I could only imagine a search selecting a million or few hundred thousand items (which are separated like [....] ... [..] ..... [.......]) in a large file and then the user/programmer somehow creating indexes for his needs and then needing to convert them back to ranges.
[you said]
"I forgot one question: what is the source of your array ?
I mean, if there already is something that performs the task
of ordering a lot of numbers and then putting them in an array, seems like
your range-finding requirement performance-wise should be integrated with it !"
When a user selects an a range of data the range will be added to a List<range>. When adding them range it will determan the position to insert using a binaryseach and a bitwise compliment operation. They will always be sorted from the start. No sort methods will need to be called. The source of the array may come from a method long[]GetSelectedIndexes which converted the ranges into an array of indexes. Although I do also have a method called Range[]GetSelectedIndexeRanges which is more likely to be called more than the index array version. Also the indexes could come from anywhere as FindIndexRanges will be exposed to the programmer using the control. If GetSelectedIndexes is called it will return the sorted indexes that are selected. They are already sorted as I said, GetSelectedIndexes uses the Ranges to create the index array.
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
I am still confused about your overall intentions.
I know the data is text (not memory blocks) in an existing, probably
unmodifiable, app. But then, I dont follow yet. It would help a lot
if you could sketch a more global view.
when you say " They will always be sorted from the start. No sort methods will need to be called." I understand you have code that adds a new number to
an existing, ordered, collection of numbers. Well that is exactly my point,
assume the existing collection of numbers already is range oriented
(which is true for an empty collection),
then you need to add one number at a time to such range-oriented collection,
which should not be to hard:
- locate in existing list (ur already doing that)
- if fits at end of existing range, enlarge that range
- else if fits at beginning of next existing range, enlarge that range
- else insert new range with length 1
I hope this makes sense...
Regards,
Luc Pattyn
|
|
|
|
|
Luc Pattyn wrote:
when you say " They will always be sorted from the start. No sort methods will need to be called." I understand you have code that adds a new number to
an existing, ordered, collection of numbers. Well that is exactly my point,
assume the existing collection of numbers already is range oriented
(which is true for an empty collection),
then you need to add one number at a time to such range-oriented collection,
which should not be to hard:
- locate in existing list (ur already doing that)
- if fits at end of existing range, enlarge that range
- else if fits at beginning of next existing range, enlarge that range
- else insert new range with length 1
I hope this makes sense...
I am doing that in the SelectData method. Perhaps I could email you the source code to HDPC 1.0 (my previous version of the hex editor control) and the new HDPC 2.0 (which I am just getting started on) If you wish to view the source then take a look at the Data class. The Data class is where all the complicated operations are. You will then understand what FindIndexRanges is used for if you look to see how it is used in the actual hex editor that goes with HDPC 1.0. Version 1.0 is very slow although I was attempting to keep simplicity a number one priority in version 1.0 it became a performance nightmare.
FindIndexRanges may not be needed anymore in the new version, I want to keep it for compatibility. I am still in the pre-alpha stage of development for HDPC 2.0 and somethings may be removed and changed. I may either remove the method(unlikely) or mark is as obsolete since I have new API that does not kill performance, although I cannot forsee how this control will be used if at all I want to allow as much flexibility as possible. The purpose of FindIndexRanges is to take an array of numbers, (it doesn't matter from where) and convert it to a range array. I cannot assume that those numbers ARE the selected data indexes.
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
Sure, full code could help, and I am willing to look at it,
but remember I am unfamiliar with your application domain, I do not know
what it is you want to achieve at the functional level.
Regards,
Luc Pattyn
|
|
|
|
|
There is full documentation, at least almost full for version 1.0. Is it possible to send a zip through codeproject?
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
dont know about mail thru CP, but I have mailed my e-mail adr to you.
where do I find the doc on DHPC, is there a web site or something ?
regards,
Luc Pattyn
|
|
|
|
|
Luc Pattyn wrote: where do I find the doc on DHPC, is there a web site or something ?
The source code and documentation is being emailed to you now. I have not created a web site for HDPC although I will create an article for it when it is completed or at least in beta. The documentation is in a .pdf document, class view diagrams (.png), readme.txt files, and Visio 2007 files,
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
Hi Captain,
I am under the impression your code generates way too many exceptions, and that's what
is slowing things down; optimizing with ranges wont make much of a difference as long
as Paint and MouseMove events generate one or more PointNotVisible events.
Will send you a quick hack to DataPresenterControl.cs
Regards,
Luc Pattyn
|
|
|
|
|
Luc Pattyn wrote:
I am under the impression your code generates way too many exceptions, and that's what
is slowing things down; optimizing with ranges wont make much of a difference as long
as Paint and MouseMove events generate one or more PointNotVisible events.
Yeah, it does generate too many exceptions.
The ranges are not only to improve performance of the core functionality but it is also to greatly reduce memory consumption. Selecting 1 million bytes will not use a ton of memory any more, it will use 2 longs for each selection (plus another long if you count the range variable in the Range struct).
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|
Have you looked at version 2.0 yet?
█▒▒▒▒▒██▒█▒██
█▒█████▒▒▒▒▒█
█▒██████▒█▒██
█▒█████▒▒▒▒▒█
█▒▒▒▒▒██▒█▒██
|
|
|
|
|