← Back to team overview

pbxt-discuss team mailing list archive

Re: Row buffers and Object (was Re: free_table_share() != drizzle)

 

On Fri, 21 May 2010 11:31:20 +0200, Paul McCullagh <paul.mccullagh@xxxxxxxxxxxxx> wrote:
> My problem is that the val_ methods are hard-coded to reference  
> record[0].

You can get around that by using Field::move_field_offset.

something like:

  ptrdiff_t row_offset= buf - table->record[0];
  (**field).move_field_offset(row_offset);
  (do things with field)
  (**field).move_field_offset(-row_offset);

if buf is record[1] then we'll be doing things with it.

> So I have a problem when the row buffer is an engine internal buffer  
> (not record[0]). In this case I need the offset to calculate where the  
> field data starts in the internal row buffer.

the above should work... although it would be way better if we fix it up
to be an absolute pointer instead of doing (faulty) pointer math.

>  From this point of view, expanding the dependency on record[] would  
> be the wrong way to go.
> 
> Instead, I suggest a "Row" object, into which I can plug the start of  
> the row buffer. Then we would have:
> 
> doInsertRecord(Row *row_object)
> 
> The Row object knows everything about the row and can be used to  
> access the fields.

I've been thinking of a Tuple object instead, so we don't always have to
have the entire row buffer around if only a subset of rows are operated
on (this could be more advantageous for column based engines).

I'm also thinking that Tuple would just be an interface, and engines
could provide their own implementation.

With accessor methods, then the main server code could examine rows in
their native format instead of always having to convert from engine to
server formats. We would then only convert rows to over-the-wire
(server) format when they go over the wire.

> So the Row object is a "per thread" object. You call row_object- 
>  >setBuffer(u_char *buf) to set the row buffer and then you use an  
> array of fields to get and set the data in the buffer.

We could do RowBuffer(row_buffer, ptr) instead, so that it's impossible
to ever forget to set the buffer back to something.

> So then the record[] array would become an array of Row objects. And  
> an engine could create Row object to manipulate row buffers internally  
> (which is exactly what I am doing with the internal Table object - or  
> TableShare object).

I think a Row object is just formalising the existing interface a bit
more... which could be a good intermediate step. I like the Tuple idea a
bit better for a number of reasons, most of which are just different
ways of expressing "things more compact in memory" and "save converting
row/tuple formats".

One thing to think about is that Field is not part of record[], and it
would sort of have to be part of Row to be sane and be able to have
different Row objects accessed concurrently (or wrap Field calls to
get/set the offset).

> The record[0] object would be passed to doInsertRecord(buf), as it is  
> today.
> 
> But now, the engine will not have to know that: buf == record[0]!

mostly :)

That's the annoying bit - it's *mostly* true :)

> Stewart: would something like this also work for your implementation  
> of the Embedded InnoDB?

I'd prefer the Tuple way of doing things, as when operating on a subset
of columns, it would save a bunch of effort.



-- 
Stewart Smith



Follow ups

References