Forum Moderators: coopster

Message Too Old, No Replies

altering bits in a string

         

brotherhood of LAN

4:21 pm on May 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I am running a cron job that's testing if a server is up or not, basically its a CURL function that checks a URL, returning 1 if the server is found and 0 if it isnt -- 1 bit of information.

The results of the function will be stored in a BLOB field in a mysql table, a string.

Is there a simple way for me to alter the bits in a string, so I can 'append' the results of the cron on to an existing string, i.e. bit = 1 if server found and 0 if it isnt?

For instance, the function may have checked the page 10 times before, and 10 bits are set, I would like to set the 11th bit of the string for the next time the function is run.

Hopefully explained that clearly :)

httpwebwitch

5:39 am on May 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



you're adding to the end of a string, so use the "dot" concatenator.

$string = "1101010010"; // your existing 10 bits
$newbit = 1; //

$newstring = $string.$newbit;

// now $newstring="11010100101"

then put $newstring back in your database. that ought to do it!

For someone already using cronjobs and CURL, this question seems way too simple. Am I understanding you correctly?

brotherhood of LAN

5:14 pm on May 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



hi httpwebwitch, cheers for the post.

hehe yes its probably simpler than I imagined. The thing is, I've been shown how to do it in C with an operator and thought PHP would have the same....

It would save converting the blob field to binary and appending the extra bit.

Also, say that the blob field was empty and I updated it the first time, instead of one bit of info it'll end up with 8 (a byte, 7 extra/unwanted 0's)....

So I'd also have to keep a counter, or those 7 "0" bits would look like "results".

I'd intended to just use the concatenator on $string as you have tried but do you see the prob here? :) No probs with having to store a "counter" to keep track of where in the string results are appended to, just seems that there's a function/operator out there in PHP that would do it more seamlessly. :)

coopster

5:45 pm on May 4, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



BOL, why not store two values in your table, one for attempts, one for success, then update accordingly on script execution? Why do you need to use a blob?

brotherhood of LAN

5:52 pm on May 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



>one for attempts, one for success

That's what I have coopster, after discovering the wee prob of 1 bit needing a byte storage....so there's an "attempts" column (SMALL INT) that says which bit is to be altered in the BLOB. (increments after every update starting at 0)

The blob could very well be a number field.......the function checks if a webpage is alive or not and may do this every hour for a year.... so i'd need 365*24 bits, that's why i chose a large column to store these results.

Bearing in mind there may be '000's of other URL's being checked I had previously thought storing these results "per bit" in the blob field was a good way to go about it ...perhaps not? :)

httpwebwitch

6:13 pm on May 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The method you describe is an insane waste of processing and storage; you should let the database do the work rather than parse some complex hunk of data for pre-storage and keep track of what "digit" is the "current digit"...

Firstly, You *are* compromising storage. the BLOB will reserve "elbow room" for itself and take up lots of space, even if it's empty or just contains a "0"; whereas the TINYINT(1) is always one bit, super-tiny.

Even without the whole digit counter thing, there is a serious concern with scalability.

A table with a TINYINT(1) field can have a gargantuan number of rows. Your BLOB field has an upper limit in size. Your BLOB will run out of internal room long before the database will run out of space for more TINYINTs. This is a common trap in data architecture akin to making "Zip" fields that only hold 5 characters, or using INT when DOUBLE is needed.

If you can predict the volume of data, you'll be OK with your method. But sometimes you can't predict these things, and you'd probably be accused of forming bad habits.

Think about what the data means. Why are you storing them as a series of 1001010101001...? Wouldn't it be more meaningful if each test was a separate row, with a date/time, the domain, and the success binary INT? You could easily grab any data you want with a well-written SELECT statement, and I can (hesitantly) guarantee that the database will do it faster than any PHP program hacking apart long appended strings.

May the 4th be with you

brotherhood of LAN

7:26 pm on May 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks for the feedback to the both of you....

Just wanted to address a couple of thing you mention httpwebwitch, btw by no means am i a guru though I'll try explain why i made it this way and if it has any merit...

separate row, with a date/time, the domain, and the success binary INT? You could easily grab any data you want with a well-written SELECT statement, and I can (hesitantly) guarantee that the database will do it faster than any PHP program hacking apart long appended strings

Everything in the row would be constant, apart from the results which can be one of two values, 0 or 1. A User may want to track a URL (as in the table below) for a set time span. Somehow the results of checking the URL will be stored...

If the user wants info about tasks they are running in this table, it should be fairly easy... there is a start date, frequency and a blob/table/int of 0/1's. With this data you can give the user the result for each check, the time it was run etc etc....each result is an offset from the start_date field.

Here is the basic structure of the whole thing, the cron runs every minute, the url is grabbed with php and the results are in mysql. The whole thing is up for review :)

Previously I'd used the blob to store the results and counter.....is using a blob column here innapropriate or wasteful? I thought a blob takes up Length + 2 bytes which seemed an OK sacrifice for an arbitrary length column.

id ¦ memberid ¦ urlchecksum ¦ url ¦ ua ¦ run_start ¦ run_next ¦ run_frequency ¦ run_end
1 ¦ 1 ¦ -1260668374 ¦ yahoo.com/ ¦ a ¦ 20040503160000 ¦ 20040503160026 ¦ 1 ¦ 20040503170000

id - unique id of process
memberid - member running process
urlchecksum - quick way to check if url exists in table
url - actual url to check
ua - user agent to use
run_next - Next time to run this check (in hours)
run_frequency - Time gap between checks
run_end - Time to delete this row

- Every minute the "run_next" field is compared to the current time.
- If the field is before the current time, fetch the URL and return 1 or 0
- Update/Insert a record with the result (?)